Kong提供了Http的管理API,可以实现对Kong的管理。我们利用Kong的Amin API,实现一套JAVA的管理API。这里以添加一个Service和Route为示例:
使用retrofit2实现
添加Maven依赖
- <dependency>
- <groupId>com.squareup.retrofit2</groupId>
- <artifactId>retrofit</artifactId>
- <version>${retrofit.version}</version>
- </dependency>
- <dependency>
- <groupId>com.squareup.retrofit2</groupId>
- <artifactId>converter-gson</artifactId>
- <version>${retrofit.version}</version>
- <exclusions>
- <exclusion>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.8.1</version>
- </dependency>
实现kong客户端的架子
添加Kong客户端
- @Data
- public class KongClient {
-
- private ServiceService serviceService;
- private RouteService routeService;
-
- public KongClient(String adminUrl) {
-
- if (adminUrl == null || adminUrl.isEmpty()) {
- throw new IllegalArgumentException("The adminUrl cannot be null or empty!");
- }
- RetrofitServiceCreator retrofitServiceCreatorForAdminUrl = new RetrofitServiceCreator(adminUrl);
- {
- serviceService = retrofitServiceCreatorForAdminUrl.create(ServiceService.class,RetrofitServiceService.class);
- routeService = retrofitServiceCreatorForAdminUrl.create(RouteService.class,RetrofitRouteService.class);
- }
- }
- }
添加Retrofit处理类
- public class RetrofitServiceCreator {
-
- private Retrofit retrofit;
-
-
- // -------------------------------------------------------------------
-
- public RetrofitServiceCreator(String baseUrl) {
-
- retrofit = new Retrofit.Builder()
- .baseUrl(baseUrl)
- .client(initOkHttpClient(baseUrl.toLowerCase().startsWith("https"))) // support https
- .addConverterFactory(CustomGsonConverterFactory.create()) // replace GsonConverterFactory
-
- }
-
- // -------------------------------------------------------------------
-
- @SuppressWarnings("unchecked")
- public <T> T create(Class<T> serviceInterface, Class<?> retrofitServiceInterface) {
- Object proxied = retrofit.create(retrofitServiceInterface);
- return (T) Proxy.newProxyInstance(
- RetrofitServiceCreator.class.getClassLoader(),
- new Class[] { serviceInterface },
- new RetrofitBodyExtractorInvocationHandler(proxied));
- }
-
- public <T> T createRetrofitService(Class<T> retrofitServiceInterface) {
- return retrofit.create(retrofitServiceInterface);
- }
-
- // -------------------------------------------------------------------
-
- private OkHttpClient initOkHttpClient(boolean supportHttps) {
-
- if(supportHttps) {
- HttpsUtil.SSLParams sslParams = HttpsUtil.getSslSocketFactory(null, null, null);
- OkHttpClient okHttpClient = new OkHttpClient.Builder()
- .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
- .build();
- return okHttpClient;
- }
-
- return new OkHttpClient.Builder().build();
- }
- }
添加动态代理处理类
- @Slf4j
- public class RetrofitBodyExtractorInvocationHandler implements InvocationHandler {
-
- private Object proxied;
-
- public RetrofitBodyExtractorInvocationHandler(Object proxied) {
- this.proxied = proxied;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- String methodName = method.getName();
- Class<?>[] parameterTypes = method.getParameterTypes();
- Method method1 = proxied.getClass().getMethod(methodName, parameterTypes);
- Call call = (Call) method1.invoke(proxied, args);
- Response response = call.execute();
- log.debug("Http Request: " + response.raw().request());
- log.debug("Http Response: " + response.raw().toString());
- if(!response.isSuccessful()) {
- throw new KongClientException(response.errorBody() != null ? response.errorBody().string() : String.valueOf(response.code()));
- }
- return response.body();
- }
- }
添加自定义JSON转换工厂
- class CustomGsonConverterFactory extends Converter.Factory {
-
- private final Gson gson;
-
- private CustomGsonConverterFactory(Gson gson) {
- if (gson == null) throw new NullPointerException("gson == null");
- this.gson = gson;
- }
-
- public static CustomGsonConverterFactory create() {
- return create(new Gson());
- }
-
- public static CustomGsonConverterFactory create(Gson gson) {
- return new CustomGsonConverterFactory(gson);
- }
-
- @Override
- public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
- TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
- return new CustomGsonResponseBodyConverter<>(gson, adapter);
- }
-
- @Override
- public Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
- TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
- return new CustomGsonRequestBodyConverter<>(gson, adapter);
- }
- }
实现Service的Java Admin API
添加Service实体
- @Data @Builder
- public class Service {
-
- private String id;
- private String name;
- private String protocol;
- private String host;
- private Integer port;
- private String path;
- private String url;
- private Integer retries;
- @SerializedName("connect_timeout")
- private Long connectTimeout;
- @SerializedName("read_timeout")
- private Long readTimeout;
- @SerializedName("write_timeout")
- private Long writeTimeout;
- @SerializedName("created_at")
- private Long createdAt;
- @SerializedName("updated_at")
- private Long updatedAt;
- }
添加Service接口,这里只要删除和新增
- public interface ServiceService {
-
- Service addService(Service service);
- void deleteService(String nameOrId);
- }
添加Retrofit的处理接口
- public interface RetrofitServiceService {
-
- @POST("services/")
- Call<Service> addService(@Body Service request);
- @DELETE("services/{nameOrId}")
- Call<Void> deleteService(@Path("nameOrId") String nameOrId);
- }
实现Route的Java Admin API
添加Route实体
- @Data @Builder
- public class Route {
-
- private String id;
- private List<String> protocols;
- private List<String> methods;
- private List<String> hosts;
- private List<String> paths;
- @SerializedName("strip_path")
- private Boolean stripPath;
- @SerializedName("preserve_host")
- private Boolean preserveHost;
- private Service service;
- @SerializedName("created_at")
- private Long createdAt;
- @SerializedName("updated_at")
- private Long updatedAt;
- }
添加Route接口,这里只要删除和新增
- public interface RouteService {
-
- Route addRoute(Route route);
- void DeleteRoute(String id);
- }
添加Retrofit的处理接口
- public interface RetrofitRouteService {
- @POST("routes/")
- Call<Route> addRoute(@Body Route route);
- @DELETE("routes/{id}")
- Call<Void> DeleteRoute(@Path("id") String id);
- }
单元测试一下
新建一个名字为example-service
,地址为http://mockbin.org
的Service。并为Service添加host为example.com
的Route路由。
- public class ServiceRouteTest extends BaseTest {
-
- public static final String EXAMPLE_SERVICE = "example-service";
-
- @Test
- public void createServiceAndRouteTest(){
-
- // 删除Route和Service
- CommonList<Route> commonList = kongClient.getRouteService().listRoutesByService(EXAMPLE_SERVICE);
- List<Route> routeList = commonList.getData();
- if(null!=routeList && routeList.size()>0 ){
- for (Route route : routeList) {
- kongClient.getRouteService().DeleteRoute(route.getId());
- }
- }
- kongClient.getServiceService().deleteService(EXAMPLE_SERVICE);
-
-
- // 新建Service和Route
- Service service = Service.builder().url("http://mockbin.org").name(EXAMPLE_SERVICE).build();
- Service response4service = kongClient.getServiceService().addService(service);
- printJson(response4service);
- List<String> hostList = new ArrayList<>();
- hostList.add("example.com");
- Route route = Route.builder().hosts(hostList).service(Service.builder().id(response4service.getId()).build()).build();
- Route response4route = kongClient.getRouteService().addRoute(route);
- printJson(response4route);
- }
-
- }
最后,检查下效果
使用GET
方法,访问地址http://192.168.56.112:8000
,并添加在头部添加host[]=example.com
,结果如下:
写在最后
- 利用架子可以自定义其他Kong的JAVA客户端。
- 很多时候,我们的API地址是通过程序扫描出来的,或者管理系统进行配置的。这个时候,我们就可以利用Kong的JAVA客户端快速的实现Kong的接口管理,轮训等。
- 应用降级,流控,金丝雀,灰度等等,都可以通过Kong的JAVA客户端轻松实现。