当前位置:   article > 正文

实现Kong的Java管理API - Kong最佳实践

java中的kong

Kong提供了Http的管理API,可以实现对Kong的管理。我们利用Kong的Amin API,实现一套JAVA的管理API。这里以添加一个Service和Route为示例:

使用retrofit2实现

添加Maven依赖

  1. <dependency>
  2. <groupId>com.squareup.retrofit2</groupId>
  3. <artifactId>retrofit</artifactId>
  4. <version>${retrofit.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.squareup.retrofit2</groupId>
  8. <artifactId>converter-gson</artifactId>
  9. <version>${retrofit.version}</version>
  10. <exclusions>
  11. <exclusion>
  12. <groupId>com.google.code.gson</groupId>
  13. <artifactId>gson</artifactId>
  14. </exclusion>
  15. </exclusions>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.google.code.gson</groupId>
  19. <artifactId>gson</artifactId>
  20. <version>2.8.1</version>
  21. </dependency>

实现kong客户端的架子

添加Kong客户端

  1. @Data
  2. public class KongClient {
  3. private ServiceService serviceService;
  4. private RouteService routeService;
  5. public KongClient(String adminUrl) {
  6. if (adminUrl == null || adminUrl.isEmpty()) {
  7. throw new IllegalArgumentException("The adminUrl cannot be null or empty!");
  8. }
  9. RetrofitServiceCreator retrofitServiceCreatorForAdminUrl = new RetrofitServiceCreator(adminUrl);
  10. {
  11. serviceService = retrofitServiceCreatorForAdminUrl.create(ServiceService.class,RetrofitServiceService.class);
  12. routeService = retrofitServiceCreatorForAdminUrl.create(RouteService.class,RetrofitRouteService.class);
  13. }
  14. }
  15. }

添加Retrofit处理类

  1. public class RetrofitServiceCreator {
  2. private Retrofit retrofit;
  3. // -------------------------------------------------------------------
  4. public RetrofitServiceCreator(String baseUrl) {
  5. retrofit = new Retrofit.Builder()
  6. .baseUrl(baseUrl)
  7. .client(initOkHttpClient(baseUrl.toLowerCase().startsWith("https"))) // support https
  8. .addConverterFactory(CustomGsonConverterFactory.create()) // replace GsonConverterFactory
  9. }
  10. // -------------------------------------------------------------------
  11. @SuppressWarnings("unchecked")
  12. public <T> T create(Class<T> serviceInterface, Class<?> retrofitServiceInterface) {
  13. Object proxied = retrofit.create(retrofitServiceInterface);
  14. return (T) Proxy.newProxyInstance(
  15. RetrofitServiceCreator.class.getClassLoader(),
  16. new Class[] { serviceInterface },
  17. new RetrofitBodyExtractorInvocationHandler(proxied));
  18. }
  19. public <T> T createRetrofitService(Class<T> retrofitServiceInterface) {
  20. return retrofit.create(retrofitServiceInterface);
  21. }
  22. // -------------------------------------------------------------------
  23. private OkHttpClient initOkHttpClient(boolean supportHttps) {
  24. if(supportHttps) {
  25. HttpsUtil.SSLParams sslParams = HttpsUtil.getSslSocketFactory(null, null, null);
  26. OkHttpClient okHttpClient = new OkHttpClient.Builder()
  27. .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
  28. .build();
  29. return okHttpClient;
  30. }
  31. return new OkHttpClient.Builder().build();
  32. }
  33. }

添加动态代理处理类

  1. @Slf4j
  2. public class RetrofitBodyExtractorInvocationHandler implements InvocationHandler {
  3. private Object proxied;
  4. public RetrofitBodyExtractorInvocationHandler(Object proxied) {
  5. this.proxied = proxied;
  6. }
  7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  8. String methodName = method.getName();
  9. Class<?>[] parameterTypes = method.getParameterTypes();
  10. Method method1 = proxied.getClass().getMethod(methodName, parameterTypes);
  11. Call call = (Call) method1.invoke(proxied, args);
  12. Response response = call.execute();
  13. log.debug("Http Request: " + response.raw().request());
  14. log.debug("Http Response: " + response.raw().toString());
  15. if(!response.isSuccessful()) {
  16. throw new KongClientException(response.errorBody() != null ? response.errorBody().string() : String.valueOf(response.code()));
  17. }
  18. return response.body();
  19. }
  20. }

添加自定义JSON转换工厂

  1. class CustomGsonConverterFactory extends Converter.Factory {
  2. private final Gson gson;
  3. private CustomGsonConverterFactory(Gson gson) {
  4. if (gson == null) throw new NullPointerException("gson == null");
  5. this.gson = gson;
  6. }
  7. public static CustomGsonConverterFactory create() {
  8. return create(new Gson());
  9. }
  10. public static CustomGsonConverterFactory create(Gson gson) {
  11. return new CustomGsonConverterFactory(gson);
  12. }
  13. @Override
  14. public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
  15. TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
  16. return new CustomGsonResponseBodyConverter<>(gson, adapter);
  17. }
  18. @Override
  19. public Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
  20. TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
  21. return new CustomGsonRequestBodyConverter<>(gson, adapter);
  22. }
  23. }

实现Service的Java Admin API

添加Service实体

  1. @Data @Builder
  2. public class Service {
  3. private String id;
  4. private String name;
  5. private String protocol;
  6. private String host;
  7. private Integer port;
  8. private String path;
  9. private String url;
  10. private Integer retries;
  11. @SerializedName("connect_timeout")
  12. private Long connectTimeout;
  13. @SerializedName("read_timeout")
  14. private Long readTimeout;
  15. @SerializedName("write_timeout")
  16. private Long writeTimeout;
  17. @SerializedName("created_at")
  18. private Long createdAt;
  19. @SerializedName("updated_at")
  20. private Long updatedAt;
  21. }

添加Service接口,这里只要删除和新增

  1. public interface ServiceService {
  2. Service addService(Service service);
  3. void deleteService(String nameOrId);
  4. }

添加Retrofit的处理接口

  1. public interface RetrofitServiceService {
  2. @POST("services/")
  3. Call<Service> addService(@Body Service request);
  4. @DELETE("services/{nameOrId}")
  5. Call<Void> deleteService(@Path("nameOrId") String nameOrId);
  6. }

实现Route的Java Admin API

添加Route实体

  1. @Data @Builder
  2. public class Route {
  3. private String id;
  4. private List<String> protocols;
  5. private List<String> methods;
  6. private List<String> hosts;
  7. private List<String> paths;
  8. @SerializedName("strip_path")
  9. private Boolean stripPath;
  10. @SerializedName("preserve_host")
  11. private Boolean preserveHost;
  12. private Service service;
  13. @SerializedName("created_at")
  14. private Long createdAt;
  15. @SerializedName("updated_at")
  16. private Long updatedAt;
  17. }

添加Route接口,这里只要删除和新增

  1. public interface RouteService {
  2. Route addRoute(Route route);
  3. void DeleteRoute(String id);
  4. }

添加Retrofit的处理接口

  1. public interface RetrofitRouteService {
  2. @POST("routes/")
  3. Call<Route> addRoute(@Body Route route);
  4. @DELETE("routes/{id}")
  5. Call<Void> DeleteRoute(@Path("id") String id);
  6. }

单元测试一下

新建一个名字为example-service,地址为http://mockbin.org的Service。并为Service添加host为example.com的Route路由。

  1. public class ServiceRouteTest extends BaseTest {
  2. public static final String EXAMPLE_SERVICE = "example-service";
  3. @Test
  4. public void createServiceAndRouteTest(){
  5. // 删除Route和Service
  6. CommonList<Route> commonList = kongClient.getRouteService().listRoutesByService(EXAMPLE_SERVICE);
  7. List<Route> routeList = commonList.getData();
  8. if(null!=routeList && routeList.size()>0 ){
  9. for (Route route : routeList) {
  10. kongClient.getRouteService().DeleteRoute(route.getId());
  11. }
  12. }
  13. kongClient.getServiceService().deleteService(EXAMPLE_SERVICE);
  14. // 新建Service和Route
  15. Service service = Service.builder().url("http://mockbin.org").name(EXAMPLE_SERVICE).build();
  16. Service response4service = kongClient.getServiceService().addService(service);
  17. printJson(response4service);
  18. List<String> hostList = new ArrayList<>();
  19. hostList.add("example.com");
  20. Route route = Route.builder().hosts(hostList).service(Service.builder().id(response4service.getId()).build()).build();
  21. Route response4route = kongClient.getRouteService().addRoute(route);
  22. printJson(response4route);
  23. }
  24. }

最后,检查下效果

使用GET方法,访问地址http://192.168.56.112:8000,并添加在头部添加host[]=example.com,结果如下:

使用Postman测试Kong

写在最后

  • 利用架子可以自定义其他Kong的JAVA客户端。
  • 很多时候,我们的API地址是通过程序扫描出来的,或者管理系统进行配置的。这个时候,我们就可以利用Kong的JAVA客户端快速的实现Kong的接口管理,轮训等。
  • 应用降级,流控,金丝雀,灰度等等,都可以通过Kong的JAVA客户端轻松实现。

转载于:https://my.oschina.net/u/1404949/blog/3039448

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/956455
推荐阅读
相关标签
  

闽ICP备14008679号