Skip to content

Commit

Permalink
Merge pull request #11 from HomeAdvisor/kafdrop-2.0.0
Browse files Browse the repository at this point in the history
Sync Kafdrop 2.0.0 from HomeAdvisor
  • Loading branch information
Michael Pratt authored Jun 21, 2017
2 parents 43e4ec4 + 51cf978 commit 7fb5884
Show file tree
Hide file tree
Showing 38 changed files with 522 additions and 59 deletions.
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,60 @@ Then open a browser and navigate to http://localhost:9000. The port can be overr

## Running with Docker

The following maven command will generate a Docker image:
Note for Mac Users: You need to convert newline formatting of the kafdrop.sh file *before* running this command:

```
mvn clean package assembly:single docker:build
dos2unix src/main/docker/*
```

Note for Mac Users: You need to convert newline formatting of the kafdrop.sh file *before* running this command:
The following maven command will generate a Docker image:

```
dos2unix src/main/docker/*
mvn clean package assembly:single docker:build
```


Once the build finishes you can launch the image as follows:

```
docker run -d -p 9000:9000 -e ZOOKEEPER_CONNECT=<host:port,host:port> kafdrop
```

And access the UI at http://localhost:9000.

## Kafka APIs

Starting with version 2.0.0, Kafdrop offers a set of Kafka APIs that mirror the existing HTML views. Any existing endpoint can be returned as JSON by simply setting the *Accept : application/json header*. There are also two endpoints that are JSON only:

/topic : Returns array of all topic names
/topic/{topicName}/{consumerId} : Return partition offset and lag details for a specific topic and consumer.

## Swagger

To help document the Kafka APIs, Swagger has been included. The Swagger output is available by default at the following Kafdrop URL:

/v2/api-docs

However this can be overridden with the following configuration:

springfox.documentation.swagger.v2.path=/new/swagger/path

Currently only the JSON endpoints are included in the Swagger output; the HTML views and Spring Boot debug endpoints are excluded.

You can disable Swagger output with the following configuration:

swagger.enabled=false

## CORS Headers

Starting in version 2.0.0, Kafdrop sets CORS headers for all endpoints. You can control the CORS header values with the following configurations:

cors.allowOrigins (default is *)
cors.allowMethods (default is GET,POST,PUT,DELETE)
cors.maxAge (default is 3600)
cors.allowCredentials (default is true)
cors.allowHeaders (default is Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization)

You can also disable CORS entirely with the following configuration:

cors.enabled=false
9 changes: 8 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.homeadvisor.kafka</groupId>
<artifactId>kafdrop</artifactId>
<version>1.2.2-SNAPSHOT</version>
<version>2.0.0</version>

<description>For when you have a Kaf(ka) cluster to monitor</description>

Expand Down Expand Up @@ -108,6 +108,13 @@
<artifactId>spring-beans</artifactId>
</dependency>

<!-- Swagger API docs -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/homeadvisor/kafdrop/KafDrop.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@
import com.homeadvisor.kafdrop.config.ini.IniFileReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.Banner;
import org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
Expand All @@ -44,7 +45,7 @@ public class KafDrop
public static void main(String[] args)
{
new SpringApplicationBuilder(KafDrop.class)
.showBanner(false)
.bannerMode(Banner.Mode.OFF)
.listeners(new EnvironmentSetupListener(),
new LoggingConfigurationListener())
.run(args);
Expand Down
106 changes: 106 additions & 0 deletions src/main/java/com/homeadvisor/kafdrop/config/CorsConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/

package com.homeadvisor.kafdrop.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Auto configuration for enabling CORS support. Can override behavior with
* various configs:
*
* <ul>
* <li>cors.enabled</li>
* <li>cors.allowOrigins</li>
* <li>cors.allowMethods</li>
* <li>cors.maxAge</li>
* <li>cors.allowCredentials</li>
* <li>cors.allowHeaders</li>
* </ul>
* <br/>
* To disable CORS entirely, set <b>cors.enabled=false</b>. All other configs are
* just Strings that get used as-is to set the corresponding CORS header.
*/
@Configuration
@ConditionalOnProperty(value = "cors.enabled", matchIfMissing = true)
public class CorsConfiguration
{
@Value("${cors.allowOrigins:*}")
private String corsAllowOrigins;

@Value("${cors.allowMethods:GET,POST,PUT,DELETE}")
private String corsAllowMethods;

@Value("${cors.maxAge:3600}")
private String corsMaxAge;

@Value("${cors.allowCredentials:true}")
private String corsAllowCredentials;

@Value("${cors.allowHeaders:Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization}")
private String corsAllowHeaders;

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public Filter corsFilter()
{
return new Filter()
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;

response.setHeader("Access-Control-Allow-Origin", corsAllowOrigins);
response.setHeader("Access-Control-Allow-Methods", corsAllowMethods);
response.setHeader("Access-Control-Max-Age", corsMaxAge);
response.setHeader("Access-Control-Allow-Credentials", corsAllowCredentials);
response.setHeader("Access-Control-Allow-Headers", corsAllowHeaders);

if(request.getMethod().equals(HttpMethod.OPTIONS.name()))
{
response.setStatus(HttpStatus.NO_CONTENT.value());
}
else
{
chain.doFilter(req, res);
}
}

@Override
public void destroy() {}
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/

package com.homeadvisor.kafdrop.config;

import com.google.common.base.Predicate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
* Auto configuration for Swagger. Can be disabled by setting swagger.enabled=false.
*/
@Configuration
@EnableSwagger2
@ConditionalOnProperty(value = "swagger.enabled", matchIfMissing = true)
public class SwaggerConfiguration
{
@Bean
public Docket swagger()
{
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(new ApiInfoBuilder()
.title("Kafdrop API")
.description("JSON APIs for Kafdrop")
.build())
.select()
.apis(new JsonRequestHandlerPredicate())
.paths(new IgnoreDebugPathPredicate())
.build();
}

/**
* Swagger Predicate for only selecting JSON endpoints.
*/
public class JsonRequestHandlerPredicate implements Predicate<RequestHandler>
{
@Override
public boolean apply(RequestHandler input)
{
return input.produces().contains(MediaType.APPLICATION_JSON);
}
}

/**
* Swagger Predicate for ignoring /debug endpoints.
*/
public class IgnoreDebugPathPredicate implements Predicate<String>
{
@Override
public boolean apply(String input)
{
return !input.startsWith("/debug");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 HomeAdvisor, Inc.
* Copyright 2017 HomeAdvisor, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,13 +18,22 @@

package com.homeadvisor.kafdrop.controller;

import com.homeadvisor.kafdrop.model.BrokerVO;
import com.homeadvisor.kafdrop.service.BrokerNotFoundException;
import com.homeadvisor.kafdrop.service.KafkaMonitor;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class BrokerController
Expand All @@ -40,4 +49,25 @@ public String brokerDetails(@PathVariable("id") int brokerId, Model model)
model.addAttribute("topics", kafkaMonitor.getTopics());
return "broker-detail";
}

@ApiOperation(value = "getBroker", notes = "Get details for a specific Kafka broker")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = BrokerVO.class),
@ApiResponse(code = 404, message = "Invalid Broker ID")
})
@RequestMapping(path = "/broker/{id}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public @ResponseBody BrokerVO brokerDetailsJson(@PathVariable("id") int brokerId)
{
return kafkaMonitor.getBroker(brokerId).orElseThrow(() -> new BrokerNotFoundException(String.valueOf(brokerId)));
}

@ApiOperation(value = "getAllBrokers", notes = "Get details for all known Kafka brokers")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = BrokerVO.class)
})
@RequestMapping(path = "/broker", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public @ResponseBody List<BrokerVO> brokerDetailsJson()
{
return kafkaMonitor.getBrokers();
}
}
Loading

0 comments on commit 7fb5884

Please sign in to comment.