From 4ed15bda06c8e9a407c12d527b8224737ba339d5 Mon Sep 17 00:00:00 2001 From: HuabingZhao Date: Sat, 13 Aug 2016 14:10:39 +0800 Subject: Initial code import Change-Id: I839b84e5200aedece6c33deb16bec1bf9dbb61df Signed-off-by: HuabingZhao --- .../src/main/java/org/openo/msb/ApiRouteApp.java | 550 +++++++++++++++++ .../main/java/org/openo/msb/ApiRouteAppConfig.java | 111 ++++ .../main/java/org/openo/msb/ConsulClientApp.java | 452 ++++++++++++++ .../main/java/org/openo/msb/api/ApiRouteInfo.java | 136 +++++ .../main/java/org/openo/msb/api/ConsulInfo.java | 38 ++ .../org/openo/msb/api/CustomDateSerializer.java | 39 ++ .../java/org/openo/msb/api/CustomRouteInfo.java | 102 ++++ .../main/java/org/openo/msb/api/DiscoverInfo.java | 49 ++ .../main/java/org/openo/msb/api/IuiRouteInfo.java | 102 ++++ .../main/java/org/openo/msb/api/MetricsInfo.java | 191 ++++++ .../org/openo/msb/api/MicroServiceFullInfo.java | 44 ++ .../java/org/openo/msb/api/MicroServiceInfo.java | 38 ++ .../src/main/java/org/openo/msb/api/Node.java | 75 +++ .../src/main/java/org/openo/msb/api/NodeInfo.java | 74 +++ .../main/java/org/openo/msb/api/RouteServer.java | 68 +++ .../src/main/java/org/openo/msb/api/Service.java | 104 ++++ .../java/org/openo/msb/api/ServiceAccessInfo.java | 88 +++ .../ExtendedInternalServerErrorException.java | 28 + .../api/exception/ExtendedNotFoundException.java | 28 + .../exception/ExtendedNotSupportedException.java | 27 + .../org/openo/msb/health/ApiRouteHealthCheck.java | 35 ++ .../org/openo/msb/resources/ApiRouteResource.java | 233 ++++++++ .../openo/msb/resources/CustomRouteResource.java | 152 +++++ .../org/openo/msb/resources/IuiRouteResource.java | 155 +++++ .../org/openo/msb/resources/MetricsResource.java | 49 ++ .../openo/msb/resources/MicroServiceResource.java | 247 ++++++++ .../openo/msb/resources/ServiceAccessResource.java | 65 ++ .../openo/msb/wrapper/ApiRouteServiceWrapper.java | 653 +++++++++++++++++++++ .../msb/wrapper/CustomRouteServiceWrapper.java | 474 +++++++++++++++ .../openo/msb/wrapper/IuiRouteServiceWrapper.java | 453 ++++++++++++++ .../openo/msb/wrapper/MetricsServiceWrapper.java | 92 +++ .../org/openo/msb/wrapper/MicroServiceWrapper.java | 536 +++++++++++++++++ .../openo/msb/wrapper/ServiceAccessWrapper.java | 172 ++++++ .../openo/msb/wrapper/consul/CatalogClient.java | 285 +++++++++ .../java/org/openo/msb/wrapper/consul/Consul.java | 299 ++++++++++ .../openo/msb/wrapper/consul/ConsulException.java | 42 ++ .../org/openo/msb/wrapper/consul/HealthClient.java | 247 ++++++++ .../consul/async/ConsulResponseCallback.java | 42 ++ .../msb/wrapper/consul/cache/CatalogCache.java | 70 +++ .../msb/wrapper/consul/cache/ConsulCache.java | 230 ++++++++ .../msb/wrapper/consul/cache/ConsulCache4Map.java | 258 ++++++++ .../msb/wrapper/consul/cache/HealthCache.java | 70 +++ .../msb/wrapper/consul/cache/ServiceCache.java | 50 ++ .../msb/wrapper/consul/model/ConsulResponse.java | 80 +++ .../wrapper/consul/model/catalog/CatalogNode.java | 41 ++ .../consul/model/catalog/CatalogService.java | 52 ++ .../consul/model/catalog/ImmutableCatalogNode.java | 306 ++++++++++ .../model/catalog/ImmutableCatalogService.java | 626 ++++++++++++++++++++ .../wrapper/consul/model/catalog/ServiceInfo.java | 63 ++ .../wrapper/consul/model/health/ImmutableNode.java | 266 +++++++++ .../consul/model/health/ImmutableService.java | 478 +++++++++++++++ .../msb/wrapper/consul/model/health/Node.java | 35 ++ .../msb/wrapper/consul/model/health/Service.java | 48 ++ .../wrapper/consul/model/health/ServiceHealth.java | 73 +++ .../msb/wrapper/consul/option/CatalogOptions.java | 39 ++ .../msb/wrapper/consul/option/ConsistencyMode.java | 21 + .../consul/option/ImmutableCatalogOptions.java | 251 ++++++++ .../consul/option/ImmutableQueryOptions.java | 531 +++++++++++++++++ .../openo/msb/wrapper/consul/option/Options.java | 29 + .../msb/wrapper/consul/option/ParamAdder.java | 23 + .../msb/wrapper/consul/option/QueryOptions.java | 100 ++++ .../consul/util/Base64EncodingDeserializer.java | 45 ++ .../openo/msb/wrapper/consul/util/ClientUtil.java | 246 ++++++++ .../org/openo/msb/wrapper/consul/util/Jackson.java | 34 ++ .../consul/util/ObjectMapperContextResolver.java | 35 ++ .../wrapper/consul/util/SecondsDeserializer.java | 43 ++ .../msb/wrapper/consul/util/SecondsSerializer.java | 34 ++ .../consul/util/UnsignedLongDeserializer.java | 37 ++ .../IMicroServiceChangeListener.java | 33 ++ .../MicroServiceChangeListener.java | 306 ++++++++++ .../java/org/openo/msb/wrapper/util/FileUtil.java | 66 +++ .../openo/msb/wrapper/util/JacksonJsonUtil.java | 120 ++++ .../java/org/openo/msb/wrapper/util/JedisUtil.java | 221 +++++++ .../org/openo/msb/wrapper/util/MetricsUtil.java | 24 + .../org/openo/msb/wrapper/util/MicroServiceDB.java | 423 +++++++++++++ .../openo/msb/wrapper/util/MicroServiceUtil.java | 96 +++ .../org/openo/msb/wrapper/util/RegExpTestUtil.java | 88 +++ .../java/org/openo/msb/wrapper/util/RouteUtil.java | 135 +++++ 78 files changed, 12301 insertions(+) create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java (limited to 'apiroute/apiroute-service/src/main/java/org') diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java new file mode 100644 index 0000000..0e0860d --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java @@ -0,0 +1,550 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb; + +import io.dropwizard.Application; +import io.dropwizard.assets.AssetsBundle; +import io.dropwizard.jetty.HttpConnectorFactory; +import io.dropwizard.server.SimpleServerFactory; +import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; +import io.swagger.jaxrs.config.BeanConfig; +import io.swagger.jaxrs.listing.ApiListingResource; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import net.sf.json.JSONObject; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.ApiRouteInfo; +import org.openo.msb.api.ConsulInfo; +import org.openo.msb.api.CustomRouteInfo; +import org.openo.msb.api.DiscoverInfo; +import org.openo.msb.api.IuiRouteInfo; +import org.openo.msb.api.RouteServer; +import org.openo.msb.api.exception.ExtendedNotFoundException; +import org.openo.msb.health.ApiRouteHealthCheck; +import org.openo.msb.resources.ApiRouteResource; +import org.openo.msb.resources.CustomRouteResource; +import org.openo.msb.resources.IuiRouteResource; +import org.openo.msb.resources.MetricsResource; +import org.openo.msb.resources.MicroServiceResource; +import org.openo.msb.resources.ServiceAccessResource; +import org.openo.msb.wrapper.ApiRouteServiceWrapper; +import org.openo.msb.wrapper.CustomRouteServiceWrapper; +import org.openo.msb.wrapper.IuiRouteServiceWrapper; +import org.openo.msb.wrapper.serviceListener.MicroServiceChangeListener; +import org.openo.msb.wrapper.util.FileUtil; +import org.openo.msb.wrapper.util.JacksonJsonUtil; +import org.openo.msb.wrapper.util.JedisUtil; +import org.openo.msb.wrapper.util.MetricsUtil; +import org.openo.msb.wrapper.util.MicroServiceDB; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonInclude; + +public class ApiRouteApp extends Application { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class); + + public static void main(String[] args) throws Exception { + new ApiRouteApp().run(args); + + } + + private ApiRouteAppConfig config; + + @Override + public String getName() { + return " MicroService Bus "; + } + + @Override + public void initialize(Bootstrap bootstrap) { + + + } + + @Override + public void run(ApiRouteAppConfig configuration, Environment environment) { + + initRootPath(); + + + new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics", + "index.html", "iui-metrics").run(environment); + + new AssetsBundle("/iui-route", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html", + "iui-microservices").run(environment); + + new AssetsBundle("/api-doc", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc", + "index.html", "api-doc").run(environment); + + new AssetsBundle("/ext", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext", + "index.html", "ext").run(environment); + + + + + final ApiRouteHealthCheck healthCheck = + new ApiRouteHealthCheck(configuration.getDefaultWorkspace()); + environment.healthChecks().register("template", healthCheck); + environment.jersey().register(new ApiRouteResource()); + environment.jersey().register(new IuiRouteResource()); + environment.jersey().register(new MetricsResource()); + environment.jersey().register(new CustomRouteResource()); + environment.jersey().register(new ServiceAccessResource()); + environment.jersey().register(new MicroServiceResource()); + + config = configuration; + + initSwaggerConfig(environment, configuration); + initRedisConfig(configuration); + checkRedisConnect(); + initMetricsConfig(configuration); + initVisualRangeMatches(); + + registerServiceChangeListener(); + + + } + + private void initMetricsConfig(ApiRouteAppConfig configuration) { + + SimpleServerFactory simpleServerFactory = + (SimpleServerFactory) configuration.getServerFactory(); + HttpConnectorFactory httpConnectorFactory = + (HttpConnectorFactory) simpleServerFactory.getConnector(); + MetricsUtil.adminContextPath = + "http://127.0.0.1:" + httpConnectorFactory.getPort() + + simpleServerFactory.getAdminContextPath() + "/metrics"; + } + + private void initSwaggerConfig(Environment environment, ApiRouteAppConfig configuration) { + + environment.jersey().register(new ApiListingResource()); + environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); + + BeanConfig config = new BeanConfig(); + config.setTitle("MicroService Bus rest API"); + config.setVersion("1.0.0"); + config.setResourcePackage("org.openo.msb.resources"); + SimpleServerFactory simpleServerFactory = + (SimpleServerFactory) configuration.getServerFactory(); + String basePath = simpleServerFactory.getApplicationContextPath(); + String rootPath = simpleServerFactory.getJerseyRootPath(); + + rootPath = rootPath.substring(0, rootPath.indexOf("/*")); + + basePath = + basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath) + .append(rootPath).toString(); + + LOGGER.info("getApplicationContextPath: " + basePath); + config.setBasePath(basePath); + config.setScan(true); + } + + + private void initRootPath(){ + try { + + URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json"); + if (urlRootPath != null) { + String path = urlRootPath.getPath(); + + LOGGER.info("read initUrlRootPath:" + path); + + String fileContent = FileUtil.readFile(path); + JSONObject jsonObj = JSONObject.fromObject(fileContent); + RouteUtil.IUI_ROOT_PATH=jsonObj.get("iuiRootPath").toString(); + RouteUtil.API_ROOT_PATH=jsonObj.get("apiRootPath").toString(); + } + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("read initUrlRootPath Files throw exception", e); + } + + } + private void initRedisConfig(ApiRouteAppConfig configuration) { + + String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); + String jarPath = path.substring(0, path.lastIndexOf("/")); + + LOGGER.info("jarpath: " + jarPath); + LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace()); + + String confDir = + jarPath + "/" + configuration.getDefaultWorkspace() + "/" + + configuration.getPropertiesDir(); + String propertiesPath = confDir + "/" + configuration.getPropertiesName(); + + JedisUtil.propertiesPath = propertiesPath; + + LOGGER.info("propertiesPath: " + propertiesPath); + LOGGER.info("confDir: " + confDir); + + try { + File dirFile = new File(confDir); + + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage()); + } + + + try { + File propertiesFile = new File(propertiesPath); + if (!propertiesFile.exists()) { + + + propertiesFile.createNewFile(); + + BufferedWriter output = new BufferedWriter(new FileWriter(propertiesFile)); + StringBuilder contentBuilder = new StringBuilder(); + contentBuilder.append("redis.host=127.0.0.1\n").append("redis.port=6379\n") + .append("#connectionTimeout\n").append("redis.connectionTimeout=2000\n") + .append("#redis dbIndex,defaule:0\n") + .append("redis.db_index=0\n\n") + .append("#--------------redis pool config--------------\n") + .append("#maxTotal\n").append("redis.pool.maxTotal=100\n") + .append("#maxIdle\n").append("redis.pool.maxIdle=20\n") + .append("#maxWaitMillis:ms\n") + .append("redis.pool.maxWaitMillis=1000\n") + .append("#testOnBorrow\n") + .append("redis.pool.testOnBorrow=false\n") + .append("#testOnReturn\n") + .append("redis.pool.testOnReturn=true\n") + .append("#nginx Port\n").append("server.port=10080\n"); + + output.write(contentBuilder.toString()); + output.close(); + + } + } catch (IOException e) { + // TODO Auto-generated catch block + LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage()); + } + } + + + private void checkRedisConnect() { + + new Thread(new Runnable() { + public void run() { + int n = 0; + while (true) { + if (ApiRouteServiceWrapper.checkRedisConnect() == false) { + n++; + System.out.println(n + + "/10 : Initial Route Configuration——redis connection fail..."); + + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + LOGGER.error("Thread.sleep throw except:"+e.getMessage()); + } + + + if (n >= 10) { + System.out.println("Initial Route Configuration fail,timeout exit"); + LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit..."); + break; + } + } else { + System.out.println("starting to initial Route Configuration"); + // initRouteInfoFromConfig(); + initRouteInfoFromJson(); + System.out.println("starting to initial consul Configuration"); + runConsulClientApp(); + + break; + } + } + + } + }).start(); + } + + + + + /** + * @Title: initVisualRangeMatches + * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions) + * @return: void + */ + private void initVisualRangeMatches(){ + try { + if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null) + { + + URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json"); + if (visualRangePath != null) { + String path = visualRangePath.getPath(); + + LOGGER.info("read initVisualRangeMatches:" + path); + + String fileContent = FileUtil.readFile(path); + JSONObject jsonObj = JSONObject.fromObject(fileContent); + String visualRangeArray=jsonObj.get("visualRange").toString(); + + + RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ","); + + + + } + } + else{ + RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ","); + } + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("read initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e); + } + } + + /** + * @Title: initRouteInfoFromJson + * @Description: TODO(按照JSON文件配置初始化route数据) + * @return: void + */ + private void initRouteInfoFromJson() { + + URL apiDocsPath = ApiRouteApp.class.getResource("/ext/initServices"); + if (apiDocsPath != null) { + String path = apiDocsPath.getPath(); + + LOGGER.info("read JsonFilefolder:" + path); + + try { + File[] files = FileUtil.readFileFolder(path); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isFile() && file.getName().endsWith(".json")) { + LOGGER.info("read JsonFile:" + file.getPath()); + String fileContent = FileUtil.readFile(file.getPath()); + saveInitService2redis(fileContent); + } else { + LOGGER.warn(file.getName() + " is not a right file"); + } + } + + + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + LOGGER.error("read initServices Files throw FileNotFoundException", e); + } catch (IOException e) { + // TODO Auto-generated catch block + LOGGER.error("read initServices Files throw IOexception", e); + } + + } + + + + } + + + + private void saveInitService2redis(String fileContent) { + try { + List routeList = + (List) JacksonJsonUtil.jsonToListBean(fileContent); + for (ApiRouteInfo route : routeList) { + String url = route.getUrl(); + + if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) { + + try{ + CustomRouteInfo dbCustomRoute = + CustomRouteServiceWrapper.getInstance().getCustomRouteInstance( + route.getServiceName()); + } + catch(ExtendedNotFoundException e){ + + LOGGER.info("initCustomRoute: ServiceName--" + route.getServiceName()); + + CustomRouteInfo customRouteInfo = new CustomRouteInfo(); + customRouteInfo.setControl(route.getControl()); + customRouteInfo.setServers(route.getServers()); + customRouteInfo.setServiceName(route.getServiceName()); + customRouteInfo.setStatus(route.getStatus()); + customRouteInfo.setUrl(route.getUrl()); + + + CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance( + customRouteInfo, ""); + + + } + } else { + + if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) { + + + try{ + ApiRouteInfo dbApiRoute = + ApiRouteServiceWrapper.getInstance().getApiRouteInstance( + route.getServiceName(), route.getVersion()); + } + catch(ExtendedNotFoundException e){ + LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName()); + ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, ""); + } + + + } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) { + + try{ + IuiRouteInfo dbIuiRoute = + IuiRouteServiceWrapper.getInstance().getIuiRouteInstance( + route.getServiceName()); + } + catch(ExtendedNotFoundException e){ + + LOGGER.info(" initiuiRoute: ServiceName--" + route.getServiceName()); + IuiRouteInfo iuiRouteInfo = new IuiRouteInfo(); + iuiRouteInfo.setControl(route.getControl()); + iuiRouteInfo.setServers(route.getServers()); + iuiRouteInfo.setServiceName(route.getServiceName()); + iuiRouteInfo.setStatus(route.getStatus()); + + if(url.equals("/iui/microservices")){ + iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices"); + } + else{ + iuiRouteInfo.setUrl(route.getUrl()); + } + + IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); + + } + + } else { + LOGGER.error("init Service throw exception——serviceName: " + route.getServiceName()+",url:"+url); + } + } + + + + } + + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("read initServices Files throw exception", e); + } + + } + + + + /** + * The listener registration service changes + */ + private void registerServiceChangeListener() { + MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener()); + } + + // Open the consul to monitor subscription service + private void runConsulClientApp() { + DiscoverInfo config_discoverInfo = config.getDiscoverInfo(); + + ConsulInfo config_consulInfo=config.getConsulInfo(); + + RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled()); + + if (config_discoverInfo.isEnabled()) { + try{ + if(System.getenv("SDCLIENT_SVC_PORT")==null) + { + //yml + RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp()); + RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort()); + + } + else{ + + String discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1]; + String sdIP=discoverAddress.split(":")[0]; + int sdPort=Integer + .parseInt(discoverAddress.split(":")[1]); + + RouteUtil.discoverInfo.setIp(sdIP); + RouteUtil.discoverInfo.setPort(sdPort); + + config_consulInfo.setIp(sdIP); + config_consulInfo.setPort(sdPort); + + + } + + + + //Registration service discovery routing + //api + ApiRouteInfo discoverApiService=new ApiRouteInfo(); + discoverApiService.setServiceName("msdiscover"); + discoverApiService.setUrl("/api/microservices/v1"); + discoverApiService.setVersion("v1"); + discoverApiService.setMetricsUrl("/admin/metrics"); + discoverApiService.setApiJson("/api/microservices/v1/swagger.json"); + + RouteServer[] servers=new RouteServer[1]; + servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort())); + discoverApiService.setServers(servers); + + ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, ""); + + //iui + IuiRouteInfo discoverIUIService=new IuiRouteInfo(); + discoverIUIService.setServiceName("msdiscover"); + discoverIUIService.setUrl("/iui/microservices"); + discoverIUIService.setServers(servers); + IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService); + + + + ConsulClientApp consulClientApp = new ConsulClientApp(config_consulInfo.getIp(), config_consulInfo.getPort()); + // Monitor service change + consulClientApp.startServiceListen(); + LOGGER.info("start monitor consul service--" +config_consulInfo.getIp() + ":" + + config_consulInfo.getPort()); + } + catch(Exception e){ + LOGGER.error("start monitor consul service fail:"+e.getMessage()); + } + } + + + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java new file mode 100644 index 0000000..6439462 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java @@ -0,0 +1,111 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb; + +import io.dropwizard.Configuration; + +import javax.validation.Valid; + +import org.hibernate.validator.constraints.NotEmpty; +import org.openo.msb.api.ConsulInfo; +import org.openo.msb.api.DiscoverInfo; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ApiRouteAppConfig extends Configuration { + @NotEmpty + private String defaultWorkspace = "apiroute-works"; + + @NotEmpty + private String defaultName = "Stranger"; + + @NotEmpty + private String propertiesName="redis.properties"; + + @NotEmpty + private String propertiesDir="conf"; + + + @Valid + private DiscoverInfo discoverInfo; + + @Valid + private ConsulInfo consulInfo; + + @JsonProperty + public ConsulInfo getConsulInfo() { + return consulInfo; + } + + @JsonProperty + public void setConsulInfo(ConsulInfo consulInfo) { + this.consulInfo = consulInfo; + } + + + public String getPropertiesDir() { + return propertiesDir; + } + + public void setPropertiesDir(String propertiesDir) { + this.propertiesDir = propertiesDir; + } + + public String getPropertiesName() { + return propertiesName; + } + + public void setPropertiesName(String propertiesName) { + this.propertiesName = propertiesName; + } + + @JsonProperty + public String getDefaultWorkspace() { + return defaultWorkspace; + } + + @JsonProperty + public void setDefaultWorkspace(String defaultWorkspace) { + this.defaultWorkspace = defaultWorkspace; + } + + @JsonProperty + public String getDefaultName() { + return defaultName; + } + + @JsonProperty + public void setDefaultName(String name) { + this.defaultName = name; + } + + + + @JsonProperty + public DiscoverInfo getDiscoverInfo() { + return discoverInfo; + } + + @JsonProperty + public void setDiscoverInfo(DiscoverInfo discoverInfo) { + this.discoverInfo = discoverInfo; + } + + + + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java new file mode 100644 index 0000000..bb0ff66 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java @@ -0,0 +1,452 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.MicroServiceFullInfo; +import org.openo.msb.api.MicroServiceInfo; +import org.openo.msb.api.Node; +import org.openo.msb.wrapper.MicroServiceWrapper; +import org.openo.msb.wrapper.consul.CatalogClient; +import org.openo.msb.wrapper.consul.Consul; +import org.openo.msb.wrapper.consul.HealthClient; +import org.openo.msb.wrapper.consul.cache.CatalogCache; +import org.openo.msb.wrapper.consul.cache.ConsulCache; +import org.openo.msb.wrapper.consul.cache.ConsulCache4Map; +import org.openo.msb.wrapper.consul.cache.HealthCache; +import org.openo.msb.wrapper.consul.cache.ServiceCache; +import org.openo.msb.wrapper.consul.model.catalog.CatalogService; +import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; +import org.openo.msb.wrapper.consul.model.health.Service; +import org.openo.msb.wrapper.consul.model.health.ServiceHealth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConsulClientApp { + + private final Consul consul; + private final CatalogClient catalogClient; + private final HealthClient healthClient; + private AtomicReference> cacheList = new AtomicReference>( + new ArrayList()); + + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulClientApp.class); + + public ConsulClientApp(String ip, int port) { + URL url = null; + try { + url = new URL("http", ip, port, ""); + } catch (MalformedURLException e1) { + // TODO Auto-generated catch block + LOGGER.error("start ConsulClientApp throw exception", e1); + throw new RuntimeException(e1); + } + this.consul = Consul.builder().withUrl(url).build(); // connect to Consul on localhost + this.catalogClient = consul.catalogClient(); + this.healthClient = consul.healthClient(); + } + + public Consul getConsul() { + return consul; + } + + public CatalogClient getCatalogClient() { + return catalogClient; + } + + private void stopNodeListen(String serviceName) { + try { + + ListIterator cacheListLit = cacheList.get().listIterator(); + while (cacheListLit.hasNext()) { + HealthCache cache = (HealthCache) cacheListLit.next(); + if (cache.getServiceName().equals(serviceName)) { + + cache.stop(); + cacheListLit.remove(); + LOGGER.info(cache.getServiceName() + " NodeListen stoped"); + break; + } + } + + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("stop Node:[" + serviceName + "] Listen throw exception", e); + } + + + } + + /** + * @Title startServiceListen + * @Description TODO(Open the consul registration services to monitor) + * @return void + */ + public void startServiceListen() { + final ServiceCache serviceCache = ServiceCache.newCache(catalogClient, 30); + serviceCache.addListener(new ConsulCache4Map.Listener>>() { + @Override + public void notify(List oldValues, List newValues) { + // do Something with updated server List + LOGGER.info("--new service notify--"); + + List deRegisterServiceList = getDiffrent(oldValues, newValues); + + + for (ServiceInfo serviceInfo : deRegisterServiceList) { + try { + + MicroServiceWrapper.getInstance().deleteMicroService( + serviceInfo.getServiceName(), serviceInfo.getVersion()); + + + stopNodeListen(serviceInfo.getServiceName()); + LOGGER.info("Cancel MicroServiceInfo and stop node listen successs:" + + serviceInfo.getServiceName()); + } catch (Exception e) { + LOGGER.error("Cancel MicroServiceInfo and stop node listen FAIL : ", e); + + } + + } + + + List registerServiceList = getDiffrent(newValues, oldValues); + for (ServiceInfo serviceInfo : registerServiceList) { + + // if (deRegisterServiceList.contains(serviceInfo)) continue; + + + LOGGER.info(" new serviceName:" + serviceInfo.getServiceName() + " version:" + + serviceInfo.getVersion()); + // Open Node to monitor new registration service + startHealthNodeListen(serviceInfo.getServiceName(), serviceInfo.getVersion()); + + } + + + } + + }); + + try { + LOGGER.info("start...consul ... service..Listening."); + serviceCache.start(); + + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("start...service..Listen throw exception", e); + } + } + + + /** + * @Title startHealthNodeListen + * @Description TODO(Open a service node changes to monitor, only to return to health service) + * @param serviceName + * @return + * @return HealthCache + */ + private HealthCache startHealthNodeListen(final String serviceName, final String version) { + final HealthCache healthCache = HealthCache.newCache(healthClient, serviceName, 30); + healthCache.addListener(new HealthCache.Listener() { + @Override + public void notify(Map newValues) { + // do Something with updated server map + LOGGER.info(serviceName + "--new node notify--"); + + if (newValues.isEmpty()) { + LOGGER.info(serviceName + "--nodeList is Empty--"); + + + MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version); + + // try { + // healthCache.stop(); + // } catch (Exception e) { + // LOGGER.equals(serviceName+"-- stop Node error:"+e.getMessage()); + // } + + } else { + + MicroServiceInfo microServiceInfo = new MicroServiceInfo(); + HashSet nodes = new HashSet(); + String url = ""; + String version = "", visualRange = "", protocol = "",lb_policy=""; + + for (Map.Entry entry : newValues.entrySet()) { + String nodeName = entry.getKey().toString(); + ServiceHealth value = (ServiceHealth) entry.getValue(); + + Node node = new Node(); + Service service = value.getService(); + node.setIp(service.getAddress()); + node.setPort(String.valueOf(service.getPort())); + + + try { + List tagList = service.getTags(); + for (String tag : tagList) { + if (tag.startsWith("url")) { + if (tag.split(":").length == 2) { + url = tag.split(":")[1]; + } else { + url = ""; + } + + + continue; + } + if (tag.startsWith("version")) { + if (tag.split(":").length == 2) { + version = tag.split(":")[1]; + } else { + version = ""; + } + continue; + } + if (tag.startsWith("protocol")) { + protocol = tag.split(":")[1]; + continue; + } + if (tag.startsWith("visualRange")) { + visualRange = tag.split(":")[1]; + continue; + } + + if (tag.startsWith("lb_policy")) { + lb_policy = tag.split(":")[1]; + continue; + } + + } + + + } catch (Exception e) { + LOGGER.error(serviceName + " read tag throw exception", e); + System.out.println(serviceName + " read tag throw exception"); + } + + nodes.add(node); + } + + microServiceInfo.setNodes(nodes); + microServiceInfo.setProtocol(protocol); + microServiceInfo.setUrl(url); + microServiceInfo.setServiceName(serviceName); + microServiceInfo.setLb_policy(lb_policy); + if (!visualRange.isEmpty()) { + microServiceInfo.setVisualRange(visualRange); + } + microServiceInfo.setVersion(version); + + try { + MicroServiceFullInfo microServiceFullInfo = + MicroServiceWrapper.getInstance().saveMicroServiceInstance( + microServiceInfo, false, "", ""); + LOGGER.info("register MicroServiceInfo successs:" + + microServiceFullInfo.getServiceName()); + } catch (Exception e) { + LOGGER.error("register MicroServiceInfo FAIL : " + serviceName, e); + + } + } + } + }); + try { + LOGGER.info(serviceName + " Node Listen start"); + cacheList.get().add(healthCache); + healthCache.start(); + + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error(serviceName + " Node Listen start throw exception", e); + } + + return healthCache; + } + + /** + * @Title startNodeListen + * @Description TODO(Open a service node changes to monitor) + * @param serviceName + * @return + * @return CatalogCache + */ + @Deprecated + private CatalogCache startNodeListen(final String serviceName) { + final CatalogCache catalogCache = CatalogCache.newCache(catalogClient, serviceName, 30); + catalogCache.addListener(new ConsulCache.Listener() { + @Override + public void notify(Map newValues) { + // do Something with updated server map + System.out.println(serviceName + "--new node notify--"); + LOGGER.info(serviceName + "--new node notify--"); + + if (newValues.isEmpty()) { + System.out.println(serviceName + "-- nodeList is Empty--"); + LOGGER.info(serviceName + "--nodeList is Empty-stop service[" + serviceName + + "] listen-"); + try { + catalogCache.stop(); + } catch (Exception e) { + LOGGER.equals(serviceName + "-- stop Node error:" + e.getMessage()); + } + + } else { + + MicroServiceInfo microServiceInfo = new MicroServiceInfo(); + HashSet nodes = new HashSet(); + String url = ""; + String version = "", visualRange = "", protocol = ""; + + for (Map.Entry entry : newValues.entrySet()) { + String nodeName = entry.getKey().toString(); + CatalogService value = (CatalogService) entry.getValue(); + + Node node = new Node(); + node.setIp(value.getServiceAddress()); + node.setPort(String.valueOf(value.getServicePort())); + + + try { + List tagList = value.getServiceTags(); + for (String tag : tagList) { + if (tag.startsWith("url")) { + if (tag.split(":").length == 2) { + url = tag.split(":")[1]; + } else { + url = ""; + } + + + continue; + } + if (tag.startsWith("version")) { + if (tag.split(":").length == 2) { + version = tag.split(":")[1]; + } else { + version = ""; + } + continue; + } + if (tag.startsWith("protocol")) { + protocol = tag.split(":")[1]; + continue; + } + if (tag.startsWith("visualRange")) { + visualRange = tag.split(":")[1]; + continue; + } + if (tag.startsWith("ttl")) { + int ttl = Integer.parseInt(tag.split(":")[1]); + node.setTtl(ttl); + continue; + } + } + + + } catch (Exception e) { + LOGGER.error(serviceName + " read tag throw exception", e); + System.out.println(serviceName + " read tag throw exception"); + } + + nodes.add(node); + + + System.out.println(nodeName + ":" + value.getServiceAddress() + " " + + value.getServicePort() + " " + value.getServiceTags()); + } + + microServiceInfo.setNodes(nodes); + microServiceInfo.setProtocol(protocol); + microServiceInfo.setUrl(url); + microServiceInfo.setServiceName(serviceName); + if (!visualRange.isEmpty()) { + microServiceInfo.setVisualRange(visualRange); + } + microServiceInfo.setVersion(version); + + try { + MicroServiceFullInfo microServiceFullInfo = + MicroServiceWrapper.getInstance().saveMicroServiceInstance( + microServiceInfo, false, "", ""); + LOGGER.info("register MicroServiceInfo successs:" + microServiceFullInfo); + System.out.println("register MicroServiceInfo successs:" + serviceName); + } catch (Exception e) { + LOGGER.error("register MicroServiceInfo FAIL : ", e); + + } + } + } + }); + try { + System.out.println(serviceName + " Node Listen start"); + LOGGER.info(serviceName + " Node Listen start"); + catalogCache.start(); + + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error(serviceName + " Node Listen start throw exception", e); + } + + return catalogCache; + } + + + /** + * @Title getDiffrent + * @Description TODO(Extract the list1 and list2 different data sets) + * @param list1 + * @param list2 + * @return + * @return List + */ + private List getDiffrent(List list1, List list2) { + + List diff = new ArrayList(); + + + + for (ServiceInfo serviceInfo : list1) { + if (!list2.contains(serviceInfo)) { + diff.add(serviceInfo); + } + } + + return diff; + } + + public static void main(String[] args) { + ConsulClientApp consulTest = new ConsulClientApp("127.0.0.1", 10081); + consulTest.startServiceListen(); + + + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java new file mode 100644 index 0000000..54f3f34 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java @@ -0,0 +1,136 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + + +public class ApiRouteInfo implements Serializable{ + private static final long serialVersionUID = 1L; + @ApiModelProperty(required = true) + private String serviceName; + + @ApiModelProperty(example = "v1", required = true) + private String version; + + @ApiModelProperty(value = "Target Service URL,start with /",example = "/test", required = true) + private String url; + + private String apiJson=""; //swagger json Path + + @ApiModelProperty(value = "[apiJson Type] 0:local file 1: remote file", allowableValues = "0,1", example = "1") + private String apiJsonType="1"; + private String metricsUrl=""; + + @ApiModelProperty(value = "[control Range] 0:default 1:readonly 2:hidden ", allowableValues = "0,1,2", example = "0") + private String control="0"; + + @ApiModelProperty(value = "[status] 1:abled 0:disabled ", allowableValues = "0,1", example = "1") + private String status="1"; + + @ApiModelProperty(value = "[visual Range]interSystem:0,inSystem:1", allowableValues = "0,1", example = "1") + private String visualRange = "1"; + + @ApiModelProperty(value = "[LB Policy]non_ip_hash:0,ip_hash:1", allowableValues = "0,1", example = "0") + private String useOwnUpstream="0"; //负载均衡策略 + + @ApiModelProperty(required = true) + private RouteServer servers[]; + + + + public String getServiceName() { + return serviceName; + } + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + + public String getApiJson() { + return apiJson; + } + public void setApiJson(String apiJson) { + this.apiJson = apiJson; + } + + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public RouteServer[] getServers() { + return servers; + } + public void setServers(RouteServer[] servers) { + this.servers = servers; + } + + + public String getApiJsonType() { + return apiJsonType; + } + public void setApiJsonType(String apiJsonType) { + this.apiJsonType = apiJsonType; + } + public String getMetricsUrl() { + return metricsUrl; + } + public void setMetricsUrl(String metricsUrl) { + this.metricsUrl = metricsUrl; + } + public String getControl() { + return control; + } + public void setControl(String control) { + this.control = control; + } + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + public String getVisualRange() { + return visualRange; + } + public void setVisualRange(String visualRange) { + this.visualRange = visualRange; + } + public String getUseOwnUpstream() { + return useOwnUpstream; + } + + public void setUseOwnUpstream(String useOwnUpstream) { + this.useOwnUpstream = useOwnUpstream; + } + + + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java new file mode 100644 index 0000000..12c0dcb --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java @@ -0,0 +1,38 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.Serializable; + +public class ConsulInfo implements Serializable{ + private static final long serialVersionUID = 1L; + private String ip; + private int port; + + public String getIp() { + return ip; + } + public void setIp(String ip) { + this.ip = ip; + } + public int getPort() { + return port; + } + public void setPort(int port) { + this.port = port; + } + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java new file mode 100644 index 0000000..f99dcad --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java @@ -0,0 +1,39 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class CustomDateSerializer extends JsonSerializer { + + @Override + public void serialize(Date value, + JsonGenerator jsonGenerator, + SerializerProvider provider) + throws IOException, JsonProcessingException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + jsonGenerator.writeString(sdf.format(value)); + } + + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java new file mode 100644 index 0000000..2b84a38 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java @@ -0,0 +1,102 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +public class CustomRouteInfo implements Serializable{ + + private static final long serialVersionUID = 1L; + @ApiModelProperty(required = true) + private String serviceName; + + @ApiModelProperty(value = "Target Service URL,start with /",example = "/test", required = true) + private String url; + + @ApiModelProperty(value = "[control Range] 0:default 1:readonly 2:hidden ", allowableValues = "0,1,2", example = "0") + private String control="0"; + + @ApiModelProperty(value = "[status] 1:abled 0:disabled ", allowableValues = "0,1", example = "1") + private String status="1"; + + @ApiModelProperty(value = "[visual Range]interSystem:0,inSystem:1", allowableValues = "0,1", example = "1") + private String visualRange = "1"; + + @ApiModelProperty(value = "[LB Policy]non_ip_hash:0,ip_hash:1", allowableValues = "0,1", example = "0") + private String useOwnUpstream="0"; //负载均衡策略 + + @ApiModelProperty(required = true) + private RouteServer servers[]; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public RouteServer[] getServers() { + return servers; + } + + public void setServers(RouteServer[] servers) { + this.servers = servers; + } + + public String getControl() { + return control; + } + + public void setControl(String control) { + this.control = control; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getVisualRange() { + return visualRange; + } + + public void setVisualRange(String visualRange) { + this.visualRange = visualRange; + } + + public String getUseOwnUpstream() { + return useOwnUpstream; + } + + public void setUseOwnUpstream(String useOwnUpstream) { + this.useOwnUpstream = useOwnUpstream; + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java new file mode 100644 index 0000000..122dbc4 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java @@ -0,0 +1,49 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.Serializable; + +public class DiscoverInfo implements Serializable{ + private static final long serialVersionUID = 1L; + private String ip; + private int port; + private boolean enabled; + + + public String getIp() { + return ip; + } + public void setIp(String ip) { + this.ip = ip; + } + public int getPort() { + return port; + } + public void setPort(int port) { + this.port = port; + } + public boolean isEnabled() { + return enabled; + } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java new file mode 100644 index 0000000..0087fdf --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java @@ -0,0 +1,102 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + + +public class IuiRouteInfo implements Serializable{ + private static final long serialVersionUID = 1L; + @ApiModelProperty(required = true) + private String serviceName; + + @ApiModelProperty(value = "Target Service URL,start with /",example = "/test", required = true) + private String url; + + @ApiModelProperty(value = "[control Range] 0:default 1:readonly 2:hidden ", allowableValues = "0,1,2", example = "0") + private String control="0"; + + @ApiModelProperty(value = "[status] 1:abled 0:disabled ", allowableValues = "0,1", example = "1") + private String status="1"; + + @ApiModelProperty(value = "[visual Range]interSystem:0,inSystem:1", allowableValues = "0,1", example = "1") + private String visualRange = "1"; + + @ApiModelProperty(value = "[LB Policy]non_ip_hash:0,ip_hash:1", allowableValues = "0,1", example = "0") + private String useOwnUpstream="0"; //负载均衡策略 + + @ApiModelProperty(required = true) + private RouteServer servers[]; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public RouteServer[] getServers() { + return servers; + } + + public void setServers(RouteServer[] servers) { + this.servers = servers; + } + + public String getControl() { + return control; + } + + public void setControl(String control) { + this.control = control; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getVisualRange() { + return visualRange; + } + + public void setVisualRange(String visualRange) { + this.visualRange = visualRange; + } + + public String getUseOwnUpstream() { + return useOwnUpstream; + } + + public void setUseOwnUpstream(String useOwnUpstream) { + this.useOwnUpstream = useOwnUpstream; + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java new file mode 100644 index 0000000..324b582 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java @@ -0,0 +1,191 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import com.fasterxml.jackson.annotation.JsonProperty; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MetricsInfo{ + private Gauges gauges; + private Timers timers; +} + +@Data +@NoArgsConstructor +@AllArgsConstructor +class Gauges { + + @JsonProperty("jvm.attribute.uptime") + private JVMMetrics jvm_attribute_uptime; + + @JsonProperty("jvm.memory.pools.Eden-Space.usage") + private JVMMetrics jvm_memory_pools_Eden_Space_usage; + + @JsonProperty("jvm.memory.pools.PS-Eden-Space.usage") + private JVMMetrics jvm_memory_pools_PS_Eden_Space_usage; + + @JsonProperty("jvm.memory.pools.Perm-Gen.usage") + private JVMMetrics jvm_memory_pools_Perm_Gen_usage; + + @JsonProperty("jvm.memory.pools.PS-Perm-Gen.usage") + private JVMMetrics jvm_memory_pools_PS_Perm_Gen_usage; + + @JsonProperty("jvm.memory.pools.Survivor-Space.usage") + private JVMMetrics jvm_memory_pools_Survivor_Space_usage; + + @JsonProperty("jvm.memory.pools.PS-Survivor-Space.usage") + private JVMMetrics jvm_memory_pools_PS_Survivor_Space_usage; + + @JsonProperty("jvm.memory.pools.Tenured-Gen.usage") + private JVMMetrics jvm_memory_pools_Tenured_Gen_usage; + + @JsonProperty("jvm.memory.pools.PS-Old-Gen.usage") + private JVMMetrics jvm_memory_pools_PS_Old_Gen_usage; + + @JsonProperty("jvm.memory.pools.Code-Cache.usage") + private JVMMetrics jvm_memory_pools_Code_Cache_usage; + + @JsonProperty("jvm.memory.heap.init") + private JVMMetrics jvm_memory_heap_init; + + @JsonProperty("jvm.memory.non-heap.init") + private JVMMetrics jvm_memory_non_heap_init; + + @JsonProperty("jvm.memory.heap.used") + private JVMMetrics jvm_memory_heap_used; + + @JsonProperty("jvm.memory.non-heap.used") + private JVMMetrics jvm_memory_non_heap_used; + + @JsonProperty("jvm.memory.heap.max") + private JVMMetrics jvm_memory_heap_max; + + @JsonProperty("jvm.threads.runnable.count") + private JVMMetrics jvm_threads_runnable_count; + + @JsonProperty("jvm.threads.timed_waiting.count") + private JVMMetrics jvm_threads_timed_waiting_count; + + @JsonProperty("jvm.threads.waiting.count") + private JVMMetrics jvm_threads_waiting_count; + + @JsonProperty("jvm.threads.blocked.count") + private JVMMetrics jvm_threads_blocked_count; + + @JsonProperty("jvm.threads.count") + private JVMMetrics jvm_threads_count; + + + +} + +@Data +@NoArgsConstructor +@AllArgsConstructor +class Timers{ + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.addApiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_addApiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.deleteApiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_deleteApiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiDocs") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiDocs; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiRoutes") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiRoutes; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getServerIP") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getServerIP; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.updateApiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_updateApiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.addIuiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_addIuiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.deleteIuiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_deleteIuiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.getIuiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_getIuiRoute; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.getIuiRoutes") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_getIuiRoutes; + + @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.updateIuiRoute") + private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_updateIuiRoute; + + @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.get-requests") + private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_get_requests; + + @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.post-requests") + private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_post_requests; + + @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.put-requests") + private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_put_requests; + + @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.delete-requests") + private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_delete_requests; + + @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.other-requests") + private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_other_requests; + +} + +@Data +@NoArgsConstructor +@AllArgsConstructor +class JVMMetrics{ + private double value; +} + +@Data +@NoArgsConstructor +@AllArgsConstructor +class HttpMetrics{ + private int count; + private double max; + private double mean; + private double min; + private double p50; + private double p75; + private double p95; + private double p98; + private double p99; + private double p999; + private double stddev; + private double m15_rate; + private double m1_rate; + private double m5_rate; + private double mean_rate; + private String duration_units; + private String rate_units; +} + + diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java new file mode 100644 index 0000000..ccf1977 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java @@ -0,0 +1,44 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.Serializable; +import java.util.Set; + +public class MicroServiceFullInfo extends Service implements Serializable { + private static final long serialVersionUID = 1L; + + private Set nodes; + + private String status = "1"; //0:disable 1:enable + + public Set getNodes() { + return nodes; + } + + public void setNodes(Set nodes) { + this.nodes = nodes; + } + + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java new file mode 100644 index 0000000..e6e1b73 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java @@ -0,0 +1,38 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.Serializable; +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class MicroServiceInfo extends Service implements Serializable { + private static final long serialVersionUID = 1L; + + private Set nodes; + + public Set getNodes() { + return nodes; + } + + public void setNodes(Set nodes) { + this.nodes = nodes; + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java new file mode 100644 index 0000000..f0d179f --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java @@ -0,0 +1,75 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class Node implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(required = true) + private String ip; + + @ApiModelProperty(required = true) + private String port; + + private int ttl=-1; + + + + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public int getTtl() { + return ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + public Node(){ + + } + + public Node(String ip,String port,int ttl){ + this.ip = ip; + this.port = port; + this.ttl = ttl; + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java new file mode 100644 index 0000000..9988e1d --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java @@ -0,0 +1,74 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class NodeInfo extends Node { + + private static final long serialVersionUID = 8955786461351557306L; + + private String nodeId; + + + + @JsonSerialize(using = CustomDateSerializer.class) + private Date expiration; + + @JsonSerialize(using = CustomDateSerializer.class) + private Date created_at; + + @JsonSerialize(using = CustomDateSerializer.class) + private Date updated_at; + + public Date getExpiration() { + return expiration; + } + + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + public Date getCreated_at() { + return created_at; + } + + public void setCreated_at(Date created_at) { + this.created_at = created_at; + } + + public Date getUpdated_at() { + return updated_at; + } + + public void setUpdated_at(Date updated_at) { + this.updated_at = updated_at; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java new file mode 100644 index 0000000..3e01c4f --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java @@ -0,0 +1,68 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + + +public class RouteServer implements Serializable{ + private static final long serialVersionUID = 1L; + @ApiModelProperty(required = true) + private String ip; + + @ApiModelProperty(required = true) + private String port; + private int weight=0; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public RouteServer(){ + + } + + public RouteServer(String ip,String port){ + this.ip=ip; + this.port=port; + this.weight=0; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java new file mode 100644 index 0000000..51f0e86 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java @@ -0,0 +1,104 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Service implements Serializable { + private static final long serialVersionUID = 1L; + // 服务名 + @ApiModelProperty(required = true) + private String serviceName; + // 版本号 + @ApiModelProperty(example = "v1") + private String version=""; + // 服务url + @ApiModelProperty(value = "Target Service URL,start with /",example = "/api/serviceName/v1", required = true) + private String url=""; + // 服务对应协议,比如REST、UI、MQ、FTP、SNMP、TCP、UDP + @ApiModelProperty(value = "Service Protocol", allowableValues = "REST,UI, MQ, FTP,SNMP,TCP,UDP", example = "REST",required = true) + private String protocol = ""; + + //服务的可见范围 系统间:0 系统内:1 + @ApiModelProperty(value = "[visual Range]interSystem:0,inSystem:1", allowableValues = "0,1", example = "1") + private String visualRange = "1"; + + //负载均衡策略类型 + @ApiModelProperty(value = "lb policy", allowableValues = "round-robin,hash,least_conn", example = "hash") + private String lb_policy=""; + + @ApiModelProperty(required = true) + private Set nodes; + + public Set getNodes() { + return nodes; + } + + public void setNodes(Set nodes) { + this.nodes = nodes; + } + + public String getServiceName() { + return serviceName; + } + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public String getProtocol() { + return protocol; + } + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getVisualRange() { + return visualRange; + } + + public void setVisualRange(String visualRange) { + this.visualRange = visualRange; + } + + + public String getLb_policy() { + return lb_policy; + } + + public void setLb_policy(String lb_policy) { + this.lb_policy = lb_policy; + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java new file mode 100644 index 0000000..34c4a67 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java @@ -0,0 +1,88 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonInclude; + +public class ServiceAccessInfo implements Serializable { + private static final long serialVersionUID = 1L; + // (api|iui|custom|p2p) + private String serviceType; + + private String serviceName; + @JsonInclude(JsonInclude.Include.NON_NULL) + private String version; + + private String accessAddr; + + /** + * @return the serviceType + */ + public String getServiceType() { + return serviceType; + } + + /** + * @param serviceType the serviceType to set + */ + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + /** + * @return the serviceName + */ + public String getServiceName() { + return serviceName; + } + + /** + * @param serviceName the serviceName to set + */ + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + /** + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * @param version the version to set + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * @return the accessAddr + */ + public String getAccessAddr() { + return accessAddr; + } + + /** + * @param accessAddr the accessAddr to set + */ + public void setAccessAddr(String accessAddr) { + this.accessAddr = accessAddr; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java new file mode 100644 index 0000000..ce57dc6 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java @@ -0,0 +1,28 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api.exception; + +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class ExtendedInternalServerErrorException extends InternalServerErrorException { + + public ExtendedInternalServerErrorException(final String message) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(message).type(MediaType.TEXT_PLAIN).build()); + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java new file mode 100644 index 0000000..ca5f747 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java @@ -0,0 +1,28 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api.exception; + +import javax.ws.rs.NotFoundException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class ExtendedNotFoundException extends NotFoundException { + + public ExtendedNotFoundException(final String message) { + super(Response.status(Response.Status.NOT_FOUND).entity(message).type(MediaType.TEXT_PLAIN).build()); + } +} + diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java new file mode 100644 index 0000000..84bfbaa --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java @@ -0,0 +1,27 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.api.exception; + +import javax.ws.rs.NotSupportedException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class ExtendedNotSupportedException extends NotSupportedException { + + public ExtendedNotSupportedException(final String message) { + super(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).entity(message).type(MediaType.TEXT_PLAIN).build()); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java new file mode 100644 index 0000000..dc2af2a --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java @@ -0,0 +1,35 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.health; + +import com.codahale.metrics.health.HealthCheck; + +public class ApiRouteHealthCheck extends HealthCheck { + private final String template; + + public ApiRouteHealthCheck(String template) { + this.template = template; + } + + @Override + protected Result check() throws Exception { + final String saying = String.format(template, "TEST"); + if (!saying.contains("TEST")) { + return Result.unhealthy("template doesn't include a name"); + } + return Result.healthy(); + } +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java new file mode 100644 index 0000000..cd86047 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java @@ -0,0 +1,233 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.net.URI; + +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.UriInfo; + +import org.apache.http.HttpStatus; +import org.openo.msb.api.ApiRouteInfo; +import org.openo.msb.api.DiscoverInfo; +import org.openo.msb.wrapper.ApiRouteServiceWrapper; +import org.openo.msb.wrapper.CustomRouteServiceWrapper; +import org.openo.msb.wrapper.IuiRouteServiceWrapper; +import org.openo.msb.wrapper.util.JacksonJsonUtil; +import org.openo.msb.wrapper.util.RouteUtil; + +import com.codahale.metrics.annotation.Timed; + +@Path("/apiRoute") +@Api(tags = { "ApiRoute" }) +@Produces(MediaType.APPLICATION_JSON) +public class ApiRouteResource { + + @Context + UriInfo uriInfo; // actual uri info + + @GET + @Path("/") + @ApiOperation(value = "get all ApiRoute ", code = HttpStatus.SC_OK,response = ApiRouteInfo.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get ApiRouteInfo List fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public ApiRouteInfo[] getApiRoutes() { + return ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(); + } + + @POST + @Path("/") + @ApiOperation(value = "add one ApiRoute ", code = HttpStatus.SC_CREATED,response = ApiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add ApiRouteInfo fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable ApiRouteInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response addApiRoute( + @ApiParam(value = "ApiRoute Instance Info", required = true) ApiRouteInfo apiRouteInfo) { + ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfo,""); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + new_apiRouteInfo.getServiceName()+"/version/"+new_apiRouteInfo.getVersion()).build(); + return Response.created(returnURI).entity(new_apiRouteInfo).build(); + + } + + @GET + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "get one ApiRoute ",code = HttpStatus.SC_OK, response = ApiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "ApiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get ApiRouteInfo fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public ApiRouteInfo getApiRoute( + @ApiParam(value = "ApiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "ApiRoute version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version) { + + return ApiRouteServiceWrapper.getInstance().getApiRouteInstance(serviceName,version); + + } + + @PUT + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "update one ApiRoute by serviceName and version", code = HttpStatus.SC_CREATED,response = ApiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update ApiRouteInfo fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable ApiRouteInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateApiRoute( + @ApiParam(value = "ApiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "ApiRoute version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "ApiRoute Instance Info", required = true) ApiRouteInfo apiRouteInfo) { + + ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().updateApiRouteInstance(serviceName,version,apiRouteInfo,""); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + new_apiRouteInfo.getServiceName()+"/version/"+new_apiRouteInfo.getVersion()).build(); + return Response.created(returnURI).entity(new_apiRouteInfo).build(); + + } + + + + @DELETE + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "delete one ApiRoute by serviceName and version", code = HttpStatus.SC_NO_CONTENT) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete ApiRouteInfo succeed "), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "ApiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete ApiRouteInfo fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public void deleteApiRoute( + @ApiParam(value = "ApiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "ApiRoute version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version) { + + + ApiRouteServiceWrapper.getInstance().deleteApiRoute(serviceName, version,"*",""); + + } + + + @GET + @Path("/apiDocs") + @ApiOperation(value = "get all Local apiDoc ", code = HttpStatus.SC_OK, response = String.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get apiDoc List fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public String[] getApiDocs() { + + String[] apiDocs = ApiRouteServiceWrapper.getInstance().getAllApiDocs(); + return apiDocs; + + } + + @GET + @Path("/apiGatewayPort") + @ApiOperation(value = "get apiGateway Port ", code = HttpStatus.SC_OK, response = String.class) + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get apiGateway Port fail", response = String.class)}) + @Produces(MediaType.TEXT_PLAIN) + @Timed + public String getApiGatewayPort() { + + return ApiRouteServiceWrapper.getInstance().getApiGatewayPort(); + + } + + @GET + @Path("/discoverInfo") + @ApiOperation(value = "get discover Info ", code = HttpStatus.SC_OK,response = DiscoverInfo.class) + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get discover Info fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public DiscoverInfo getServiceDiscoverInfo() { + + return ApiRouteServiceWrapper.getInstance().getServiceDiscoverInfo(); + } + + @PUT + @Path("/{serviceName}/version/{version}/status/{status}") + @ApiOperation(value = "update one ApiRoute status by serviceName and version", code = HttpStatus.SC_CREATED,response = ApiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "ApiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update status fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateApiRouteStatus( + @ApiParam(value = "ApiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "ApiRoute version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "ApiRoute status,1:abled 0:disabled", required = true) @PathParam("status") String status) { + + ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName,version,status); + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_apiRouteInfo).build(); + + } + + @GET + @Path("/export") + @ApiOperation(value = "export all route service Info by json-file", code = HttpStatus.SC_OK,response = String.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "export fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_ACCEPTABLE, message = " not Acceptable client-side", response = String.class)}) + @Produces(MediaType.TEXT_PLAIN) + public Response exportService() throws Exception { + + + Object[] apirouteArray= ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(); + Object[] iuirouteArray= IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(); + Object[] customrouteArray= CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(); + + Object[] temprouteArray =RouteUtil.concat(apirouteArray, iuirouteArray); + Object[] allrouteArray=RouteUtil.concat(temprouteArray, customrouteArray); + + + String allrouteJson=JacksonJsonUtil.beanToJson(allrouteArray); + + ResponseBuilder response = Response.ok(allrouteJson); + response.header("Content-Disposition", + "attachment; filename=\"RouteService.json\""); + return response.build(); + + + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java new file mode 100644 index 0000000..89cdf5f --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java @@ -0,0 +1,152 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.net.URI; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.http.HttpStatus; +import org.openo.msb.api.CustomRouteInfo; +import org.openo.msb.wrapper.CustomRouteServiceWrapper; + +import com.codahale.metrics.annotation.Timed; + +@Path("/customRoute") +@Api(tags = { "CustomRoute" }) +@Produces(MediaType.APPLICATION_JSON) +public class CustomRouteResource { + + @Context + UriInfo uriInfo; // actual uri info + + @GET + @Path("/all") + @ApiOperation(value = "get all CustomRoute ", code = HttpStatus.SC_OK,response = CustomRouteInfo.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get CustomRouteInfo List fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public CustomRouteInfo[] getCustomRoutes() { + return CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(); + } + + @POST + @Path("/instance") + @ApiOperation(value = "add one CustomRoute ", code = HttpStatus.SC_CREATED,response = CustomRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add CustomRouteInfo fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable CustomRouteInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response addCustomRoute( + @ApiParam(value = "CustomRoute Instance Info", required = true) CustomRouteInfo customRouteInfo) { + CustomRouteInfo new_customRouteInfo = CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfo,""); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/instance?serviceName=" + new_customRouteInfo.getServiceName()).build(); + return Response.created(returnURI).entity(new_customRouteInfo).build(); + + } + + @GET + @Path("/instance") + @ApiOperation(value = "get one CustomRoute ",code = HttpStatus.SC_OK, response = CustomRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "CustomRoute not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRoute Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get CustomRoute fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public CustomRouteInfo getCustomRoute( + @ApiParam(value = "CustomRoute serviceName", required = false) @QueryParam("serviceName") String serviceName) { + + + return CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(serviceName); + + } + + @PUT + @Path("/instance") + @ApiOperation(value = "update one CustomRoute by serviceName", code = HttpStatus.SC_CREATED,response = CustomRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRoute Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update CustomRoute fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable CustomRoute JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateCustomRoute( + @ApiParam(value = "CustomRoute serviceName", required = true) @QueryParam("serviceName") String serviceName, + @ApiParam(value = "CustomRoute Instance Info", required = true) CustomRouteInfo customRoute) { + + CustomRouteInfo new_customRouteInfo= CustomRouteServiceWrapper.getInstance().updateCustomRouteInstance(serviceName,customRoute,""); + + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_customRouteInfo).build(); + + } + + @DELETE + @Path("/instance") + @ApiOperation(value = "delete one CustomRoute by serviceName", code = HttpStatus.SC_NO_CONTENT) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete customRoute succeed "), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "customRoute not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete customRoute fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public void deleteCustomRoute( + @ApiParam(value = "CustomRoute serviceName", required = true) @QueryParam("serviceName") String serviceName) { + + CustomRouteServiceWrapper.getInstance().deleteCustomRoute(serviceName,"*",""); + + } + + @PUT + @Path("/status") + @ApiOperation(value = "update one CustomRoute status by serviceName ",code = HttpStatus.SC_CREATED, response = CustomRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable customRoute Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "customRoute not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update status fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateCustomRouteStatus( + @ApiParam(value = "CustomRoute serviceName", required = true) @QueryParam("serviceName") String serviceName, + @ApiParam(value = "CustomRoute status,1:abled 0:disabled", required = true) @QueryParam("status") String status) { + + CustomRouteInfo new_customRouteInfo = CustomRouteServiceWrapper.getInstance().updateCustomRouteStatus(serviceName,status); + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_customRouteInfo).build(); + + + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java new file mode 100644 index 0000000..b852fa9 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java @@ -0,0 +1,155 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.net.URI; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.http.HttpStatus; +import org.openo.msb.api.IuiRouteInfo; +import org.openo.msb.wrapper.IuiRouteServiceWrapper; + +import com.codahale.metrics.annotation.Timed; + +@Path("/iuiRoute") +@Api(tags = { "iuiRoute" }) +@Produces(MediaType.APPLICATION_JSON) +public class IuiRouteResource { + + @Context + UriInfo uriInfo; // actual uri info + + @GET + @Path("/") + @ApiOperation(value = "get all iuiRoute ", code = HttpStatus.SC_OK,response = IuiRouteInfo.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get iuiRouteInfo List fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public IuiRouteInfo[] getIuiRoutes() { + return IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(); + } + + @POST + @Path("/") + @ApiOperation(value = "add one iuiRoute ", code = HttpStatus.SC_CREATED,response = IuiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable iuiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add iuiRouteInfo fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable iuiRouteInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response addIuiRoute( + @ApiParam(value = "iuiRoute Instance Info", required = true) IuiRouteInfo iuiRouteInfo) { + IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + new_iuiRouteInfo.getServiceName()).build(); + return Response.created(returnURI).entity(new_iuiRouteInfo).build(); + + } + + @GET + @Path("/{serviceName}") + @ApiOperation(value = "get one iuiRoute ",code = HttpStatus.SC_OK, response = IuiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "IuiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get IuiRouteInfo fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public IuiRouteInfo getIuiRoute( + @ApiParam(value = "iuiRoute serviceName", required = true) @PathParam("serviceName") String serviceName) { + + return IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(serviceName); + + } + + @PUT + @Path("/{serviceName}") + @ApiOperation(value = "update one iuiRoute by serviceName", code = HttpStatus.SC_CREATED,response = IuiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update IuiRouteInfo fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable IuiRouteInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateIuiRoute( + @ApiParam(value = "iuiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "iuiRoute Instance Info", required = true) IuiRouteInfo iuiRouteInfo) { + + IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().updateIuiRouteInstance(serviceName,iuiRouteInfo); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + serviceName).build(); + return Response.created(returnURI).entity(new_iuiRouteInfo).build(); + } + + @DELETE + @Path("/{serviceName}") + @ApiOperation(value = "delete one iuiRoute by serviceName", code = HttpStatus.SC_NO_CONTENT) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete IuiRouteInfo succeed "), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "IuiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete IuiRouteInfo fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public void deleteIuiRoute( + @ApiParam(value = "iuiRoute serviceName", required = true) @PathParam("serviceName") String serviceName) { + + IuiRouteServiceWrapper.getInstance().deleteIuiRoute(serviceName,"*"); + + } + + @PUT + @Path("/{serviceName}/status/{status}") + @ApiOperation(value = "update one iuiRoute status by serviceName ",code = HttpStatus.SC_CREATED, response = IuiRouteInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "IuiRouteInfo not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update IuiRouteInfo status fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateIuiRouteStatus( + @ApiParam(value = "iuiRoute serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "iuiRoute status,1:abled 0:disabled", required = true) @PathParam("status") String status) { + + IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().updateIuiRouteStatus(serviceName,status); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + serviceName).build(); + return Response.created(returnURI).entity(new_iuiRouteInfo).build(); + + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java new file mode 100644 index 0000000..d15799b --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java @@ -0,0 +1,49 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.http.impl.client.CloseableHttpClient; +import org.openo.msb.api.MetricsInfo; +import org.openo.msb.wrapper.MetricsServiceWrapper; + +import com.codahale.metrics.annotation.Timed; + +@Path("/metrics") +@Api(tags = { "metrics" }) +@Produces(MediaType.APPLICATION_JSON) +public class MetricsResource { + + + @GET + @Path("/") + @ApiOperation(value = "get Metrics Info ", response = MetricsInfo.class) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public MetricsInfo getMetricsInfo() { + return MetricsServiceWrapper.getMetricsInfo(); + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java new file mode 100644 index 0000000..5ea80ae --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java @@ -0,0 +1,247 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.net.URI; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.openo.msb.api.MicroServiceFullInfo; +import org.openo.msb.api.MicroServiceInfo; +import org.openo.msb.wrapper.MicroServiceWrapper; +import org.openo.msb.wrapper.util.MicroServiceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.codahale.metrics.annotation.Timed; + +@Path("/services") +@Api(tags = {"MSB-Service Resource"}) +@Produces(MediaType.APPLICATION_JSON) +public class MicroServiceResource { + + @Context + UriInfo uriInfo; // actual uri info + + + private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class); + + @GET + @Path("/") + @ApiOperation(value = "get all microservices ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice List fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public MicroServiceFullInfo[] getMicroService() { + return MicroServiceWrapper.getInstance().getAllMicroServiceInstances(); + } + + @POST + @Path("/") + @ApiOperation(value = "add one microservice ", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add microservice fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response addMicroService( + @ApiParam(value = "MicroServiceInfo Instance Info", required = true) MicroServiceInfo microServiceInfo, + @Context HttpServletRequest request, + @ApiParam(value = "createOrUpdate", required = false) @QueryParam("createOrUpdate") @DefaultValue("true") boolean createOrUpdate, + @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port) { + + String ip=MicroServiceUtil.getRealIp(request); + + MicroServiceFullInfo microServiceFullInfo = + MicroServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo, + createOrUpdate,ip,port); + URI returnURI = + uriInfo.getAbsolutePathBuilder() + .path("/" + microServiceInfo.getServiceName() + "/version/" + + microServiceInfo.getVersion()).build(); + return Response.created(returnURI).entity(microServiceFullInfo).build(); + } + + + + @GET + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "get one microservice ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public MicroServiceFullInfo getMicroService( + @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port) { + + + return MicroServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version,port); + + + } + + @PUT + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "update one microservice by serviceName and version", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update microservice fail", response = String.class), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateMicroService( + @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "microservice Instance Info", required = true) MicroServiceInfo microServiceInfo) { + + MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().updateMicroServiceInstance(serviceName, version, + microServiceInfo); + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build(); + + } + + @PUT + @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}") + @ApiOperation(value = "update single node by serviceName and version and node", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update node fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateNode( + @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "ip") @PathParam("ip") String ip, + @ApiParam(value = "port") @PathParam("port") String port, + @ApiParam(value = "ttl") @QueryParam("ttl") int ttl) { + + MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().updateMicroServiceNode(serviceName, version, ip,port, ttl); + + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build(); + + } + + + + @DELETE + @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}") + @ApiOperation(value = "delete single node by serviceName and version and node", code = HttpStatus.SC_NO_CONTENT) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete node succeed "), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "node not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete node fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public void deleteNode( + @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "ip") @PathParam("ip") String ip, + @ApiParam(value = "port") @PathParam("port") String port) { + + MicroServiceWrapper.getInstance().deleteMicroServiceInstance(serviceName, version, ip,port); + + } + + + @DELETE + @Path("/{serviceName}/version/{version}") + @ApiOperation(value = "delete one full microservice by serviceName and version", code = HttpStatus.SC_NO_CONTENT) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete microservice succeed "), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete microservice fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public void deleteMicroService( + @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port) { + + + MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version,port); + + } + + @PUT + @Path("/{serviceName}/version/{version}/status/{status}") + @ApiOperation(value = "update microservice status by serviceName and version", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update status fail", response = String.class)}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public Response updateServiceStatus( + @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName, + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version, + @ApiParam(value = "status,1:abled 0:disabled") @PathParam("status") String status) { + + MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().updateMicroServiceStatus(serviceName, version,status); + + return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build(); + + } + +// @PUT +// @Path("/ttl") +// @ApiOperation(value = "test json date iso8601 ", code = 200, response = String.class) +// @Produces(MediaType.APPLICATION_JSON) +// @Timed +// public String testIso8601( +// @ApiParam(value = "microservice Instance Info", required = true) MicroServiceFullInfo microServiceInfo) { +// Set nodes=microServiceInfo.getNodes(); +// String rtn="rtn:"; +// for(NodeInfo node:nodes){ +// Date date=node.getExpiration(); +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); +// String datettl=sdf.format(date); +// rtn+=datettl; +// } +// +// +// return rtn; +// } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java new file mode 100644 index 0000000..6a2d741 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java @@ -0,0 +1,65 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +import java.util.List; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.openo.msb.api.ServiceAccessInfo; +import org.openo.msb.wrapper.ServiceAccessWrapper; + +import com.codahale.metrics.annotation.Timed; + + +@Path("/serviceaccess") +@Api(tags = {"ServiceAccess"}) +@Produces(MediaType.APPLICATION_JSON) +public class ServiceAccessResource { + + @GET + @Path("/{serviceName}") + @ApiOperation(value = "get the msb access address of the service ", response = ServiceAccessInfo.class) + @ApiResponses(value = {@ApiResponse(code = 500, message = "get access address error ")}) + @Produces(MediaType.APPLICATION_JSON) + @Timed + public List getApiRoute( + @ApiParam(value = "serviceName") @PathParam("serviceName") String serviceName, + @ApiParam(value = "service type", allowableValues = "api,iui,custom,p2p") @QueryParam("type") String serviceType, + @ApiParam(value = "version") @QueryParam("version") @DefaultValue("") String version, + @ApiParam(hidden = true) @HeaderParam("Host") String host) { + + host=host.split(":")[0]; + + return ServiceAccessWrapper.getInstance().getApiRouteAccessAddr(serviceType, serviceName, + version, host); + + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java new file mode 100644 index 0000000..6f0ed7d --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java @@ -0,0 +1,653 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.ApiRouteInfo; +import org.openo.msb.api.DiscoverInfo; +import org.openo.msb.api.RouteServer; +import org.openo.msb.api.exception.ExtendedInternalServerErrorException; +import org.openo.msb.api.exception.ExtendedNotFoundException; +import org.openo.msb.api.exception.ExtendedNotSupportedException; +import org.openo.msb.wrapper.util.JedisUtil; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; + + + +/** + * @ClassName: ApiRouteServiceWrapper + * @Description: TODO(ApiRoute服务类) + * @author tanghua10186366 + * @date 2015年9月25日 上午9:44:04 + * + */ +public class ApiRouteServiceWrapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteServiceWrapper.class); + + + private static ApiRouteServiceWrapper instance = new ApiRouteServiceWrapper(); + + private ApiRouteServiceWrapper() {} + + public static ApiRouteServiceWrapper getInstance() { + return instance; + } + + /** + * @Title: getAllApiRouteInstances + * @Description: TODO(获取全部服务列表) + * @param: @return + * @return: ApiRouteInfoBean[] + */ + public ApiRouteInfo[] getAllApiRouteInstances() { + + + Jedis jedis = null; + ApiRouteInfo[] apiRouteList = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取全部服务列表 + String routekey = + RouteUtil + .getPrefixedKey("", RouteUtil.APIROUTE, "*", RouteUtil.ROUTE_PATH_INFO); + Set routeSet = jedis.keys(routekey); + apiRouteList = new ApiRouteInfo[routeSet.size()]; + + int i = 0; + for (String routePath : routeSet) { + String[] routePathArray = routePath.split(":"); + ApiRouteInfo apiRoute = + getApiRouteInstance(routePathArray[3], routePathArray[4], jedis); + apiRouteList[i] = apiRoute; + i++; + } + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return apiRouteList; + } + + + + public static boolean checkRedisConnect() { + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis != null) { + return true; + } + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return false; + } + + /** + * @Title: getApiRouteInstance + * @Description: TODO(通过服务名+版本号获取单个服务对象信息) + * @param: @param serviceName + * @param: @param version + * @param: @return + * @return: ApiRouteInfo + */ + public ApiRouteInfo getApiRouteInstance(String serviceName, String version) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException("version (" + version + + ") is not a valid format"); + } + } + + + ApiRouteInfo apiRouteInfo = null; + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + apiRouteInfo = getApiRouteInstance(serviceName, version, jedis); + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + if (null == apiRouteInfo) { + String errInfo = + "ApiRouteInfo not found: serviceName-" + serviceName + " ,version-" + version; + LOGGER.warn(errInfo); + throw new ExtendedNotFoundException(errInfo); + + } + + return apiRouteInfo; + + } + + public ApiRouteInfo getApiRouteInstance(String serviceName, String version, Jedis jedis) + throws Exception { + if ("null".equals(version)) { + version = ""; + } + + ApiRouteInfo apiRouteInfo = null; + + + // 获取info信息 + String routekey = + RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, + RouteUtil.ROUTE_PATH_INFO); + Map infomap = jedis.hgetAll(routekey); + if (!infomap.isEmpty()) { + apiRouteInfo = new ApiRouteInfo(); + apiRouteInfo.setServiceName(serviceName); + apiRouteInfo.setVersion(version); + apiRouteInfo.setUrl(infomap.get("url")); + apiRouteInfo.setMetricsUrl(infomap.get("metricsUrl")); + apiRouteInfo.setApiJson(infomap.get("apijson")); + apiRouteInfo.setApiJsonType(infomap.get("apiJsonType")); + apiRouteInfo.setControl(infomap.get("control")); + apiRouteInfo.setStatus(infomap.get("status")); + apiRouteInfo.setVisualRange(infomap.get("visualRange")); + apiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); + + + // 获取负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, + RouteUtil.ROUTE_PATH_LOADBALANCE); + Set serviceLBset = jedis.keys(serviceLBkey + ":*"); + int serverNum = serviceLBset.size(); + RouteServer[] apiRouteServerList = new RouteServer[serverNum]; + int i = 0; + for (String serviceInfo : serviceLBset) { + Map serviceLBmap = jedis.hgetAll(serviceInfo); + RouteServer server = new RouteServer(); + server.setIp(serviceLBmap.get("ip")); + server.setPort(serviceLBmap.get("port")); + server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); + apiRouteServerList[i] = server; + i++; + } + + apiRouteInfo.setServers(apiRouteServerList); + + // 获取生命周期信息 + +// ApiRouteLifeCycle lifeCycle = new ApiRouteLifeCycle(); +// String serviceLifekey = +// RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, +// RouteUtil.APIROUTE_PATH_LIFE); +// Map serviceLifeMap = jedis.hgetAll(serviceLifekey); +// +// lifeCycle.setInstallPath(serviceLifeMap.get("path")); +// lifeCycle.setStartScript(serviceLifeMap.get("start")); +// lifeCycle.setStopScript(serviceLifeMap.get("stop")); +// +// apiRouteInfo.setLifeCycle(lifeCycle); + } + + + return apiRouteInfo; + } + + /** + * @Title: updateApiRouteInstance + * @Description: TODO(更新单个服务信息) + * @param: @param serviceName + * @param: @param version + * @param: @param apiRouteInfo + * @param: @return + * @return: ApiRouteInfo + */ + public synchronized ApiRouteInfo updateApiRouteInstance(String serviceName, String version, + ApiRouteInfo apiRouteInfo, String serverPort) { + + if ("null".equals(version)) { + version = ""; + } + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException("version (" + version + + ") is not a valid format"); + } + } + + + + + try { + + + if (serviceName.equals(apiRouteInfo.getServiceName()) + && version.equals(apiRouteInfo.getVersion())) { + // 删除已存在负载均衡服务器信息 + deleteApiRoute(serviceName, version, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", + serverPort); + + } else { + // 如果已修改服务名或者版本号,先删除此服务全部已有信息 + deleteApiRoute(serviceName, version, "*", serverPort); + } + + + saveApiRouteInstance(apiRouteInfo, serverPort); + + + } catch (ExtendedNotSupportedException e) { + throw e; + } catch (Exception e) { + LOGGER.error("update ApiRoute throw exception", e); + throw new ExtendedInternalServerErrorException("update apiRouteInfo throw exception" + + e.getMessage()); + + } + + return apiRouteInfo; + + } + + /** + * @Title updateApiRouteStatus + * @Description TODO(更新单个服务状态) + * @param serviceName + * @param version + * @param status + * @return + * @return RouteResult + */ + public synchronized ApiRouteInfo updateApiRouteStatus(String serviceName, String version, + String status) { + + if ("null".equals(version)) { + version = ""; + } + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException("version (" + version + + ") is not a valid format"); + } + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { + throw new ExtendedNotSupportedException( + "save ApiRouteInfo Status FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + ApiRouteInfo new_apiRouteInfo = getApiRouteInstance(serviceName, version); + + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, + RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("status", status); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new Exception("fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + new_apiRouteInfo.setStatus(status); + + + } catch (Exception e) { + LOGGER.error("update ApiRoute status throw exception", e); + throw new ExtendedInternalServerErrorException("update ApiRoute status throw exception" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return new_apiRouteInfo; + } + + + /** + * @Title: saveApiRouteInstance + * @Description: TODO(存储单个服务信息) + * @param: @param apiRouteInfo + * @param: @return + * @return: ApiRouteInfo + */ + public synchronized ApiRouteInfo saveApiRouteInstance(ApiRouteInfo apiRouteInfo, + String serverPort) { + + + + if (StringUtils.isBlank(apiRouteInfo.getServiceName()) + || apiRouteInfo.getServers().length == 0) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL: Some required fields are empty"); + } + + if (StringUtils.isNotBlank(apiRouteInfo.getVersion())) { + if (!RegExpTestUtil.versionRegExpTest(apiRouteInfo.getVersion())) { + throw new ExtendedNotSupportedException("version (" + apiRouteInfo.getVersion() + + ") is not a valid format"); + } + } + + if (StringUtils.isNotBlank(apiRouteInfo.getUrl())) { + if (!RegExpTestUtil.urlRegExpTest(apiRouteInfo.getUrl())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:url is not a valid format(url must be begin with /)"); + + } + } + + if (!RouteUtil.contain(RouteUtil.visualRangeRange, apiRouteInfo.getVisualRange())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:VisualRange is wrong,value range:(" + + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.controlRangeMatches, apiRouteInfo.getControl())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:control is wrong,value range:(" + + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, apiRouteInfo.getStatus())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, apiRouteInfo.getUseOwnUpstream())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" + + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); + } + + // 检查服务实例格式 + RouteServer[] serverList = apiRouteInfo.getServers(); + for (int i = 0; i < serverList.length; i++) { + RouteServer server = serverList[i]; + if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { + throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:IP(" + + server.getIp() + ")is not a valid ip address"); + } + + if (!RegExpTestUtil.portRegExpTest(server.getPort())) { + throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:Port(" + + server.getPort() + ")is not a valid Port address"); + } + } + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, + apiRouteInfo.getServiceName().trim(), apiRouteInfo.getVersion().trim(), + RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("url", "/".equals(apiRouteInfo.getUrl().trim()) ? "" : apiRouteInfo + .getUrl().trim()); + serviceInfoMap.put("apijson", apiRouteInfo.getApiJson()); + serviceInfoMap.put("apiJsonType", apiRouteInfo.getApiJsonType()); + serviceInfoMap.put("metricsUrl", apiRouteInfo.getMetricsUrl()); + serviceInfoMap.put("control", apiRouteInfo.getControl()); + serviceInfoMap.put("status", apiRouteInfo.getStatus()); + serviceInfoMap.put("visualRange", apiRouteInfo.getVisualRange()); + serviceInfoMap.put("useOwnUpstream", apiRouteInfo.getUseOwnUpstream()); + + // 准备负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, + apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(), + RouteUtil.ROUTE_PATH_LOADBALANCE); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + + // 保存负载均衡信息 + for (int i = 0; i < serverList.length; i++) { + Map servermap = new HashMap(); + RouteServer server = serverList[i]; + + servermap.put("ip", server.getIp()); + servermap.put("port", server.getPort()); + servermap.put("weight", Integer.toString(server.getWeight())); + + jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); + } + // 保存生命周期信息 + +// ApiRouteLifeCycle lifeCycle = apiRouteInfo.getLifeCycle(); +// if (lifeCycle != null) { +// String serviceLifekey = +// RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, +// apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(), +// RouteUtil.APIROUTE_PATH_LIFE); +// Map serviceLifeMap = new HashMap(); +// serviceLifeMap.put("path", lifeCycle.getInstallPath()); +// serviceLifeMap.put("start", lifeCycle.getStartScript()); +// serviceLifeMap.put("stop", lifeCycle.getStopScript()); +// jedis.hmset(serviceLifekey, serviceLifeMap); +// } + + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return apiRouteInfo; + } + + + + /** + * @Title: deleteApiRoute + * @Description: TODO(删除单个服务信息) + * @param: @param type + * @param: @param serviceName + * @param: @param version + * @param: @param delKey + * @param: @return + * @return: void + */ + public synchronized void deleteApiRoute(String serviceName, String version, String delKey, + String serverPort) { + + if ("null".equals(version)) { + version = ""; + } + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException("version (" + version + + ") is not a valid format"); + } + } + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取info信息 + String routekey = + RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, serviceName, version, + delKey); + Set infoSet = jedis.keys(routekey); + + if (infoSet.isEmpty()) { + throw new ExtendedNotFoundException("delete ApiRoute FAIL:serviceName-" + + serviceName + ",version:" + version + " not fond "); + } + + String[] paths = new String[infoSet.size()]; + + // Set-->数组 + infoSet.toArray(paths); + + jedis.del(paths); + + + } catch (ExtendedNotFoundException e) { + throw e; + } catch (Exception e) { + LOGGER.error("delete ApiRoute throw exception", e); + throw new ExtendedInternalServerErrorException("delete ApiRoute throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + + } + + /** + * @Title: getAllApiDocs + * @Description: TODO(获取本地ext\initSwaggerJson目录的全部json文件目录) + * @param: @return + * @return: String[] + */ + public String[] getAllApiDocs() { + URL apiDocsPath = ApiRouteServiceWrapper.class.getResource("/ext/initSwaggerJson"); + if (apiDocsPath != null) { + String path = apiDocsPath.getPath(); + + try { + return readfile(path); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + LOGGER.error("read ApiDocs Files throw FileNotFoundException", e); + throw new ExtendedInternalServerErrorException("read ApiDocs Files throw FileNotFoundException:" + + e.getMessage()); + } catch (IOException e) { + // TODO Auto-generated catch block + LOGGER.error("read ApiDocs Files throw IOexception", e); + throw new ExtendedInternalServerErrorException("read ApiDocs Files throw IOexception:" + + e.getMessage()); + } + + } + + + return null; + } + + /** + * 读取某个文件夹下的所有文件 + */ + public String[] readfile(String filepath) throws FileNotFoundException, IOException { + File file = new File(filepath); + if (file.isDirectory()) { + String[] filelist = file.list(); + return filelist; + } + return null; + } + + public String getApiGatewayPort() { + // return JedisUtil.serverIp+":"+JedisUtil.serverPort; + return System.getenv("APIGATEWAY_EXPOSE_PORT") == null ? String + .valueOf(JedisUtil.serverPort) : System.getenv("APIGATEWAY_EXPOSE_PORT"); + + } + + public DiscoverInfo getServiceDiscoverInfo() { + return RouteUtil.discoverInfo; + + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java new file mode 100644 index 0000000..85d4d4e --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java @@ -0,0 +1,474 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.CustomRouteInfo; +import org.openo.msb.api.RouteServer; +import org.openo.msb.api.exception.ExtendedInternalServerErrorException; +import org.openo.msb.api.exception.ExtendedNotFoundException; +import org.openo.msb.api.exception.ExtendedNotSupportedException; +import org.openo.msb.wrapper.util.JedisUtil; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; + +public class CustomRouteServiceWrapper { + + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomRouteServiceWrapper.class); + + private static CustomRouteServiceWrapper instance = new CustomRouteServiceWrapper(); + + private CustomRouteServiceWrapper() {} + + public static CustomRouteServiceWrapper getInstance() { + return instance; + } + + + /** + * @Title: getAllCustomRouteService + * @Description: TODO(获取全部内容服务列表) + * @param: @return + * @return: CustomRouteInfo[] + */ + public CustomRouteInfo[] getAllCustomRouteInstances() { + + + Jedis jedis = null; + CustomRouteInfo[] customRouteList = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取全部服务列表 + String routekey = + RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, "*", + RouteUtil.ROUTE_PATH_INFO); + Set routeSet = jedis.keys(routekey); + customRouteList = new CustomRouteInfo[routeSet.size()]; + + int i = 0; + for (String routePath : routeSet) { + String[] routePathArray = routePath.split(":"); + CustomRouteInfo customRoute = getCustomRouteInstance(routePathArray[3], jedis); + customRouteList[i] = customRoute; + i++; + } + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return customRouteList; + } + + + + /** + * @Title: getCustomRouteInstance + * @Description: TODO(通过服务名获取单个内容服务对象信息) + * @param: @param serviceName + * @param: @return + * @return: CustomRouteInfo + */ + public CustomRouteInfo getCustomRouteInstance(String serviceName) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + CustomRouteInfo customRouteInfo; + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + customRouteInfo = getCustomRouteInstance(serviceName, jedis); + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + if (null == customRouteInfo) { + String errInfo = "customRouteInfo not found: serviceName-" + serviceName; + LOGGER.warn(errInfo); + throw new ExtendedNotFoundException(errInfo); + + } + + return customRouteInfo; + + } + + public CustomRouteInfo getCustomRouteInstance(String serviceName, Jedis jedis) throws Exception { + + + CustomRouteInfo customRouteInfo = null; + + + // 获取info信息 + String routekey = + RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, + RouteUtil.ROUTE_PATH_INFO); + Map infomap = jedis.hgetAll(routekey); + if (!infomap.isEmpty()) { + customRouteInfo = new CustomRouteInfo(); + customRouteInfo.setServiceName(serviceName); + customRouteInfo.setUrl(infomap.get("url")); + customRouteInfo.setControl(infomap.get("control")); + customRouteInfo.setStatus(infomap.get("status")); + customRouteInfo.setVisualRange(infomap.get("visualRange")); + customRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); + + + // 获取负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, + RouteUtil.ROUTE_PATH_LOADBALANCE); + Set serviceLBset = jedis.keys(serviceLBkey + ":*"); + int serverNum = serviceLBset.size(); + RouteServer[] CustomRouteServerList = new RouteServer[serverNum]; + int i = 0; + for (String serviceInfo : serviceLBset) { + Map serviceLBmap = jedis.hgetAll(serviceInfo); + RouteServer server = new RouteServer(); + server.setIp(serviceLBmap.get("ip")); + server.setPort(serviceLBmap.get("port")); + server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); + CustomRouteServerList[i] = server; + i++; + } + + customRouteInfo.setServers(CustomRouteServerList); + } + + + return customRouteInfo; + } + + /** + * @Title: updateCustomRouteInstance + * @Description: TODO(更新单个服务信息) + * @param: @param serviceName + * @param: @param CustomRouteInfo + * @param: @return + * @return: CustomRouteInfo + */ + public synchronized CustomRouteInfo updateCustomRouteInstance(String serviceName, + CustomRouteInfo customRouteInfo, String serverPort) { + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + try { + + if (serviceName.equals(customRouteInfo.getServiceName())) { + // 删除已存在负载均衡服务器信息 + deleteCustomRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", serverPort); + } else { + // 如果已修改服务名,先删除此服务全部已有信息 + deleteCustomRoute(serviceName, "*", serverPort); + } + + + saveCustomRouteInstance(customRouteInfo, serverPort); + + + + } catch (ExtendedNotSupportedException e) { + throw e; + } catch (Exception e) { + LOGGER.error("updateCustomRoute throw exception", e); + throw new ExtendedInternalServerErrorException("update CustomRoute throw exception" + + e.getMessage()); + + } + + return customRouteInfo; + + } + + /** + * @Title updateCustomRouteStatus + * @Description TODO(更新单个服务状态) + * @param serviceName + * @param status + * @return + * @return RouteResult + */ + public synchronized CustomRouteInfo updateCustomRouteStatus(String serviceName, String status) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo Status FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + CustomRouteInfo new_customRouteInfo = getCustomRouteInstance(serviceName); + + + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, + RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("status", status); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + new_customRouteInfo.setStatus(status); + + } catch (Exception e) { + + LOGGER.error("update CustomRoute status throw exception", e); + throw new ExtendedInternalServerErrorException( + "update CustomRoute status throw exception" + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return new_customRouteInfo; + } + + /** + * @Title: saveCustomRouteInstance + * @Description: TODO(存储单个服务信息) + * @param: @param CustomRouteInfo + * @param: @return + * @return: CustomRouteInfo + */ + public synchronized CustomRouteInfo saveCustomRouteInstance(CustomRouteInfo customRouteInfo, + String serverPort) { + + if (StringUtils.isBlank(customRouteInfo.getServiceName()) + || customRouteInfo.getServers().length == 0) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL: Some required fields are empty"); + } + + + if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getServiceName())) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL: ServiceName is not a valid format(ServiceName must be begin with /)"); + + } + + if (StringUtils.isNotBlank(customRouteInfo.getUrl())){ + if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getUrl())) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL:url is not a valid format(url must be begin with /)"); + + } + } + + if (!RouteUtil.contain(RouteUtil.visualRangeRange, customRouteInfo.getVisualRange())) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL:VisualRange is wrong,value range:(" + + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.controlRangeMatches, customRouteInfo.getControl())) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL:control is wrong,value range:(" + + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, customRouteInfo.getStatus())) { + throw new ExtendedNotSupportedException( + "save CustomRouteInfo FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, customRouteInfo.getUseOwnUpstream())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" + + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); + } + + // 检查服务实例格式 + RouteServer[] serverList = customRouteInfo.getServers(); + for (int i = 0; i < serverList.length; i++) { + RouteServer server = serverList[i]; + if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { + throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:IP(" + + server.getIp() + ")is not a valid ip address"); + } + + if (!RegExpTestUtil.portRegExpTest(server.getPort())) { + throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:Port(" + + server.getPort() + ")is not a valid Port address"); + } + } + + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, + customRouteInfo.getServiceName().trim(), RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("url", "/".equals(customRouteInfo.getUrl().trim()) + ? "" + : customRouteInfo.getUrl().trim()); + serviceInfoMap.put("control", customRouteInfo.getControl()); + serviceInfoMap.put("status", customRouteInfo.getStatus()); + serviceInfoMap.put("visualRange", customRouteInfo.getVisualRange()); + serviceInfoMap.put("useOwnUpstream", customRouteInfo.getUseOwnUpstream()); + + + + // 准备负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, + customRouteInfo.getServiceName(), RouteUtil.ROUTE_PATH_LOADBALANCE); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + + // 保存负载均衡信息 + + for (int i = 0; i < serverList.length; i++) { + Map servermap = new HashMap(); + RouteServer server = serverList[i]; + + servermap.put("ip", server.getIp()); + servermap.put("port", server.getPort()); + servermap.put("weight", Integer.toString(server.getWeight())); + + jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); + } + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis);; + } + + return customRouteInfo; + } + + + + /** + * @Title: deleteCustomRoute + * @Description: TODO(删除单个服务信息) + * @param: @param type + * @param: @param serviceName + * @param: @param delKey + * @param: @return + * @return: void + */ + public synchronized void deleteCustomRoute(String serviceName, String delKey, String serverPort) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + Jedis jedis = null; + + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取info信息 + String routekey = + RouteUtil + .getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, serviceName, delKey); + Set infoSet = jedis.keys(routekey); + + if (infoSet.isEmpty()) { + throw new ExtendedNotFoundException("delete CustomRoute FAIL:serviceName-" + + serviceName + " not fond "); + } + + + String[] paths = new String[infoSet.size()]; + + // Set-->数组 + infoSet.toArray(paths); + + jedis.del(paths); + + } catch (ExtendedNotFoundException e) { + throw e; + } catch (Exception e) { + + LOGGER.error("delete CustomRoute throw exception", e); + throw new ExtendedInternalServerErrorException("delete CustomRoute throw exception:" + + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java new file mode 100644 index 0000000..d705172 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java @@ -0,0 +1,453 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.IuiRouteInfo; +import org.openo.msb.api.RouteServer; +import org.openo.msb.api.exception.ExtendedInternalServerErrorException; +import org.openo.msb.api.exception.ExtendedNotFoundException; +import org.openo.msb.api.exception.ExtendedNotSupportedException; +import org.openo.msb.wrapper.util.JedisUtil; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; + +public class IuiRouteServiceWrapper { + + + private static final Logger LOGGER = LoggerFactory.getLogger(IuiRouteServiceWrapper.class); + + private static IuiRouteServiceWrapper instance = new IuiRouteServiceWrapper(); + + private IuiRouteServiceWrapper() {} + + public static IuiRouteServiceWrapper getInstance() { + return instance; + } + + + /** + * @Title: getAllIuiRouteService + * @Description: TODO(获取全部内容服务列表) + * @param: @return + * @return: IuiRouteInfo[] + */ + public IuiRouteInfo[] getAllIuiRouteInstances() { + + + Jedis jedis = null; + IuiRouteInfo[] iuiRouteList = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取全部服务列表 + String routekey = + RouteUtil + .getPrefixedKey("", RouteUtil.IUIROUTE, "*", RouteUtil.ROUTE_PATH_INFO); + Set routeSet = jedis.keys(routekey); + iuiRouteList = new IuiRouteInfo[routeSet.size()]; + + int i = 0; + for (String routePath : routeSet) { + String[] routePathArray = routePath.split(":"); + IuiRouteInfo iuiRoute = getIuiRouteInstance(routePathArray[3], jedis); + iuiRouteList[i] = iuiRoute; + i++; + } + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return iuiRouteList; + } + + + + /** + * @Title: getIuiRouteInstance + * @Description: TODO(通过服务名获取单个内容服务对象信息) + * @param: @param serviceName + * @param: @return + * @return: IuiRouteInfo + */ + public IuiRouteInfo getIuiRouteInstance(String serviceName) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + IuiRouteInfo iuiRouteInfo = null; + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + iuiRouteInfo = getIuiRouteInstance(serviceName, jedis); + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + if (null == iuiRouteInfo) { + String errInfo = "iuiRouteInfo not found: serviceName-" + serviceName; + LOGGER.warn(errInfo); + throw new ExtendedNotFoundException(errInfo); + + } + + return iuiRouteInfo; + + } + + public IuiRouteInfo getIuiRouteInstance(String serviceName, Jedis jedis) throws Exception { + + + IuiRouteInfo iuiRouteInfo = null; + + + // 获取info信息 + String routekey = + RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, + RouteUtil.ROUTE_PATH_INFO); + Map infomap = jedis.hgetAll(routekey); + if (!infomap.isEmpty()) { + iuiRouteInfo = new IuiRouteInfo(); + iuiRouteInfo.setServiceName(serviceName); + iuiRouteInfo.setUrl(infomap.get("url")); + iuiRouteInfo.setControl(infomap.get("control")); + iuiRouteInfo.setStatus(infomap.get("status")); + iuiRouteInfo.setVisualRange(infomap.get("visualRange")); + iuiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); + + + // 获取负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, + RouteUtil.ROUTE_PATH_LOADBALANCE); + Set serviceLBset = jedis.keys(serviceLBkey + ":*"); + int serverNum = serviceLBset.size(); + RouteServer[] iuiRouteServerList = new RouteServer[serverNum]; + int i = 0; + for (String serviceInfo : serviceLBset) { + Map serviceLBmap = jedis.hgetAll(serviceInfo); + RouteServer server = new RouteServer(); + server.setIp(serviceLBmap.get("ip")); + server.setPort(serviceLBmap.get("port")); + server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); + iuiRouteServerList[i] = server; + i++; + } + + iuiRouteInfo.setServers(iuiRouteServerList); + } + + + return iuiRouteInfo; + } + + /** + * @Title: updateIuiRouteInstance + * @Description: TODO(更新单个服务信息) + * @param: @param serviceName + * @param: @param IuiRouteInfo + * @param: @return + * @return: IuiRouteInfo + */ + public synchronized IuiRouteInfo updateIuiRouteInstance(String serviceName, + IuiRouteInfo iuiRouteInfo) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + try { + if (serviceName.equals(iuiRouteInfo.getServiceName())) { + // 删除已存在负载均衡服务器信息 + deleteIuiRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*"); + + } else { + // 如果已修改服务名,先删除此服务全部已有信息 + deleteIuiRoute(serviceName, "*"); + } + saveIuiRouteInstance(iuiRouteInfo); + + } catch (ExtendedNotSupportedException e) { + throw e; + } catch (Exception e) { + LOGGER.error("updateIuiRoute throw exception", e); + throw new ExtendedInternalServerErrorException("update IuiRouteInfo throw exception" + + e.getMessage()); + } + + return iuiRouteInfo; + + } + + /** + * @Title updateIuiRouteStatus + * @Description TODO(更新单个服务状态) + * @param serviceName + * @param status + * @return + * @return RouteResult + */ + public synchronized IuiRouteInfo updateIuiRouteStatus(String serviceName, String status) { + + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { + throw new ExtendedNotSupportedException( + "save IuiRouteInfo Status FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + IuiRouteInfo new_iuiRouteInfo = getIuiRouteInstance(serviceName); + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, + RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("status", status); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + new_iuiRouteInfo.setStatus(status); + + } catch (Exception e) { + LOGGER.error("update IuiRoute status throw exception", e); + throw new ExtendedInternalServerErrorException( + "update IuiRouteInfo status throw exception" + e.getMessage()); + + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return new_iuiRouteInfo; + } + + /** + * @Title: saveIuiRouteInstance + * @Description: TODO(存储单个服务信息) + * @param: @param IuiRouteInfo + * @param: @return + * @return: IuiRouteInfo + */ + public synchronized IuiRouteInfo saveIuiRouteInstance(IuiRouteInfo iuiRouteInfo) { + + if (StringUtils.isBlank(iuiRouteInfo.getServiceName()) + || iuiRouteInfo.getServers().length == 0) { + throw new ExtendedNotSupportedException( + "save iuiRouteInfo FAIL: Some required fields are empty"); + } + + if (StringUtils.isNotBlank(iuiRouteInfo.getUrl())){ + if (!RegExpTestUtil.urlRegExpTest(iuiRouteInfo.getUrl())) { + throw new ExtendedNotSupportedException( + "save iuiRouteInfo FAIL:url is not a valid format(url must be begin with /)"); + + } + } + + if (!RouteUtil.contain(RouteUtil.visualRangeRange, iuiRouteInfo.getVisualRange())) { + throw new ExtendedNotSupportedException( + "save iuiRouteInfo FAIL:VisualRange is wrong,value range:(" + + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.controlRangeMatches, iuiRouteInfo.getControl())) { + throw new ExtendedNotSupportedException( + "save iuiRouteInfo FAIL:control is wrong,value range:(" + + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.statusRangeMatches, iuiRouteInfo.getStatus())) { + throw new ExtendedNotSupportedException( + "save iuiRouteInfo FAIL:status is wrong,value range:(" + + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); + } + + if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, iuiRouteInfo.getUseOwnUpstream())) { + throw new ExtendedNotSupportedException( + "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" + + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); + } + + // 检查服务实例格式 + RouteServer[] serverList = iuiRouteInfo.getServers(); + for (int i = 0; i < serverList.length; i++) { + RouteServer server = serverList[i]; + if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { + throw new ExtendedNotSupportedException("save iuiRouteInfo FAIL:IP(" + + server.getIp() + ")is not a valid ip address"); + } + + if (!RegExpTestUtil.portRegExpTest(server.getPort())) { + throw new ExtendedNotSupportedException("save iuiRouteInfo FAIL:Port(" + + server.getPort() + ")is not a valid Port address"); + } + } + + + // 准备info信息 + String serviceInfokey = + RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, iuiRouteInfo.getServiceName().trim(), + RouteUtil.ROUTE_PATH_INFO); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("url", "/".equals(iuiRouteInfo.getUrl().trim()) ? "" : iuiRouteInfo + .getUrl().trim()); + serviceInfoMap.put("control", iuiRouteInfo.getControl()); + serviceInfoMap.put("status", iuiRouteInfo.getStatus()); + serviceInfoMap.put("visualRange", iuiRouteInfo.getVisualRange()); + serviceInfoMap.put("useOwnUpstream", iuiRouteInfo.getUseOwnUpstream()); + + + // 准备负载均衡信息 + String serviceLBkey = + RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, iuiRouteInfo.getServiceName(), + RouteUtil.ROUTE_PATH_LOADBALANCE); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + // 保存info信息 + jedis.hmset(serviceInfokey, serviceInfoMap); + + // 保存负载均衡信息 + for (int i = 0; i < serverList.length; i++) { + Map servermap = new HashMap(); + RouteServer server = serverList[i]; + + servermap.put("ip", server.getIp()); + servermap.put("port", server.getPort()); + servermap.put("weight", Integer.toString(server.getWeight())); + + jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); + } + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new ExtendedInternalServerErrorException("call redis throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis);; + } + + return iuiRouteInfo; + } + + + + /** + * @Title: deleteIuiRoute + * @Description: TODO(删除单个服务信息) + * @param: @param type + * @param: @param serviceName + * @param: @param delKey + * @param: @return + * @return: void + */ + public synchronized void deleteIuiRoute(String serviceName, String delKey) { + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new ExtendedInternalServerErrorException( + "fetch from jedis pool failed,null object!"); + } + + // 获取info信息 + String routekey = RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, delKey); + Set infoSet = jedis.keys(routekey); + + if (infoSet.isEmpty()) { + throw new ExtendedNotFoundException("delete IuiRoute FAIL:serviceName-" + + serviceName + " not fond "); + } + + String[] paths = new String[infoSet.size()]; + + // Set-->数组 + infoSet.toArray(paths); + + jedis.del(paths); + + + } catch (ExtendedNotFoundException e) { + throw e; + } catch (Exception e) { + LOGGER.error("delete IuiRoute throw exception", e); + throw new ExtendedInternalServerErrorException("delete IuiRoute throw exception:" + + e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java new file mode 100644 index 0000000..656acb8 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java @@ -0,0 +1,92 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.io.IOException; + +import org.apache.http.ParseException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.openo.msb.api.MetricsInfo; +import org.openo.msb.wrapper.util.MetricsUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class MetricsServiceWrapper { + + private static final Logger LOGGER = LoggerFactory + .getLogger(MetricsServiceWrapper.class); + + public static MetricsInfo getMetricsInfo() { + + String metricsUrl = MetricsUtil.adminContextPath; + String metricsJson = sendGetRequest(metricsUrl); + + metricsJson = metricsJson.replace("E_", "");//.replaceAll("(?![0-9])(\\.)(?![0-9])", "_").replace("-", "_") + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + MetricsInfo metricsInfo = new MetricsInfo(); + try { + metricsInfo = mapper.readValue(metricsJson, MetricsInfo.class); + } catch (Exception e) { + // TODO Auto-generated catch block + LOGGER.error("Jackson readValue to metricsInfo throw exception", e); + } + + return metricsInfo; + } + + public static String sendGetRequest(String url) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + + try { + CloseableHttpResponse res = httpClient.execute(httpGet); + try { + if (res.getStatusLine().getStatusCode() == MetricsUtil.SC_OK) { + return EntityUtils.toString(res.getEntity()); + } + } finally { + res.close(); + } + } catch (ParseException e) { + LOGGER.error("HttpClient throw ParseException:" + url, e); + } catch (IOException e) { + LOGGER.error("HttpClient throw IOException:" + url, e); + } + finally{ + try { + httpClient.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + LOGGER.error("HttpClient Close throw IOException", e); + } + } + + return null; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java new file mode 100644 index 0000000..4e5e6cb --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java @@ -0,0 +1,536 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.MicroServiceFullInfo; +import org.openo.msb.api.MicroServiceInfo; +import org.openo.msb.api.Node; +import org.openo.msb.api.NodeInfo; +import org.openo.msb.api.exception.ExtendedInternalServerErrorException; +import org.openo.msb.api.exception.ExtendedNotFoundException; +import org.openo.msb.api.exception.ExtendedNotSupportedException; +import org.openo.msb.wrapper.util.MicroServiceDB; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MicroServiceWrapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceWrapper.class); + + private static MicroServiceWrapper instance = new MicroServiceWrapper(); + + + private MicroServiceWrapper() {} + + public static MicroServiceWrapper getInstance() { + return instance; + } + + + /** + * @Title: getAllMicroServiceInstances + * @Description: getAllMicroServiceInstances + * @param: @return + * @return: Response + * @throws Exception + */ + public MicroServiceFullInfo[] getAllMicroServiceInstances(){ + + try { + return MicroServiceDB.getInstance().getAllMicroServiceInstances(); + + } catch (Exception e) { + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + } + + /** + * @Title: getMicroServiceInstance + * @Description: (getMicroServiceInstance) + * @param: @param serviceName + * @param: @param version + * @param: @return + * @return: ApiRouteInfo + */ + public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException("serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException("version (" + version + + ") is not a valid format"); + } + } + + MicroServiceFullInfo microServiceInfo; + try { + microServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort); + + } catch (Exception e) { + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + if (null == microServiceInfo) { + String errInfo = + "microservice not found: serviceName-" + serviceName + ",version-" + version; + LOGGER.warn(errInfo); + throw new ExtendedNotFoundException(errInfo); + + } + + return microServiceInfo; + } + + + + /** + * @Title: updateMicroServiceInstance + * @Description: updateMicroServiceInstance + * @param: serviceName + * @param: version + * @param: microServiceInfo + * @return: RouteResult + */ + public synchronized MicroServiceFullInfo updateMicroServiceInstance(String serviceName, + String version, MicroServiceInfo microServiceInfo) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + try { + + + MicroServiceFullInfo oldService= getMicroServiceInstance(serviceName,version,""); + + // Delete the original record + MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); + // Notify the listeners + MicroServiceDB.getInstance().noticeApiListener(oldService, "DELETE",""); + // Save the new record + MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,""); + + MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD",""); + MicroServiceFullInfo newMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance( + microServiceInfo.getServiceName(), microServiceInfo.getVersion(),""); + return newMicroServiceInfo; + } catch (Exception e) { + LOGGER.error("update MicroService throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + + } + + public synchronized MicroServiceFullInfo updateMicroServiceNode(String serviceName, + String version, String ip,String port, int ttl) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException( + "update MicroService Node FAIL:serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException( + "update MicroService Node FAIL:version is not a valid format"); + } + } + + if (!RegExpTestUtil.ipRegExpTest(ip)) { + throw new ExtendedNotSupportedException("update MicroService Node FAIL:ip(" + ip + + ")is not a valid IP address"); + } + + if (!RegExpTestUtil.portRegExpTest(port)) { + throw new ExtendedNotSupportedException("update MicroService Node FAIL:port(" + port + + ")is not a valid Port address"); + } + + try { + + MicroServiceDB.getInstance().updateMicroServiceNode2Redis(serviceName, version, ip,port,ttl); + + MicroServiceFullInfo newMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); + + return newMicroServiceInfo; + } catch (NullPointerException e) { + throw new ExtendedNotFoundException(e.getMessage()); + } catch (Exception e) { + LOGGER.error("update MicroServiceNode throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + } + + /** + * @Title updateMicroServiceStatus + * @Description updateMicroServiceStatus + * @param serviceName + * @param version + * @param status + * @return + * @return RouteResult + */ + + public synchronized MicroServiceFullInfo updateMicroServiceStatus(String serviceName, String version, + String status) { + + if ("null".equals(version)) { + version = ""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException( + "update MicroService status FAIL:serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException( + "update MicroService status FAIL:version is not a valid format"); + } + } + + if(!"0".equals(status) && !"2".equals(status) && !"1".equals(status)){ + + throw new ExtendedNotSupportedException("update MicroService status FAIL:status is wrong"); + } + + + try { + + MicroServiceDB.getInstance().updateMicroServiceStatus(serviceName, version, status); + + MicroServiceFullInfo newMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); + + // Notify the listeners + MicroServiceDB.getInstance().noticeUpdateStatusListener(newMicroServiceInfo, status); + + + return newMicroServiceInfo; + } catch (NullPointerException e) { + throw new ExtendedNotFoundException(e.getMessage()); + } catch (Exception e) { + LOGGER.error("update MicroServiceNode throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + + } + + + public synchronized MicroServiceFullInfo saveMicroServiceInstance( + MicroServiceInfo microServiceInfo, boolean createOrUpdate,String requestIP,String serverPort) { + // 保存数据格式判断 + + if (StringUtils.isBlank(microServiceInfo.getServiceName()) + || StringUtils.isBlank(microServiceInfo.getProtocol()) + || microServiceInfo.getNodes().size() == 0) { + throw new ExtendedNotSupportedException( + "register MicroServiceInfo FAIL: Some required fields are empty"); + } + + for (Node node : microServiceInfo.getNodes()) { + + if(node.getIp()==null || node.getIp().isEmpty()){ + node.setIp(requestIP); + } + else if (!RegExpTestUtil.ipRegExpTest(node.getIp())) { + throw new ExtendedNotSupportedException("register MicroServiceInfo FAIL:IP(" + + node.getIp() + ")is not a valid ip address"); + } + + if (!RegExpTestUtil.portRegExpTest(node.getPort())) { + throw new ExtendedNotSupportedException("register MicroServiceInfo FAIL:Port(" + + node.getPort() + ")is not a valid Port address"); + } + } + + if (StringUtils.isNotBlank(microServiceInfo.getVersion())) { + if (!RegExpTestUtil.versionRegExpTest(microServiceInfo.getVersion())) { + throw new ExtendedNotSupportedException( + "register MicroServiceInfo FAIL:version is not a valid format"); + + } + } + + if (StringUtils.isNotBlank(microServiceInfo.getUrl().trim())) { + if (!RegExpTestUtil.urlRegExpTest(microServiceInfo.getUrl())) { + throw new ExtendedNotSupportedException( + "register MicroServiceInfo FAIL:url is not a valid format(url must be begin with /)"); + + } + } + + + if (RouteUtil.PROTOCOL_LIST.indexOf(microServiceInfo.getProtocol().trim()) == -1) { + throw new ExtendedNotSupportedException( + "register MicroServiceInfo FAIL:Protocol is wrong,value range:(" + + RouteUtil.PROTOCOL_LIST + ")"); + } + + MicroServiceFullInfo existingMicroServiceInfo; + try { + //To determine whether a service already exists + existingMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance( + microServiceInfo.getServiceName().trim(), microServiceInfo.getVersion().trim(),serverPort); + + MicroServiceFullInfo newMicroServiceInfo ; + if (existingMicroServiceInfo != null) { + //a service already exists + + if (!existingMicroServiceInfo.getProtocol().equals(microServiceInfo.getProtocol())) { + throw new ExtendedNotSupportedException( + "MicroServiceInfo with different protocols and same serviceName is already existing"); + } + + if (createOrUpdate == false) { + //After the first remove added + MicroServiceDB.getInstance().deleteMicroService( + microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort); + + MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort); + + } else { + //Add the original record and save directly + MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort); + } + + newMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance( + microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort); + + //Notify the listeners + MicroServiceDB.getInstance().noticeUpdateApiListener(microServiceInfo.getServiceName(),microServiceInfo.getVersion(),newMicroServiceInfo,serverPort); + + } else { + //Save the new record + MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort); + //Notify the listeners + MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD",serverPort); + newMicroServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance( + microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort); + } + + + + return newMicroServiceInfo; + + } catch (ExtendedNotSupportedException e) { + throw e; + } catch (Exception e) { + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + } + + + public synchronized void deleteMicroService(String serviceName, String version) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:version is not a valid format"); + + } + } + + try { + + MicroServiceFullInfo microServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); + + if (microServiceInfo == null) { + LOGGER.warn("serviceName-"+ serviceName + ",version-" + version + " not fond "); + return; + } + + MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); + //Notify the listeners + MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",""); + + } catch (Exception e) { + LOGGER.error("delete MicroServiceInfo throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + + } + + LOGGER.info("delete MicroServiceInfo success:serviceName-" + + serviceName + ",version-" + version ); + + } + + + public synchronized void deleteMicroService(String serviceName, String version,String serverPort) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:version is not a valid format"); + + } + } + + try { + + MicroServiceFullInfo microServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort); + + if (microServiceInfo == null) { + throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-" + + serviceName + ",version-" + version + " not fond "); + } + + MicroServiceDB.getInstance().deleteMicroService(serviceName, version,serverPort); + //Notify the listeners + MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",serverPort); + } catch (ExtendedNotFoundException e) { + throw e; + } catch (Exception e) { + LOGGER.error("delete MicroServiceInfo throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + + } + + LOGGER.info("delete MicroServiceInfo success:serviceName-" + + serviceName + ",version-" + version ); + + } + + public synchronized void deleteMicroServiceInstance(String serviceName, String version, + String ip,String port) { + if("null".equals(version)) { + version=""; + } + serviceName=serviceName.replace("*", "/"); + + if (StringUtils.isBlank(serviceName)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:serviceName can't be empty"); + } + + if (StringUtils.isNotBlank(version)) { + if (!RegExpTestUtil.versionRegExpTest(version)) { + throw new ExtendedNotSupportedException( + "delete MicroServiceInfo FAIL:version is not a valid format"); + } + } + + if (!RegExpTestUtil.ipRegExpTest(ip)) { + throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:IP(" + ip + + ")is not a valid IP address"); + } + + if (!RegExpTestUtil.portRegExpTest(port)) { + throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:Port(" + port + + ")is not a valid Port address"); + } + + + try { + MicroServiceFullInfo microServiceInfo = + MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); + + if (microServiceInfo == null) { + throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-" + + serviceName + ",version-" + version + " not fond "); + } + + Set nodes = microServiceInfo.getNodes(); + + boolean ifFindBNode = false; + + for (Node node : nodes) { + if (node.getIp().equals(ip) && node.getPort().equals(port)) { + ifFindBNode = true; + nodes.remove(node); + + if (nodes.isEmpty()) { + //delete MicroService + MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); + //Notify the listeners + MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",""); + } else { + //delete Node + MicroServiceDB.getInstance().deleteNode(serviceName, version, ip,port); + MicroServiceDB.getInstance().noticeUpdateApiListener(serviceName, version,microServiceInfo,""); + } + + break; + } + } + + if (!ifFindBNode) { + throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL: node-" + ip+":"+port + + " not fond "); + } + + + } catch (ExtendedNotFoundException e) { + throw e; + } catch (Exception e) { + LOGGER.error("deleteApiRoute throw exception", e); + throw new ExtendedInternalServerErrorException(e.getMessage()); + + } + + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java new file mode 100644 index 0000000..35b02e7 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java @@ -0,0 +1,172 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openo.msb.api.ServiceAccessInfo; +import org.openo.msb.wrapper.util.JedisUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; + +public class ServiceAccessWrapper { + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAccessWrapper.class); + + private static ServiceAccessWrapper instance = new ServiceAccessWrapper(); + + private ServiceAccessWrapper() {} + + public static ServiceAccessWrapper getInstance() { + return instance; + } + + public ServiceAccessInfo getApiServiceAccessAddr(String serviceName, String version, String host) { + + ServiceAccessInfo apiRouteAccessInfo = null; + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new Exception("fetch from jedis pool failed,null object!"); + } + + if ("null".equals(version)) { + version = ""; + } + + String routekey = + RouteUtil.getPrefixedKey("",RouteUtil.APIROUTE, serviceName, version, + RouteUtil.ROUTE_PATH_INFO); + Boolean isExist = jedis.exists(routekey); + if (isExist) { + apiRouteAccessInfo = new ServiceAccessInfo(); + apiRouteAccessInfo.setServiceName(serviceName); + apiRouteAccessInfo.setVersion(version); + String accessAddr = "http://" + host + "/api/" + serviceName + "/" + version; + apiRouteAccessInfo.setAccessAddr(accessAddr); + } + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + return apiRouteAccessInfo; + + } + + public List getApiRouteAccessAddr(String serviceType, String serviceName, + String version, String host) { + List serviceList = new ArrayList(); + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new Exception("fetch from jedis pool failed,null object!"); + } + + String keyPattern = this.getRedisSearchPattern(serviceType, serviceName, version); + Set infoKeys = jedis.keys(keyPattern); + Pattern pattern = this.getKeyPattern(); + for (Iterator iterator = infoKeys.iterator(); iterator.hasNext();) { + String infoKey = (String) iterator.next(); + Matcher matcher = pattern.matcher(infoKey); + if (matcher.matches()) { + ServiceAccessInfo serviceAccessInfo = new ServiceAccessInfo(); + serviceAccessInfo.setServiceType(matcher.group("servicetype")); + serviceAccessInfo.setServiceName(matcher.group("servicename")); + serviceAccessInfo.setVersion(matcher.group("version")); + this.buildServiceAccessAddr(serviceAccessInfo, host, infoKey, jedis); + serviceList.add(serviceAccessInfo); + } + } + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + return serviceList; + + } + + private void buildServiceAccessAddr(ServiceAccessInfo serviceAccessInfo, String host, + String infoKey, Jedis jedis) { + String serviceType = serviceAccessInfo.getServiceType(); + StringBuffer accessAddr = new StringBuffer(); + switch (serviceType) { + case RouteUtil.APIROUTE: + accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) + .append("/").append(serviceAccessInfo.getServiceType()).append("/") + .append(serviceAccessInfo.getServiceName()).append("/") + .append(serviceAccessInfo.getVersion()); + serviceAccessInfo.setAccessAddr(accessAddr.toString()); + break; + case RouteUtil.IUIROUTE: + accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) + .append("/").append(serviceAccessInfo.getServiceType()).append("/") + .append(serviceAccessInfo.getServiceName()); + serviceAccessInfo.setAccessAddr(accessAddr.toString()); + break; + case RouteUtil.CUSTOMROUTE: + accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) + .append(serviceAccessInfo.getServiceName()); + serviceAccessInfo.setAccessAddr(accessAddr.toString()); + break; + case RouteUtil.P2PROUTE: + accessAddr.append(jedis.hget(infoKey, "url")); + serviceAccessInfo.setAccessAddr(accessAddr.toString()); + break; + default: + serviceAccessInfo.setAccessAddr("not supported now"); + break; + } + } + + private String getRedisSearchPattern(String serviceType, String serviceName, String version) { + StringBuffer sb = new StringBuffer(); + sb.append(RouteUtil.ROUTE_PATH); + if (null != serviceType && !"".equals(serviceType)) { + sb.append(":").append(serviceType); + } else { + sb.append(":").append("*"); + } + sb.append(":").append(serviceName); + if (null != version && !"".equals(version)) { + sb.append(":"); + sb.append(version); + sb.append(":"); + } else { + sb.append(":*"); + } + sb.append(RouteUtil.ROUTE_PATH_INFO); + return sb.toString(); + } + + private Pattern getKeyPattern() { + String pStr = + "conductor:routing:(?api|iui|custom|p2p):(?[^:]+)(:(?[^:]*))?:info"; + return Pattern.compile(pStr); + } +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java new file mode 100644 index 0000000..576bf9b --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java @@ -0,0 +1,285 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul; + +import static org.openo.msb.wrapper.consul.util.ClientUtil.response; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.model.catalog.CatalogNode; +import org.openo.msb.wrapper.consul.model.catalog.CatalogService; +import org.openo.msb.wrapper.consul.model.health.Node; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +/** + * HTTP Client for /v1/catalog/ endpoints or api/catalog/v1 by openresty + */ +public class CatalogClient { + + private static final GenericType> TYPE_STRING_LIST = new GenericType>() {}; + private static final GenericType> TYPE_NODE_LIST = new GenericType>() {}; + private static final GenericType>> TYPE_SERVICES_MAP = new GenericType>>() {}; + private static final GenericType> TYPE_CATALOG_SERVICE_LIST = new GenericType>() {}; + private static final GenericType TYPE_CATALOG_NODE = new GenericType() {}; + + private final WebTarget webTarget; + + /** + * Constructs an instance of this class. + * + * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. + */ + CatalogClient(WebTarget webTarget) { + this.webTarget = webTarget; + } + + /** + * Retrieves all datacenters. + * + * GET /v1/catalog/datacenters + * + * @return A list of datacenter names. + */ + public List getDatacenters() { + return webTarget.path("datacenters").request() + .accept(MediaType.APPLICATION_JSON_TYPE).get(TYPE_STRING_LIST); + } + + /** + * Retrieves all nodes. + * + * GET /v1/catalog/nodes + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse> getNodes() { + return getNodes(null, QueryOptions.BLANK); + } + + /** + * Retrieves all nodes for a given datacenter. + * + * GET /v1/catalog/nodes?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse> getNodes(CatalogOptions catalogOptions) { + return getNodes(catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/nodes + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse> getNodes(QueryOptions queryOptions) { + return getNodes(null, queryOptions); + } + + /** + * Retrieves all nodes for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/nodes?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse> getNodes(CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("nodes"), catalogOptions, queryOptions, TYPE_NODE_LIST); + } + + /** + * Retrieves all services for a given datacenter. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse>> getServices() { + return getServices(null, QueryOptions.BLANK); + } + + /** + * Retrieves all services for a given datacenter. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse>> getServices(CatalogOptions catalogOptions) { + return getServices(catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse>> getServices(QueryOptions queryOptions) { + return getServices(null, queryOptions); + } + + /** + * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse>> getServices(CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("services"), catalogOptions, queryOptions, TYPE_SERVICES_MAP); + } + + public void getService(QueryOptions queryOptions, ConsulResponseCallback>> callback) { + response(webTarget.path("services"), CatalogOptions.BLANK, + queryOptions, TYPE_SERVICES_MAP, callback); + } + + /** + * Retrieves a single service. + * + * GET /v1/catalog/service/{service} + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse> getService(String service) { + return getService(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves a single service for a given datacenter. + * + * GET /v1/catalog/service/{service}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse> getService(String service, CatalogOptions catalogOptions) { + return getService(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves a single service with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/service/{service} + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse> getService(String service, QueryOptions queryOptions) { + return getService(service, null, queryOptions); + } + + public void getService(String service, QueryOptions queryOptions, ConsulResponseCallback> callback) { + + response(webTarget.path("service").path(service), CatalogOptions.BLANK, + queryOptions, TYPE_CATALOG_SERVICE_LIST, callback); + } + + + + /** + * Retrieves a single service for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/service/{service}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse> getService(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_CATALOG_SERVICE_LIST); + } + + /** + * Retrieves a single node. + * + * GET /v1/catalog/node/{node} + * + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse getNode(String node) { + return getNode(node, null, QueryOptions.BLANK); + } + + /** + * Retrieves a single node for a given datacenter. + * + * GET /v1/catalog/node/{node}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse getNode(String node, CatalogOptions catalogOptions) { + return getNode(node, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves a single node with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/node/{node} + * + * @param queryOptions The Query Options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse getNode(String node, QueryOptions queryOptions) { + return getNode(node, null, queryOptions); + } + + /** + * Retrieves a single node for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/node/{node}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse getNode(String node, CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("node").path(node), catalogOptions, queryOptions, + TYPE_CATALOG_NODE); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java new file mode 100644 index 0000000..2a55b7f --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java @@ -0,0 +1,299 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + +import org.openo.msb.wrapper.consul.util.Jackson; +import org.openo.msb.wrapper.consul.util.ObjectMapperContextResolver; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.guava.GuavaModule; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.net.HostAndPort; + +/** + * Client for interacting with the Consul HTTP API. + * + * @author rfast + */ +public class Consul { + + /** + * Default Consul HTTP API host. + */ + public static final String DEFAULT_HTTP_HOST = "localhost"; + + /** + * Default Consul HTTP API port. + */ + public static final int DEFAULT_HTTP_PORT = 8500; + + + + + private final CatalogClient catalogClient; + + private final HealthClient healthClient; + + + /** + * Private constructor. + * + * @param url The full URL of a running Consul instance. + * @param builder JAX-RS client builder instance. + */ + private Consul(String url, ClientBuilder builder, ObjectMapper mapper) { + + if (!FluentIterable.from(builder.getConfiguration().getClasses()) + .filter(new Predicate>() { + @Override + public boolean apply(final Class clazz) { + return JacksonJaxbJsonProvider.class.isAssignableFrom(clazz); + } + }).first().isPresent()) { + builder.register(JacksonJaxbJsonProvider.class); + } + final Client client = builder + .register(new ObjectMapperContextResolver(mapper)) + .build(); + + + if(url.endsWith("8500")){ + this.catalogClient = new CatalogClient(client.target(url).path("v1").path("catalog")); + this.healthClient = new HealthClient(client.target(url).path("v1").path("health")); + } + else{ + this.catalogClient = new CatalogClient(client.target(url).path("api").path("catalog").path("v1")); + this.healthClient = new HealthClient(client.target(url).path("api").path("health").path("v1")); + } + + +// agentClient.ping(); + } + + /** + * Creates a new client given a complete URL. + * + * @deprecated Use {@link Consul.Builder} + * + * @param url The Consul API URL. + * @param builder The JAX-RS client builder instance. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String url, ClientBuilder builder, ObjectMapper mapper) { + return new Consul(url, builder, mapper); + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @param host The Consul API hostname or IP. + * @param port The Consul port. + * @param builder The JAX-RS client builder instance. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String host, int port, ClientBuilder builder, ObjectMapper mapper) { + try { + return new Consul(new URL("http", host, port, "").toString(), builder, mapper); + } catch (MalformedURLException e) { + throw new ConsulException("Bad Consul URL", e); + } + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @param host The Consul API hostname or IP. + * @param port The Consul port. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String host, int port) { + return newClient(host, port, ClientBuilder.newBuilder(), Jackson.MAPPER); + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @return A new client. + */ + @Deprecated + public static Consul newClient() { + return newClient(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT); + } + + + /** + * Get the Catalog HTTP client. + *

+ * /v1/catalog + * + * @return The Catalog HTTP client. + */ + public CatalogClient catalogClient() { + return catalogClient; + } + + public HealthClient healthClient() { + return healthClient; + } + /** + * Creates a new {@link Builder} object. + * + * @return A new Consul builder. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link Consul} client objects. + */ + public static class Builder { + private URL url; + private Optional sslContext = Optional.absent(); + private ObjectMapper objectMapper = Jackson.MAPPER; + private ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + + { + try { + url = new URL("http", "localhost", 8500, ""); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** + * Constructs a new builder. + */ + Builder() { + + } + + /** + * Sets the URL from a {@link URL} object. + * + * @param url The Consul agent URL. + * @return The builder. + */ + public Builder withUrl(URL url) { + this.url = url; + + return this; + } + + /** + * Sets the URL from a {@link HostAndPort} object. + * + * @param hostAndPort The Consul agent host and port. + * @return The builder. + */ + public Builder withHostAndPort(HostAndPort hostAndPort) { + try { + this.url = new URL("http", hostAndPort.getHostText(), hostAndPort.getPort(), ""); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + + return this; + } + + /** + * Sets the URL from a string. + * + * @param url The Consul agent URL. + * @return The builder. + */ + public Builder withUrl(String url) { + try { + this.url = new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + + return this; + } + + /** + * Sets the {@link SSLContext} for the client. + * + * @param sslContext The SSL context for HTTPS agents. + * @return The builder. + */ + public Builder withSslContext(SSLContext sslContext) { + this.sslContext = Optional.of(sslContext); + + return this; + } + + /** + * Sets the {@link ObjectMapper} for the client. + * + * @param objectMapper The {@link ObjectMapper} to use. + * @return The builder. + */ + public Builder withObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + + objectMapper.registerModule(new GuavaModule()); + + return this; + } + + /** + * Sets the JAX-RS {@link ClientBuilder} to use. + * + * @param clientBuilder The JAX-RS builder. + * @return This builder. + */ + public Builder withClientBuilder(ClientBuilder clientBuilder) { + this.clientBuilder = clientBuilder; + + return this; + } + + /** + * Constructs a new {@link Consul} client. + * + * @return A new Consul client. + */ + public Consul build() { + if (this.sslContext.isPresent()) { + this.clientBuilder.sslContext(this.sslContext.get()); + } + + return new Consul(this.url.toExternalForm(), this.clientBuilder, this.objectMapper); + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java new file mode 100644 index 0000000..ce08ac9 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java @@ -0,0 +1,42 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul; + +/** + * Wraps an exception thrown whilst interacting with the Consul API. + */ +public class ConsulException extends RuntimeException { + + /** + * Constructs an instance of this class. + * + * @param message The exception message. + */ + public ConsulException(String message) { + super(message); + } + + /** + * Constructs an instance of this class. + * + * @param message The exception message. + * @param throwable The wrapped {@link java.lang.Throwable} object. + */ + public ConsulException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java new file mode 100644 index 0000000..1d4c00a --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java @@ -0,0 +1,247 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul; + +import static org.openo.msb.wrapper.consul.util.ClientUtil.response; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.model.health.ServiceHealth; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +/** + * HTTP Client for /v1/health/ endpoints. + */ +public class HealthClient { + + + private static final GenericType> TYPE_SERVICE_HEALTH_LIST = + new GenericType>() {}; + + private final WebTarget webTarget; + + /** + * Constructs an instance of this class. + * + * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. + */ + HealthClient(WebTarget webTarget) { + this.webTarget = webTarget; + } + + + + /** + * Retrieves the healthchecks for all healthy service instances. + * + * GET /v1/health/service/{service}?passing + * + * @param service The service to query. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getHealthyServiceInstances(String service) { + return getHealthyServiceInstances(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all healthy service instances in a given datacenter. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getHealthyServiceInstances(String service, CatalogOptions catalogOptions) { + return getHealthyServiceInstances(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all healthy service instances with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?passing + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getHealthyServiceInstances(String service, QueryOptions queryOptions) { + return getHealthyServiceInstances(service, null, queryOptions); + } + + /** + * Retrieves the healthchecks for all healthy service instances in a given datacenter with + * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getHealthyServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service).queryParam("passing", "true"), + catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST); + } + + /** + * Asynchronously retrieves the healthchecks for all healthy service instances in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * Experimental. + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getHealthyServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions, + ConsulResponseCallback> callback) { + response(webTarget.path("service").path(service).queryParam("passing", "true"), + catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Asynchronously retrieves the healthchecks for all healthy service instances in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * Experimental. + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getHealthyServiceInstances(String service, QueryOptions queryOptions, + ConsulResponseCallback> callback) { + response(webTarget.path("service").path(service).queryParam("passing", "true"), + CatalogOptions.BLANK, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Retrieves the healthchecks for all nodes. + * + * GET /v1/health/service/{service} + * + * @param service The service to query. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getAllServiceInstances(String service) { + return getAllServiceInstances(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all nodes in a given datacenter. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getAllServiceInstances(String service, CatalogOptions catalogOptions) { + return getAllServiceInstances(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service} + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getAllServiceInstances(String service, QueryOptions queryOptions) { + return getAllServiceInstances(service, null, queryOptions); + } + + /** + * Retrieves the healthchecks for all nodes in a given datacenter with + * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse> getAllServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_SERVICE_HEALTH_LIST); + } + + /** + * Asynchronously retrieves the healthchecks for all nodes in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * Experimental. + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getAllServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions, + ConsulResponseCallback> callback) { + response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Asynchronously retrieves the healthchecks for all nodes in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * Experimental. + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getAllServiceInstances(String service, QueryOptions queryOptions, + ConsulResponseCallback> callback) { + response(webTarget.path("service").path(service), CatalogOptions.BLANK, + queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java new file mode 100644 index 0000000..1db3cc5 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java @@ -0,0 +1,42 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.async; + +import org.openo.msb.wrapper.consul.model.ConsulResponse; + +/** + * For API calls that support long-polling, this callback is used to handle + * the result on success or failure for an async HTTP call. + * + * @param The Response type. + */ +public interface ConsulResponseCallback { + + /** + * Callback for a successful {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. + * + * @param consulResponse The Consul response. + */ + void onComplete(ConsulResponse consulResponse); + + /** + * Callback for an unsuccessful request. + * + * @param throwable The exception thrown. + */ + void onFailure(Throwable throwable); +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java new file mode 100644 index 0000000..8cafab4 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java @@ -0,0 +1,70 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.cache; + +import java.math.BigInteger; +import java.util.List; + +import org.openo.msb.wrapper.consul.CatalogClient; +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.catalog.CatalogService; + +import com.google.common.base.Function; + +public class CatalogCache extends ConsulCache{ + + private final String serviceName; + + private CatalogCache(Function keyConversion, + ConsulCache.CallbackConsumer callbackConsumer,String serviceName) { + super(keyConversion, callbackConsumer); + this.serviceName=serviceName; + // TODO Auto-generated constructor stub + } + + + public static CatalogCache newCache( + final CatalogClient catalogClient, + final String serviceName, + final int watchSeconds){ + Function keyExtractor = new Function() { + @Override + public String apply(CatalogService input) { + //return input.getKey().substring(rootPath.length() + 1); + return input.getServiceId(); + } + }; + + final CallbackConsumer callbackConsumer = new CallbackConsumer() { + @Override + public void consume(BigInteger index, ConsulResponseCallback> callback) { + catalogClient.getService(serviceName, watchParams(index, watchSeconds),callback); + } + }; + + + return new CatalogCache(keyExtractor, callbackConsumer,serviceName); + + + } + + public String getServiceName(){ + return this.serviceName; + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java new file mode 100644 index 0000000..e7494fa --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java @@ -0,0 +1,230 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.cache; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.option.QueryOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static com.google.common.base.Preconditions.checkState; + +/** + * A cache structure that can provide an up-to-date read-only + * map backed by consul data + * + * @param + */ +public class ConsulCache { + + enum State {latent, starting, started, stopped } + + private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache.class); + + private final AtomicReference latestIndex = new AtomicReference(null); + private final AtomicReference> lastResponse = new AtomicReference>(ImmutableMap.of()); + private final AtomicReference state = new AtomicReference(State.latent); + private final CountDownLatch initLatch = new CountDownLatch(1); + private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList>(); + + private final Function keyConversion; + private final CallbackConsumer callBackConsumer; + private final ConsulResponseCallback> responseCallback; + + ConsulCache( + Function keyConversion, + CallbackConsumer callbackConsumer) { + this(keyConversion, callbackConsumer, 10, TimeUnit.SECONDS); + } + + ConsulCache( + Function keyConversion, + CallbackConsumer callbackConsumer, + final long backoffDelayQty, + final TimeUnit backoffDelayUnit) { + + this.keyConversion = keyConversion; + this.callBackConsumer = callbackConsumer; + + this.responseCallback = new ConsulResponseCallback>() { + @Override + public void onComplete(ConsulResponse> consulResponse) { + + if (!isRunning()) { + return; + } + updateIndex(consulResponse); + ImmutableMap full = convertToMap(consulResponse); + + boolean changed = !full.equals(lastResponse.get()); +// LOGGER.info("node changed:"+changed+"----"+full); + if (changed) { + // changes + lastResponse.set(full); + } + + if (changed) { + for (Listener l : listeners) { + l.notify(full); + } + } + + if (state.compareAndSet(State.starting, State.started)) { + initLatch.countDown(); + } + runCallback(); + } + + @Override + public void onFailure(Throwable throwable) { + + if (!isRunning()) { + return; + } + LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable); + + executorService.schedule(new Runnable() { + @Override + public void run() { + runCallback(); + } + }, backoffDelayQty, backoffDelayUnit); + } + }; + } + + public void start() throws Exception { + checkState(state.compareAndSet(State.latent, State.starting),"Cannot transition from state %s to %s", state.get(), State.starting); + runCallback(); + } + + public void stop() throws Exception { + State previous = state.getAndSet(State.stopped); + if (previous != State.stopped) { + executorService.shutdownNow(); + } + } + + private void runCallback() { + if (isRunning()) { + callBackConsumer.consume(latestIndex.get(), responseCallback); + } + } + + private boolean isRunning() { + return state.get() == State.started || state.get() == State.starting; + } + + public boolean awaitInitialized(long timeout, TimeUnit unit) throws InterruptedException { + return initLatch.await(timeout, unit); + } + + public ImmutableMap getMap() { + return lastResponse.get(); + } + + @VisibleForTesting + ImmutableMap convertToMap(final ConsulResponse> response) { + if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) { + return ImmutableMap.of(); + } + + final ImmutableMap.Builder builder = ImmutableMap.builder(); + final Set keySet = new HashSet<>(); + for (final V v : response.getResponse()) { + final K key = keyConversion.apply(v); + if (key != null) { + if (!keySet.contains(key)) { + builder.put(key, v); + } else { + System.out.println(key.toString()); + LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString()); + } + } + keySet.add(key); + } + return builder.build(); + } + + private void updateIndex(ConsulResponse> consulResponse) { + if (consulResponse != null && consulResponse.getIndex() != null) { + this.latestIndex.set(consulResponse.getIndex()); + } + } + + protected static QueryOptions watchParams(BigInteger index, int blockSeconds) { + if (index == null) { + return QueryOptions.BLANK; + } else { + return QueryOptions.blockSeconds(blockSeconds, index).build(); + } + } + + /** + * passed in by creators to vary the content of the cached values + * + * @param + */ + protected interface CallbackConsumer { + void consume(BigInteger index, ConsulResponseCallback> callback); + } + + /** + * Implementers can register a listener to receive + * a new map when it changes + * + * @param + */ + public interface Listener { + void notify(Map newValues); + } + + public boolean addListener(Listener listener) { + boolean added = listeners.add(listener); + if (state.get() == State.started) { + listener.notify(lastResponse.get()); + } + return added; + } + + public boolean removeListener(Listener listener) { + return listeners.remove(listener); + } + + @VisibleForTesting + protected State getState() { + return state.get(); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java new file mode 100644 index 0000000..84fd8ec --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java @@ -0,0 +1,258 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.cache; + + +import static com.google.common.base.Preconditions.checkState; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.model.catalog.CatalogService; +import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; +import org.openo.msb.wrapper.consul.option.QueryOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; + +/** + * A cache structure that can provide an up-to-date read-only + * map backed by consul data + * + * @param + */ +public class ConsulCache4Map { + + enum State {latent, starting, started, stopped } + + private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache4Map.class); + + private final AtomicReference latestIndex = new AtomicReference(null); + private final AtomicReference> lastResponse = new AtomicReference>(ImmutableList.of()); + private final AtomicReference state = new AtomicReference(State.latent); + private final CountDownLatch initLatch = new CountDownLatch(1); + private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList>(); + + private final CallbackConsumer callBackConsumer; + private final ConsulResponseCallback>> responseCallback; + + ConsulCache4Map(CallbackConsumer callbackConsumer) { + this( callbackConsumer, 10, TimeUnit.SECONDS); + } + + ConsulCache4Map( + CallbackConsumer callbackConsumer, + final long backoffDelayQty, + final TimeUnit backoffDelayUnit) { + + this.callBackConsumer = callbackConsumer; + + this.responseCallback = new ConsulResponseCallback>>() { + @Override + public void onComplete(ConsulResponse>> consulResponse) { + + if (!isRunning()) { + return; + } + updateIndex(consulResponse); + ImmutableList full = convertToList(consulResponse); + List oldList=lastResponse.get(); + boolean changed = !full.equals(lastResponse.get()); +// LOGGER.info("service changed:"+changed+"----"+full); + if (changed) { + // changes + lastResponse.set(full); + } + + if (changed) { + for (Listener l : listeners) { + l.notify(oldList,full); + } + } + + if (state.compareAndSet(State.starting, State.started)) { + initLatch.countDown(); + } + runCallback(); + } + + @Override + public void onFailure(Throwable throwable) { + + if (!isRunning()) { + return; + } + LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable); + + executorService.schedule(new Runnable() { + @Override + public void run() { + runCallback(); + } + }, backoffDelayQty, backoffDelayUnit); + } + }; + } + + public void start() throws Exception { + checkState(state.compareAndSet(State.latent, State.starting),"Cannot transition from state %s to %s", state.get(), State.starting); + runCallback(); + } + + public void stop() throws Exception { + State previous = state.getAndSet(State.stopped); + if (previous != State.stopped) { + executorService.shutdownNow(); + } + } + + private void runCallback() { + if (isRunning()) { + callBackConsumer.consume(latestIndex.get(), responseCallback); + } + } + + private boolean isRunning() { + return state.get() == State.started || state.get() == State.starting; + } + + public boolean awaitInitialized(long timeout, TimeUnit unit) throws InterruptedException { + return initLatch.await(timeout, unit); + } + + public ImmutableList getMap() { + return lastResponse.get(); + } + + @VisibleForTesting + ImmutableList convertToList(final ConsulResponse>> response) { + if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) { + return ImmutableList.of(); + } + + final ImmutableList.Builder builder = ImmutableList.builder(); + final Set keySet = new HashSet<>(); + + for(Map.Entry> entry : response.getResponse().entrySet()) { + + String key = entry.getKey(); + + if (key != null && !"consul".equals(key)) { + if (!keySet.contains(key)) { + ServiceInfo serviceInfo=new ServiceInfo(); + serviceInfo.setServiceName(key); + + List value=entry.getValue(); + for(String tag:value){ + + if(tag.startsWith("version")){ + String version; + if(tag.split(":").length==2) + { + version = tag.split(":")[1]; + } + else{ + version=""; + } + + serviceInfo.setVersion(version); + break; + } + } + + builder.add(serviceInfo); + } else { + System.out.println(key.toString()); + LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString()); + } + } + keySet.add(key); + + } + + + return builder.build(); + } + + private void updateIndex(ConsulResponse>> consulResponse) { + if (consulResponse != null && consulResponse.getIndex() != null) { + this.latestIndex.set(consulResponse.getIndex()); + } + } + + protected static QueryOptions watchParams(BigInteger index, int blockSeconds) { + if (index == null) { + return QueryOptions.BLANK; + } else { + return QueryOptions.blockSeconds(blockSeconds, index).build(); + } + } + + /** + * passed in by creators to vary the content of the cached values + * + * @param + */ + protected interface CallbackConsumer { + void consume(BigInteger index, ConsulResponseCallback>> callback); + } + + /** + * Implementers can register a listener to receive + * a new map when it changes + * + * @param + */ + public interface Listener { + void notify(List oldValues,List newValues); + } + + public boolean addListener(Listener listener) { + boolean added = listeners.add(listener); + if (state.get() == State.started) { + listener.notify(lastResponse.get(),lastResponse.get()); + } + return added; + } + + public boolean removeListener(Listener listener) { + return listeners.remove(listener); + } + + @VisibleForTesting + protected State getState() { + return state.get(); + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java new file mode 100644 index 0000000..0134eeb --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java @@ -0,0 +1,70 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.cache; + +import java.math.BigInteger; +import java.util.List; + +import org.openo.msb.wrapper.consul.HealthClient; +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.health.ServiceHealth; + +import com.google.common.base.Function; + +public class HealthCache extends ConsulCache{ + + private final String serviceName; + + private HealthCache(Function keyConversion, + ConsulCache.CallbackConsumer callbackConsumer,String serviceName) { + super(keyConversion, callbackConsumer); + this.serviceName=serviceName; + // TODO Auto-generated constructor stub + } + + + public static HealthCache newCache( + final HealthClient healthClient, + final String serviceName, + final int watchSeconds){ + Function keyExtractor = new Function() { + @Override + public String apply(ServiceHealth input) { + //return input.getKey().substring(rootPath.length() + 1); + return input.getService().getId(); + } + }; + + final CallbackConsumer callbackConsumer = new CallbackConsumer() { + @Override + public void consume(BigInteger index, ConsulResponseCallback> callback) { + healthClient.getHealthyServiceInstances(serviceName, watchParams(index, watchSeconds),callback); + } + }; + + + return new HealthCache(keyExtractor, callbackConsumer,serviceName); + + + } + + public String getServiceName(){ + return this.serviceName; + } + + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java new file mode 100644 index 0000000..80cdb7b --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java @@ -0,0 +1,50 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.cache; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import org.openo.msb.wrapper.consul.CatalogClient; +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; + +public class ServiceCache extends ConsulCache4Map>> { + private ServiceCache( ConsulCache4Map.CallbackConsumer>> callbackConsumer) { + super(callbackConsumer); + // TODO Auto-generated constructor stub + } + + + public static ServiceCache newCache( + final CatalogClient catalogClient, + final int watchSeconds){ + + + final CallbackConsumer>> callbackConsumer = new CallbackConsumer>>() { + @Override + public void consume(BigInteger index, ConsulResponseCallback>> callback) { + catalogClient.getService(watchParams(index, watchSeconds),callback); + } + }; + + + return new ServiceCache(callbackConsumer); + + + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java new file mode 100644 index 0000000..7d3b2e2 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java @@ -0,0 +1,80 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model; + +import com.google.common.base.Objects; + +import java.math.BigInteger; + +public class ConsulResponse { + + private final T response; + private final long lastContact; + private final boolean knownLeader; + private final BigInteger index; + + public ConsulResponse(T response, long lastContact, boolean knownLeader, BigInteger index) { + this.response = response; + this.lastContact = lastContact; + this.knownLeader = knownLeader; + this.index = index; + } + + public T getResponse() { + return response; + } + + public long getLastContact() { + return lastContact; + } + + public boolean isKnownLeader() { + return knownLeader; + } + + public BigInteger getIndex() { + return index; + } + + @Override + public String toString() { + return "ConsulResponse{" + + "response=" + response + + ", lastContact=" + lastContact + + ", knownLeader=" + knownLeader + + ", index=" + index + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConsulResponse that = (ConsulResponse) o; + + return Objects.equal(this.response, that.response) && + Objects.equal(this.lastContact, that.lastContact) && + Objects.equal(this.knownLeader, that.knownLeader) && + Objects.equal(this.index, that.index); + } + + @Override + public int hashCode() { + return Objects.hashCode(response, lastContact, knownLeader, index); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java new file mode 100644 index 0000000..1221c08 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java @@ -0,0 +1,41 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.catalog; + +import java.util.Map; + +import org.openo.msb.wrapper.consul.model.health.Node; +import org.openo.msb.wrapper.consul.model.health.Service; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableCatalogNode.class) +@JsonDeserialize(as = ImmutableCatalogNode.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class CatalogNode { + + @JsonProperty("Node") + public abstract Node getNode(); + + @JsonProperty("Services") + public abstract Map getServices(); + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java new file mode 100644 index 0000000..5951fa7 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java @@ -0,0 +1,52 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.catalog; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableCatalogService.class) +@JsonDeserialize(as = ImmutableCatalogService.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class CatalogService { + + @JsonProperty("Node") + public abstract String getNode(); + + @JsonProperty("Address") + public abstract String getAddress(); + + @JsonProperty("ServiceName") + public abstract String getServiceName(); + + @JsonProperty("ServiceID") + public abstract String getServiceId(); + + @JsonProperty("ServiceAddress") + public abstract String getServiceAddress(); + + @JsonProperty("ServicePort") + public abstract int getServicePort(); + + @JsonProperty("ServiceTags") + public abstract List getServiceTags(); +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java new file mode 100644 index 0000000..f504168 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java @@ -0,0 +1,306 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.catalog; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Generated; + +import org.openo.msb.wrapper.consul.model.health.Node; +import org.openo.msb.wrapper.consul.model.health.Service; + +/** + * Immutable implementation of {@link CatalogNode}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableCatalogNode.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "CatalogNode"}) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ImmutableCatalogNode extends CatalogNode { + private final Node node; + private final ImmutableMap services; + + private ImmutableCatalogNode( + Node node, + ImmutableMap services) { + this.node = node; + this.services = services; + } + + /** + * @return The value of the {@code node} attribute + */ + @JsonProperty(value = "Node") + @Override + public Node getNode() { + return node; + } + + /** + * @return The value of the {@code services} attribute + */ + @JsonProperty(value = "Services") + @Override + public ImmutableMap getServices() { + return services; + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogNode#getNode() node} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for node + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogNode withNode(Node value) { + if (this.node == value) return this; + return new ImmutableCatalogNode(Preconditions.checkNotNull(value, "node"), this.services); + } + + /** + * Copy the current immutable object by replacing the {@link CatalogNode#getServices() services} map with the specified map. + * Nulls are not permitted as keys or values. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param entries The entries to be added to the services map + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogNode withServices(Map entries) { + if (this.services == entries) return this; + ImmutableMap value = ImmutableMap.copyOf(entries); + return new ImmutableCatalogNode(this.node, value); + } + + /** + * This instance is equal to all instances of {@code ImmutableCatalogNode} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableCatalogNode + && equalTo((ImmutableCatalogNode) another); + } + + private boolean equalTo(ImmutableCatalogNode another) { + return node.equals(another.node) + && services.equals(another.services); + } + + /** + * Computes a hash code from attributes: {@code node}, {@code services}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + node.hashCode(); + h = h * 17 + services.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code CatalogNode...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("CatalogNode") + .add("node", node) + .add("services", services) + .toString(); + } + + /** + * Utility type used to correctly read immutable object from JSON representation. + * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonDeserialize + static final class Json extends CatalogNode { + Node node; + Map services; + @JsonProperty(value = "Node") + public void setNode(Node node) { + this.node = node; + } + @JsonProperty(value = "Services") + public void setServices(Map services) { + this.services = services; + } + @Override + public Node getNode() { throw new UnsupportedOperationException(); } + @Override + public Map getServices() { throw new UnsupportedOperationException(); } + } + + /** + * @param json A JSON-bindable data structure + * @return An immutable value type + * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonCreator + static ImmutableCatalogNode fromJson(Json json) { + ImmutableCatalogNode.Builder builder = ImmutableCatalogNode.builder(); + if (json.node != null) { + builder.node(json.node); + } + if (json.services != null) { + builder.putAllServices(json.services); + } + return builder.build(); + } + + /** + * Creates an immutable copy of a {@link CatalogNode} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable CatalogNode instance + */ + public static ImmutableCatalogNode copyOf(CatalogNode instance) { + if (instance instanceof ImmutableCatalogNode) { + return (ImmutableCatalogNode) instance; + } + return ImmutableCatalogNode.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableCatalogNode ImmutableCatalogNode}. + * @return A new ImmutableCatalogNode builder + */ + public static ImmutableCatalogNode.Builder builder() { + return new ImmutableCatalogNode.Builder(); + } + + /** + * Builds instances of type {@link ImmutableCatalogNode ImmutableCatalogNode}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_NODE = 0x1L; + private long initBits = 0x1; + + private Node node; + private ImmutableMap.Builder servicesBuilder = ImmutableMap.builder(); + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code CatalogNode} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(CatalogNode instance) { + Preconditions.checkNotNull(instance, "instance"); + node(instance.getNode()); + putAllServices(instance.getServices()); + return this; + } + + /** + * Initializes the value for the {@link CatalogNode#getNode() node} attribute. + * @param node The value for node + * @return {@code this} builder for use in a chained invocation + */ + public final Builder node(Node node) { + this.node = Preconditions.checkNotNull(node, "node"); + initBits &= ~INIT_BIT_NODE; + return this; + } + + /** + * Put one entry to the {@link CatalogNode#getServices() services} map. + * @param key The key in the services map + * @param value The associated value in the services map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putServices(String key, Service value) { + servicesBuilder.put(key, value); + return this; + } + + /** + * Put one entry to the {@link CatalogNode#getServices() services} map. Nulls are not permitted + * @param entry The key and value entry + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putServices(Map.Entry entry) { + servicesBuilder.put(entry); + return this; + } + + /** + * Sets or replaces all mappings from the specified map as entries for the {@link CatalogNode#getServices() services} map. Nulls are not permitted + * @param entries The entries that will be added to the services map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder services(Map entries) { + servicesBuilder = ImmutableMap.builder(); + return putAllServices(entries); + } + + /** + * Put all mappings from the specified map as entries to {@link CatalogNode#getServices() services} map. Nulls are not permitted + * @param entries The entries that will be added to the services map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putAllServices(Map entries) { + servicesBuilder.putAll(entries); + return this; + } + + /** + * Builds a new {@link ImmutableCatalogNode ImmutableCatalogNode}. + * @return An immutable instance of CatalogNode + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableCatalogNode build() throws IllegalStateException { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableCatalogNode(node, servicesBuilder.build()); + } + + private String formatRequiredAttributesMessage() { + List attributes = Lists.newArrayList(); + if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); + return "Cannot build CatalogNode, some of required attributes are not set " + attributes; + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java new file mode 100644 index 0000000..33d0e03 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java @@ -0,0 +1,626 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.catalog; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import java.util.List; +import javax.annotation.Generated; + +/** + * Immutable implementation of {@link CatalogService}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableCatalogService.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "CatalogService"}) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ImmutableCatalogService extends CatalogService { + private final String node; + private final String address; + private final String serviceName; + private final String serviceId; + private final String serviceAddress; + private final int servicePort; + private final ImmutableList serviceTags; + + private ImmutableCatalogService( + String node, + String address, + String serviceName, + String serviceId, + String serviceAddress, + int servicePort, + ImmutableList serviceTags) { + this.node = node; + this.address = address; + this.serviceName = serviceName; + this.serviceId = serviceId; + this.serviceAddress = serviceAddress; + this.servicePort = servicePort; + this.serviceTags = serviceTags; + } + + /** + * @return The value of the {@code node} attribute + */ + @JsonProperty(value = "Node") + @Override + public String getNode() { + return node; + } + + /** + * @return The value of the {@code address} attribute + */ + @JsonProperty(value = "Address") + @Override + public String getAddress() { + return address; + } + + /** + * @return The value of the {@code serviceName} attribute + */ + @JsonProperty(value = "ServiceName") + @Override + public String getServiceName() { + return serviceName; + } + + /** + * @return The value of the {@code serviceId} attribute + */ + @JsonProperty(value = "ServiceID") + @Override + public String getServiceId() { + return serviceId; + } + + /** + * @return The value of the {@code serviceAddress} attribute + */ + @JsonProperty(value = "ServiceAddress") + @Override + public String getServiceAddress() { + return serviceAddress; + } + + /** + * @return The value of the {@code servicePort} attribute + */ + @JsonProperty(value = "ServicePort") + @Override + public int getServicePort() { + return servicePort; + } + + /** + * @return The value of the {@code serviceTags} attribute + */ + @JsonProperty(value = "ServiceTags") + @Override + public ImmutableList getServiceTags() { + return serviceTags; + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getNode() node} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for node + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withNode(String value) { + if (this.node.equals(value)) return this; + return new ImmutableCatalogService( + Preconditions.checkNotNull(value, "node"), + this.address, + this.serviceName, + this.serviceId, + this.serviceAddress, + this.servicePort, + this.serviceTags); + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getAddress() address} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for address + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withAddress(String value) { + if (this.address.equals(value)) return this; + return new ImmutableCatalogService( + this.node, + Preconditions.checkNotNull(value, "address"), + this.serviceName, + this.serviceId, + this.serviceAddress, + this.servicePort, + this.serviceTags); + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceName() serviceName} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for serviceName + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withServiceName(String value) { + if (this.serviceName.equals(value)) return this; + return new ImmutableCatalogService( + this.node, + this.address, + Preconditions.checkNotNull(value, "serviceName"), + this.serviceId, + this.serviceAddress, + this.servicePort, + this.serviceTags); + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceId() serviceId} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for serviceId + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withServiceId(String value) { + if (this.serviceId.equals(value)) return this; + return new ImmutableCatalogService( + this.node, + this.address, + this.serviceName, + Preconditions.checkNotNull(value, "serviceId"), + this.serviceAddress, + this.servicePort, + this.serviceTags); + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for serviceAddress + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withServiceAddress(String value) { + if (this.serviceAddress.equals(value)) return this; + return new ImmutableCatalogService( + this.node, + this.address, + this.serviceName, + this.serviceId, + Preconditions.checkNotNull(value, "serviceAddress"), + this.servicePort, + this.serviceTags); + } + + /** + * Copy the current immutable object by setting a value for the {@link CatalogService#getServicePort() servicePort} attribute. + * A value equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for servicePort + * @return A modified copy of the {@code this} object + */ + public final ImmutableCatalogService withServicePort(int value) { + if (this.servicePort == value) return this; + return new ImmutableCatalogService( + this.node, + this.address, + this.serviceName, + this.serviceId, + this.serviceAddress, + value, + this.serviceTags); + } + + /** + * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}. + * @param elements The elements to set + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogService withServiceTags(String... elements) { + ImmutableList newValue = ImmutableList.copyOf(elements); + return new ImmutableCatalogService( + this.node, + this.address, + this.serviceName, + this.serviceId, + this.serviceAddress, + this.servicePort, + newValue); + } + + /** + * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param elements An iterable of serviceTags elements to set + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogService withServiceTags(Iterable elements) { + if (this.serviceTags == elements) return this; + ImmutableList newValue = ImmutableList.copyOf(elements); + return new ImmutableCatalogService( + this.node, + this.address, + this.serviceName, + this.serviceId, + this.serviceAddress, + this.servicePort, + newValue); + } + + /** + * This instance is equal to all instances of {@code ImmutableCatalogService} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableCatalogService + && equalTo((ImmutableCatalogService) another); + } + + private boolean equalTo(ImmutableCatalogService another) { + return node.equals(another.node) + && address.equals(another.address) + && serviceName.equals(another.serviceName) + && serviceId.equals(another.serviceId) + && serviceAddress.equals(another.serviceAddress) + && servicePort == another.servicePort + && serviceTags.equals(another.serviceTags); + } + + /** + * Computes a hash code from attributes: {@code node}, {@code address}, {@code serviceName}, {@code serviceId}, {@code serviceAddress}, {@code servicePort}, {@code serviceTags}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + node.hashCode(); + h = h * 17 + address.hashCode(); + h = h * 17 + serviceName.hashCode(); + h = h * 17 + serviceId.hashCode(); + h = h * 17 + serviceAddress.hashCode(); + h = h * 17 + servicePort; + h = h * 17 + serviceTags.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code CatalogService...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("CatalogService") + .add("node", node) + .add("address", address) + .add("serviceName", serviceName) + .add("serviceId", serviceId) + .add("serviceAddress", serviceAddress) + .add("servicePort", servicePort) + .add("serviceTags", serviceTags) + .toString(); + } + + /** + * Utility type used to correctly read immutable object from JSON representation. + * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonDeserialize + static final class Json extends CatalogService { + String node; + String address; + String serviceName; + String serviceId; + String serviceAddress; + Integer servicePort; + List serviceTags = ImmutableList.of(); + @JsonProperty(value = "Node") + public void setNode(String node) { + this.node = node; + } + @JsonProperty(value = "Address") + public void setAddress(String address) { + this.address = address; + } + @JsonProperty(value = "ServiceName") + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + @JsonProperty(value = "ServiceID") + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + @JsonProperty(value = "ServiceAddress") + public void setServiceAddress(String serviceAddress) { + this.serviceAddress = serviceAddress; + } + @JsonProperty(value = "ServicePort") + public void setServicePort(int servicePort) { + this.servicePort = servicePort; + } + @JsonProperty(value = "ServiceTags") + public void setServiceTags(List serviceTags) { + this.serviceTags = serviceTags; + } + @Override + public String getNode() { throw new UnsupportedOperationException(); } + @Override + public String getAddress() { throw new UnsupportedOperationException(); } + @Override + public String getServiceName() { throw new UnsupportedOperationException(); } + @Override + public String getServiceId() { throw new UnsupportedOperationException(); } + @Override + public String getServiceAddress() { throw new UnsupportedOperationException(); } + @Override + public int getServicePort() { throw new UnsupportedOperationException(); } + @Override + public List getServiceTags() { throw new UnsupportedOperationException(); } + } + + /** + * @param json A JSON-bindable data structure + * @return An immutable value type + * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonCreator + static ImmutableCatalogService fromJson(Json json) { + ImmutableCatalogService.Builder builder = ImmutableCatalogService.builder(); + if (json.node != null) { + builder.node(json.node); + } + if (json.address != null) { + builder.address(json.address); + } + if (json.serviceName != null) { + builder.serviceName(json.serviceName); + } + if (json.serviceId != null) { + builder.serviceId(json.serviceId); + } + if (json.serviceAddress != null) { + builder.serviceAddress(json.serviceAddress); + } + if (json.servicePort != null) { + builder.servicePort(json.servicePort); + } + if (json.serviceTags != null) { + builder.addAllServiceTags(json.serviceTags); + } + return builder.build(); + } + + /** + * Creates an immutable copy of a {@link CatalogService} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable CatalogService instance + */ + public static ImmutableCatalogService copyOf(CatalogService instance) { + if (instance instanceof ImmutableCatalogService) { + return (ImmutableCatalogService) instance; + } + return ImmutableCatalogService.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableCatalogService ImmutableCatalogService}. + * @return A new ImmutableCatalogService builder + */ + public static ImmutableCatalogService.Builder builder() { + return new ImmutableCatalogService.Builder(); + } + + /** + * Builds instances of type {@link ImmutableCatalogService ImmutableCatalogService}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_NODE = 0x1L; + private static final long INIT_BIT_ADDRESS = 0x2L; + private static final long INIT_BIT_SERVICE_NAME = 0x4L; + private static final long INIT_BIT_SERVICE_ID = 0x8L; + private static final long INIT_BIT_SERVICE_ADDRESS = 0x10L; + private static final long INIT_BIT_SERVICE_PORT = 0x20L; + private long initBits = 0x3f; + + private String node; + private String address; + private String serviceName; + private String serviceId; + private String serviceAddress; + private int servicePort; + private ImmutableList.Builder serviceTagsBuilder = ImmutableList.builder(); + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code CatalogService} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(CatalogService instance) { + Preconditions.checkNotNull(instance, "instance"); + node(instance.getNode()); + address(instance.getAddress()); + serviceName(instance.getServiceName()); + serviceId(instance.getServiceId()); + serviceAddress(instance.getServiceAddress()); + servicePort(instance.getServicePort()); + addAllServiceTags(instance.getServiceTags()); + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getNode() node} attribute. + * @param node The value for node + * @return {@code this} builder for use in a chained invocation + */ + public final Builder node(String node) { + this.node = Preconditions.checkNotNull(node, "node"); + initBits &= ~INIT_BIT_NODE; + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getAddress() address} attribute. + * @param address The value for address + * @return {@code this} builder for use in a chained invocation + */ + public final Builder address(String address) { + this.address = Preconditions.checkNotNull(address, "address"); + initBits &= ~INIT_BIT_ADDRESS; + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getServiceName() serviceName} attribute. + * @param serviceName The value for serviceName + * @return {@code this} builder for use in a chained invocation + */ + public final Builder serviceName(String serviceName) { + this.serviceName = Preconditions.checkNotNull(serviceName, "serviceName"); + initBits &= ~INIT_BIT_SERVICE_NAME; + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getServiceId() serviceId} attribute. + * @param serviceId The value for serviceId + * @return {@code this} builder for use in a chained invocation + */ + public final Builder serviceId(String serviceId) { + this.serviceId = Preconditions.checkNotNull(serviceId, "serviceId"); + initBits &= ~INIT_BIT_SERVICE_ID; + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute. + * @param serviceAddress The value for serviceAddress + * @return {@code this} builder for use in a chained invocation + */ + public final Builder serviceAddress(String serviceAddress) { + this.serviceAddress = Preconditions.checkNotNull(serviceAddress, "serviceAddress"); + initBits &= ~INIT_BIT_SERVICE_ADDRESS; + return this; + } + + /** + * Initializes the value for the {@link CatalogService#getServicePort() servicePort} attribute. + * @param servicePort The value for servicePort + * @return {@code this} builder for use in a chained invocation + */ + public final Builder servicePort(int servicePort) { + this.servicePort = servicePort; + initBits &= ~INIT_BIT_SERVICE_PORT; + return this; + } + + /** + * Adds one element to {@link CatalogService#getServiceTags() serviceTags} list. + * @param element A serviceTags element + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addServiceTags(String element) { + serviceTagsBuilder.add(element); + return this; + } + + /** + * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list. + * @param elements An array of serviceTags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addServiceTags(String... elements) { + serviceTagsBuilder.add(elements); + return this; + } + + /** + * Sets or replaces all elements for {@link CatalogService#getServiceTags() serviceTags} list. + * @param elements An iterable of serviceTags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder serviceTags(Iterable elements) { + serviceTagsBuilder = ImmutableList.builder(); + return addAllServiceTags(elements); + } + + /** + * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list. + * @param elements An iterable of serviceTags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addAllServiceTags(Iterable elements) { + serviceTagsBuilder.addAll(elements); + return this; + } + + /** + * Builds a new {@link ImmutableCatalogService ImmutableCatalogService}. + * @return An immutable instance of CatalogService + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableCatalogService build() throws IllegalStateException { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableCatalogService( + node, + address, + serviceName, + serviceId, + serviceAddress, + servicePort, + serviceTagsBuilder.build()); + } + + private String formatRequiredAttributesMessage() { + List attributes = Lists.newArrayList(); + if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); + if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); + if ((initBits & INIT_BIT_SERVICE_NAME) != 0) attributes.add("serviceName"); + if ((initBits & INIT_BIT_SERVICE_ID) != 0) attributes.add("serviceId"); + if ((initBits & INIT_BIT_SERVICE_ADDRESS) != 0) attributes.add("serviceAddress"); + if ((initBits & INIT_BIT_SERVICE_PORT) != 0) attributes.add("servicePort"); + return "Cannot build CatalogService, some of required attributes are not set " + attributes; + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java new file mode 100644 index 0000000..657af12 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java @@ -0,0 +1,63 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.catalog; + +import com.google.common.base.Objects; + +public class ServiceInfo { + + private String serviceName; + + private String version=""; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + @Override + public boolean equals(Object other) + { + if(this == other) + return true; + if(other instanceof ServiceInfo) + { + ServiceInfo that = (ServiceInfo)other; + return Objects.equal(serviceName, that.serviceName) && Objects.equal(version, that.version); + } else + { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(serviceName, version); + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java new file mode 100644 index 0000000..8499ac3 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java @@ -0,0 +1,266 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.health; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import java.util.List; +import javax.annotation.Generated; + +/** + * Immutable implementation of {@link Node}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableNode.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "Node"}) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ImmutableNode extends Node { + private final String node; + private final String address; + + private ImmutableNode(String node, String address) { + this.node = node; + this.address = address; + } + + /** + * @return The value of the {@code node} attribute + */ + @JsonProperty(value = "Node") + @Override + public String getNode() { + return node; + } + + /** + * @return The value of the {@code address} attribute + */ + @JsonProperty(value = "Address") + @Override + public String getAddress() { + return address; + } + + /** + * Copy the current immutable object by setting a value for the {@link Node#getNode() node} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for node + * @return A modified copy of the {@code this} object + */ + public final ImmutableNode withNode(String value) { + if (this.node.equals(value)) return this; + return new ImmutableNode(Preconditions.checkNotNull(value, "node"), this.address); + } + + /** + * Copy the current immutable object by setting a value for the {@link Node#getAddress() address} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for address + * @return A modified copy of the {@code this} object + */ + public final ImmutableNode withAddress(String value) { + if (this.address.equals(value)) return this; + return new ImmutableNode(this.node, Preconditions.checkNotNull(value, "address")); + } + + /** + * This instance is equal to all instances of {@code ImmutableNode} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableNode + && equalTo((ImmutableNode) another); + } + + private boolean equalTo(ImmutableNode another) { + return node.equals(another.node) + && address.equals(another.address); + } + + /** + * Computes a hash code from attributes: {@code node}, {@code address}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + node.hashCode(); + h = h * 17 + address.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Node...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("Node") + .add("node", node) + .add("address", address) + .toString(); + } + + /** + * Utility type used to correctly read immutable object from JSON representation. + * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonDeserialize + static final class Json extends Node { + String node; + String address; + @JsonProperty(value = "Node") + public void setNode(String node) { + this.node = node; + } + @JsonProperty(value = "Address") + public void setAddress(String address) { + this.address = address; + } + @Override + public String getNode() { throw new UnsupportedOperationException(); } + @Override + public String getAddress() { throw new UnsupportedOperationException(); } + } + + /** + * @param json A JSON-bindable data structure + * @return An immutable value type + * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonCreator + static ImmutableNode fromJson(Json json) { + ImmutableNode.Builder builder = ImmutableNode.builder(); + if (json.node != null) { + builder.node(json.node); + } + if (json.address != null) { + builder.address(json.address); + } + return builder.build(); + } + + /** + * Creates an immutable copy of a {@link Node} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable Node instance + */ + public static ImmutableNode copyOf(Node instance) { + if (instance instanceof ImmutableNode) { + return (ImmutableNode) instance; + } + return ImmutableNode.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableNode ImmutableNode}. + * @return A new ImmutableNode builder + */ + public static ImmutableNode.Builder builder() { + return new ImmutableNode.Builder(); + } + + /** + * Builds instances of type {@link ImmutableNode ImmutableNode}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_NODE = 0x1L; + private static final long INIT_BIT_ADDRESS = 0x2L; + private long initBits = 0x3; + + private String node; + private String address; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Node} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(Node instance) { + Preconditions.checkNotNull(instance, "instance"); + node(instance.getNode()); + address(instance.getAddress()); + return this; + } + + /** + * Initializes the value for the {@link Node#getNode() node} attribute. + * @param node The value for node + * @return {@code this} builder for use in a chained invocation + */ + public final Builder node(String node) { + this.node = Preconditions.checkNotNull(node, "node"); + initBits &= ~INIT_BIT_NODE; + return this; + } + + /** + * Initializes the value for the {@link Node#getAddress() address} attribute. + * @param address The value for address + * @return {@code this} builder for use in a chained invocation + */ + public final Builder address(String address) { + this.address = Preconditions.checkNotNull(address, "address"); + initBits &= ~INIT_BIT_ADDRESS; + return this; + } + + /** + * Builds a new {@link ImmutableNode ImmutableNode}. + * @return An immutable instance of Node + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableNode build() throws IllegalStateException { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableNode(node, address); + } + + private String formatRequiredAttributesMessage() { + List attributes = Lists.newArrayList(); + if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); + if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); + return "Cannot build Node, some of required attributes are not set " + attributes; + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java new file mode 100644 index 0000000..70eabf2 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java @@ -0,0 +1,478 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.health; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import java.util.List; +import javax.annotation.Generated; + +/** + * Immutable implementation of {@link Service}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableService.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "Service"}) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ImmutableService extends Service { + private final String id; + private final String service; + private final ImmutableList tags; + private final String address; + private final int port; + + private ImmutableService( + String id, + String service, + ImmutableList tags, + String address, + int port) { + this.id = id; + this.service = service; + this.tags = tags; + this.address = address; + this.port = port; + } + + /** + * @return The value of the {@code id} attribute + */ + @JsonProperty(value = "ID") + @Override + public String getId() { + return id; + } + + /** + * @return The value of the {@code service} attribute + */ + @JsonProperty(value = "Service") + @Override + public String getService() { + return service; + } + + /** + * @return The value of the {@code tags} attribute + */ + @JsonProperty(value = "Tags") + @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) + @Override + public ImmutableList getTags() { + return tags; + } + + /** + * @return The value of the {@code address} attribute + */ + @JsonProperty(value = "Address") + @Override + public String getAddress() { + return address; + } + + /** + * @return The value of the {@code port} attribute + */ + @JsonProperty(value = "Port") + @Override + public int getPort() { + return port; + } + + /** + * Copy the current immutable object by setting a value for the {@link Service#getId() id} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for id + * @return A modified copy of the {@code this} object + */ + public final ImmutableService withId(String value) { + if (this.id.equals(value)) return this; + return new ImmutableService( + Preconditions.checkNotNull(value, "id"), + this.service, + this.tags, + this.address, + this.port); + } + + /** + * Copy the current immutable object by setting a value for the {@link Service#getService() service} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for service + * @return A modified copy of the {@code this} object + */ + public final ImmutableService withService(String value) { + if (this.service.equals(value)) return this; + return new ImmutableService( + this.id, + Preconditions.checkNotNull(value, "service"), + this.tags, + this.address, + this.port); + } + + /** + * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}. + * @param elements The elements to set + * @return A modified copy of {@code this} object + */ + public final ImmutableService withTags(String... elements) { + ImmutableList newValue = ImmutableList.copyOf(elements); + return new ImmutableService(this.id, this.service, newValue, this.address, this.port); + } + + /** + * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param elements An iterable of tags elements to set + * @return A modified copy of {@code this} object + */ + public final ImmutableService withTags(Iterable elements) { + if (this.tags == elements) return this; + ImmutableList newValue = ImmutableList.copyOf(elements); + return new ImmutableService(this.id, this.service, newValue, this.address, this.port); + } + + /** + * Copy the current immutable object by setting a value for the {@link Service#getAddress() address} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for address + * @return A modified copy of the {@code this} object + */ + public final ImmutableService withAddress(String value) { + if (this.address.equals(value)) return this; + return new ImmutableService( + this.id, + this.service, + this.tags, + Preconditions.checkNotNull(value, "address"), + this.port); + } + + /** + * Copy the current immutable object by setting a value for the {@link Service#getPort() port} attribute. + * A value equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for port + * @return A modified copy of the {@code this} object + */ + public final ImmutableService withPort(int value) { + if (this.port == value) return this; + return new ImmutableService(this.id, this.service, this.tags, this.address, value); + } + + /** + * This instance is equal to all instances of {@code ImmutableService} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableService + && equalTo((ImmutableService) another); + } + + private boolean equalTo(ImmutableService another) { + return id.equals(another.id) + && service.equals(another.service) + && tags.equals(another.tags) + && address.equals(another.address) + && port == another.port; + } + + /** + * Computes a hash code from attributes: {@code id}, {@code service}, {@code tags}, {@code address}, {@code port}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + id.hashCode(); + h = h * 17 + service.hashCode(); + h = h * 17 + tags.hashCode(); + h = h * 17 + address.hashCode(); + h = h * 17 + port; + return h; + } + + /** + * Prints the immutable value {@code Service...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("Service") + .add("id", id) + .add("service", service) + .add("tags", tags) + .add("address", address) + .add("port", port) + .toString(); + } + + /** + * Utility type used to correctly read immutable object from JSON representation. + * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonDeserialize + static final class Json extends Service { + String id; + String service; + List tags = ImmutableList.of(); + String address; + Integer port; + @JsonProperty(value = "ID") + public void setId(String id) { + this.id = id; + } + @JsonProperty(value = "Service") + public void setService(String service) { + this.service = service; + } + @JsonProperty(value = "Tags") + @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) + public void setTags(List tags) { + this.tags = tags; + } + @JsonProperty(value = "Address") + public void setAddress(String address) { + this.address = address; + } + @JsonProperty(value = "Port") + public void setPort(int port) { + this.port = port; + } + @Override + public String getId() { throw new UnsupportedOperationException(); } + @Override + public String getService() { throw new UnsupportedOperationException(); } + @Override + public List getTags() { throw new UnsupportedOperationException(); } + @Override + public String getAddress() { throw new UnsupportedOperationException(); } + @Override + public int getPort() { throw new UnsupportedOperationException(); } + } + + /** + * @param json A JSON-bindable data structure + * @return An immutable value type + * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure + */ + @Deprecated + @JsonCreator + static ImmutableService fromJson(Json json) { + ImmutableService.Builder builder = ImmutableService.builder(); + if (json.id != null) { + builder.id(json.id); + } + if (json.service != null) { + builder.service(json.service); + } + if (json.tags != null) { + builder.addAllTags(json.tags); + } + if (json.address != null) { + builder.address(json.address); + } + if (json.port != null) { + builder.port(json.port); + } + return builder.build(); + } + + /** + * Creates an immutable copy of a {@link Service} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable Service instance + */ + public static ImmutableService copyOf(Service instance) { + if (instance instanceof ImmutableService) { + return (ImmutableService) instance; + } + return ImmutableService.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableService ImmutableService}. + * @return A new ImmutableService builder + */ + public static ImmutableService.Builder builder() { + return new ImmutableService.Builder(); + } + + /** + * Builds instances of type {@link ImmutableService ImmutableService}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_ID = 0x1L; + private static final long INIT_BIT_SERVICE = 0x2L; + private static final long INIT_BIT_ADDRESS = 0x4L; + private static final long INIT_BIT_PORT = 0x8L; + private long initBits = 0xf; + + private String id; + private String service; + private ImmutableList.Builder tagsBuilder = ImmutableList.builder(); + private String address; + private int port; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Service} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(Service instance) { + Preconditions.checkNotNull(instance, "instance"); + id(instance.getId()); + service(instance.getService()); + addAllTags(instance.getTags()); + address(instance.getAddress()); + port(instance.getPort()); + return this; + } + + /** + * Initializes the value for the {@link Service#getId() id} attribute. + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final Builder id(String id) { + this.id = Preconditions.checkNotNull(id, "id"); + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Initializes the value for the {@link Service#getService() service} attribute. + * @param service The value for service + * @return {@code this} builder for use in a chained invocation + */ + public final Builder service(String service) { + this.service = Preconditions.checkNotNull(service, "service"); + initBits &= ~INIT_BIT_SERVICE; + return this; + } + + /** + * Adds one element to {@link Service#getTags() tags} list. + * @param element A tags element + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addTags(String element) { + tagsBuilder.add(element); + return this; + } + + /** + * Adds elements to {@link Service#getTags() tags} list. + * @param elements An array of tags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addTags(String... elements) { + tagsBuilder.add(elements); + return this; + } + + /** + * Sets or replaces all elements for {@link Service#getTags() tags} list. + * @param elements An iterable of tags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder tags(Iterable elements) { + tagsBuilder = ImmutableList.builder(); + return addAllTags(elements); + } + + /** + * Adds elements to {@link Service#getTags() tags} list. + * @param elements An iterable of tags elements + * @return {@code this} builder for use in a chained invocation + */ + public final Builder addAllTags(Iterable elements) { + tagsBuilder.addAll(elements); + return this; + } + + /** + * Initializes the value for the {@link Service#getAddress() address} attribute. + * @param address The value for address + * @return {@code this} builder for use in a chained invocation + */ + public final Builder address(String address) { + this.address = Preconditions.checkNotNull(address, "address"); + initBits &= ~INIT_BIT_ADDRESS; + return this; + } + + /** + * Initializes the value for the {@link Service#getPort() port} attribute. + * @param port The value for port + * @return {@code this} builder for use in a chained invocation + */ + public final Builder port(int port) { + this.port = port; + initBits &= ~INIT_BIT_PORT; + return this; + } + + /** + * Builds a new {@link ImmutableService ImmutableService}. + * @return An immutable instance of Service + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableService build() throws IllegalStateException { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableService(id, service, tagsBuilder.build(), address, port); + } + + private String formatRequiredAttributesMessage() { + List attributes = Lists.newArrayList(); + if ((initBits & INIT_BIT_ID) != 0) attributes.add("id"); + if ((initBits & INIT_BIT_SERVICE) != 0) attributes.add("service"); + if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); + if ((initBits & INIT_BIT_PORT) != 0) attributes.add("port"); + return "Cannot build Service, some of required attributes are not set " + attributes; + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java new file mode 100644 index 0000000..83e6632 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java @@ -0,0 +1,35 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.health; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableNode.class) +@JsonDeserialize(as = ImmutableNode.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class Node { + + @JsonProperty("Node") + public abstract String getNode(); + + @JsonProperty("Address") + public abstract String getAddress(); +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java new file mode 100644 index 0000000..379e9f1 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java @@ -0,0 +1,48 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.health; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.collect.ImmutableList; + + +@JsonSerialize(as = ImmutableService.class) +@JsonDeserialize(as = ImmutableService.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class Service { + + @JsonProperty("ID") + public abstract String getId(); + + @JsonProperty("Service") + public abstract String getService(); + + @JsonProperty("Tags") + @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) + public abstract List getTags(); + + @JsonProperty("Address") + public abstract String getAddress(); + + @JsonProperty("Port") + public abstract int getPort(); +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java new file mode 100644 index 0000000..d353b55 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java @@ -0,0 +1,73 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.model.health; + +import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Objects; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ServiceHealth { + + @JsonProperty("Node") + public Node node; + + @JsonProperty("Service") + public Service service; + + public Node getNode() { + return node; + } + + public void setNode(Node node) { + this.node = node; + } + + public Service getService() { + return service; + } + + public void setService(Service service) { + this.service = service; + } + + @Override + public boolean equals(Object other) + { + if(this == other) + return true; + if(other instanceof ServiceHealth) + { + ServiceHealth that = (ServiceHealth)other; + return Objects.equal(node, that.node) && Objects.equal(service, that.service); + } else + { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(node, service); + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java new file mode 100644 index 0000000..34972fe --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java @@ -0,0 +1,39 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; + +import javax.ws.rs.client.WebTarget; + +import com.google.common.base.Optional; + + +public abstract class CatalogOptions implements ParamAdder { + + public abstract Optional getDatacenter(); + public abstract Optional getTag(); + + public static final CatalogOptions BLANK = ImmutableCatalogOptions.builder().build(); + + @Override + public final WebTarget apply(final WebTarget input) { + WebTarget added = optionallyAdd(input, "dc", getDatacenter()); + added = optionallyAdd(added, "tag", getTag()); + return added; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java new file mode 100644 index 0000000..52afa00 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java @@ -0,0 +1,21 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +public enum ConsistencyMode { + DEFAULT, STALE, CONSISTENT +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java new file mode 100644 index 0000000..35eda18 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java @@ -0,0 +1,251 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import javax.annotation.Generated; + +/** + * Immutable implementation of {@link CatalogOptions}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableCatalogOptions.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "CatalogOptions"}) +public final class ImmutableCatalogOptions extends CatalogOptions { + private final Optional datacenter; + private final Optional tag; + + private ImmutableCatalogOptions( + Optional datacenter, + Optional tag) { + this.datacenter = datacenter; + this.tag = tag; + } + + /** + * @return The value of the {@code datacenter} attribute + */ + @Override + public Optional getDatacenter() { + return datacenter; + } + + /** + * @return The value of the {@code tag} attribute + */ + @Override + public Optional getTag() { + return tag; + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link CatalogOptions#getDatacenter() datacenter} attribute. + * @param value The value for datacenter + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogOptions withDatacenter(String value) { + Optional newValue = Optional.of(value); + return new ImmutableCatalogOptions(newValue, this.tag); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getDatacenter() datacenter} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for datacenter + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogOptions withDatacenter(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "datacenter"); + if (this.datacenter == value) return this; + return new ImmutableCatalogOptions(value, this.tag); + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link CatalogOptions#getTag() tag} attribute. + * @param value The value for tag + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogOptions withTag(String value) { + Optional newValue = Optional.of(value); + return new ImmutableCatalogOptions(this.datacenter, newValue); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getTag() tag} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for tag + * @return A modified copy of {@code this} object + */ + public final ImmutableCatalogOptions withTag(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "tag"); + if (this.tag == value) return this; + return new ImmutableCatalogOptions(this.datacenter, value); + } + + /** + * This instance is equal to all instances of {@code ImmutableCatalogOptions} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableCatalogOptions + && equalTo((ImmutableCatalogOptions) another); + } + + private boolean equalTo(ImmutableCatalogOptions another) { + return datacenter.equals(another.datacenter) + && tag.equals(another.tag); + } + + /** + * Computes a hash code from attributes: {@code datacenter}, {@code tag}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + datacenter.hashCode(); + h = h * 17 + tag.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code CatalogOptions...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("CatalogOptions") + .add("datacenter", datacenter) + .add("tag", tag) + .toString(); + } + + /** + * Creates an immutable copy of a {@link CatalogOptions} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable CatalogOptions instance + */ + public static ImmutableCatalogOptions copyOf(CatalogOptions instance) { + if (instance instanceof ImmutableCatalogOptions) { + return (ImmutableCatalogOptions) instance; + } + return ImmutableCatalogOptions.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableCatalogOptions ImmutableCatalogOptions}. + * @return A new ImmutableCatalogOptions builder + */ + public static ImmutableCatalogOptions.Builder builder() { + return new ImmutableCatalogOptions.Builder(); + } + + /** + * Builds instances of type {@link ImmutableCatalogOptions ImmutableCatalogOptions}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private Optional datacenter = Optional.absent(); + private Optional tag = Optional.absent(); + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code CatalogOptions} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(CatalogOptions instance) { + Preconditions.checkNotNull(instance, "instance"); + Optional datacenterOptional = instance.getDatacenter(); + if (datacenterOptional.isPresent()) { + datacenter(datacenterOptional); + } + Optional tagOptional = instance.getTag(); + if (tagOptional.isPresent()) { + tag(tagOptional); + } + return this; + } + + /** + * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter. + * @param datacenter The value for datacenter + * @return {@code this} builder for chained invocation + */ + public final Builder datacenter(String datacenter) { + this.datacenter = Optional.of(datacenter); + return this; + } + + /** + * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter. + * @param datacenter The value for datacenter + * @return {@code this} builder for use in a chained invocation + */ + public final Builder datacenter(Optional datacenter) { + this.datacenter = Preconditions.checkNotNull(datacenter, "datacenter"); + return this; + } + + /** + * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag. + * @param tag The value for tag + * @return {@code this} builder for chained invocation + */ + public final Builder tag(String tag) { + this.tag = Optional.of(tag); + return this; + } + + /** + * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag. + * @param tag The value for tag + * @return {@code this} builder for use in a chained invocation + */ + public final Builder tag(Optional tag) { + this.tag = Preconditions.checkNotNull(tag, "tag"); + return this; + } + + /** + * Builds a new {@link ImmutableCatalogOptions ImmutableCatalogOptions}. + * @return An immutable instance of CatalogOptions + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableCatalogOptions build() throws IllegalStateException { + return new ImmutableCatalogOptions(datacenter, tag); + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java new file mode 100644 index 0000000..87a0f8a --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java @@ -0,0 +1,531 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.primitives.Booleans; +import java.math.BigInteger; +import java.util.ArrayList; +import javax.annotation.Generated; + +/** + * Immutable implementation of {@link QueryOptions}. + *

+ * Use the builder to create immutable instances: + * {@code ImmutableQueryOptions.builder()}. + */ +@SuppressWarnings("all") +@Generated({"Immutables.generator", "QueryOptions"}) +public final class ImmutableQueryOptions extends QueryOptions { + private final Optional wait; + private final Optional token; + private final Optional index; + private final Optional near; + private final ConsistencyMode consistencyMode; + private final boolean isBlocking; + private final boolean hasToken; + + private ImmutableQueryOptions(ImmutableQueryOptions.Builder builder) { + this.wait = builder.wait; + this.token = builder.token; + this.index = builder.index; + this.near = builder.near; + if (builder.consistencyMode != null) { + initShim.consistencyMode(builder.consistencyMode); + } + this.consistencyMode = initShim.getConsistencyMode(); + this.isBlocking = initShim.isBlocking(); + this.hasToken = initShim.hasToken(); + this.initShim = null; + } + + private ImmutableQueryOptions( + Optional wait, + Optional token, + Optional index, + Optional near, + ConsistencyMode consistencyMode) { + this.wait = wait; + this.token = token; + this.index = index; + this.near = near; + this.consistencyMode = consistencyMode; + initShim.consistencyMode(consistencyMode); + this.isBlocking = initShim.isBlocking(); + this.hasToken = initShim.hasToken(); + this.initShim = null; + } + + private static final int STAGE_INITIALIZING = -1; + private static final int STAGE_UNINITIALIZED = 0; + private static final int STAGE_INITIALIZED = 1; + private volatile InitShim initShim = new InitShim(); + + private final class InitShim { + private ConsistencyMode consistencyMode; + private byte consistencyModeStage; + + ConsistencyMode getConsistencyMode() { + if (consistencyModeStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); + if (consistencyModeStage == STAGE_UNINITIALIZED) { + consistencyModeStage = STAGE_INITIALIZING; + this.consistencyMode = Preconditions.checkNotNull(ImmutableQueryOptions.super.getConsistencyMode(), "consistencyMode"); + consistencyModeStage = STAGE_INITIALIZED; + } + return consistencyMode; + } + + ConsistencyMode consistencyMode(ConsistencyMode value) { + this.consistencyMode = value; + consistencyModeStage = STAGE_INITIALIZED; + return value; + } + private boolean isBlocking; + private byte isBlockingStage; + + boolean isBlocking() { + if (isBlockingStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); + if (isBlockingStage == STAGE_UNINITIALIZED) { + isBlockingStage = STAGE_INITIALIZING; + this.isBlocking = ImmutableQueryOptions.super.isBlocking(); + isBlockingStage = STAGE_INITIALIZED; + } + return isBlocking; + } + private boolean hasToken; + private byte hasTokenStage; + + boolean hasToken() { + if (hasTokenStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); + if (hasTokenStage == STAGE_UNINITIALIZED) { + hasTokenStage = STAGE_INITIALIZING; + this.hasToken = ImmutableQueryOptions.super.hasToken(); + hasTokenStage = STAGE_INITIALIZED; + } + return hasToken; + } + + private String formatInitCycleMessage() { + ArrayList attributes = Lists.newArrayList(); + if (consistencyModeStage == STAGE_INITIALIZING) attributes.add("consistencyMode"); + if (isBlockingStage == STAGE_INITIALIZING) attributes.add("isBlocking"); + if (hasTokenStage == STAGE_INITIALIZING) attributes.add("hasToken"); + return "Cannot build QueryOptions, attribute initializers form cycle" + attributes; + } + } + + /** + * @return The value of the {@code wait} attribute + */ + @Override + public Optional getWait() { + return wait; + } + + /** + * @return The value of the {@code token} attribute + */ + @Override + public Optional getToken() { + return token; + } + + /** + * @return The value of the {@code index} attribute + */ + @Override + public Optional getIndex() { + return index; + } + + /** + * @return The value of the {@code near} attribute + */ + @Override + public Optional getNear() { + return near; + } + + /** + * @return The value of the {@code consistencyMode} attribute + */ + @Override + public ConsistencyMode getConsistencyMode() { + return initShim != null + ? initShim.getConsistencyMode() + : consistencyMode; + } + + /** + * @return The computed-at-construction value of the {@code isBlocking} attribute + */ + @Override + public boolean isBlocking() { + return initShim != null + ? initShim.isBlocking() + : isBlocking; + } + + /** + * @return The computed-at-construction value of the {@code hasToken} attribute + */ + @Override + public boolean hasToken() { + return initShim != null + ? initShim.hasToken() + : hasToken; + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getWait() wait} attribute. + * @param value The value for wait + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withWait(String value) { + Optional newValue = Optional.of(value); + return validate(new ImmutableQueryOptions(newValue, this.token, this.index, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getWait() wait} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for wait + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withWait(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "wait"); + if (this.wait == value) return this; + return validate(new ImmutableQueryOptions(value, this.token, this.index, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getToken() token} attribute. + * @param value The value for token + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withToken(String value) { + Optional newValue = Optional.of(value); + return validate(new ImmutableQueryOptions(this.wait, newValue, this.index, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getToken() token} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for token + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withToken(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "token"); + if (this.token == value) return this; + return validate(new ImmutableQueryOptions(this.wait, value, this.index, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getIndex() index} attribute. + * @param value The value for index + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withIndex(BigInteger value) { + Optional newValue = Optional.of(value); + return validate(new ImmutableQueryOptions(this.wait, this.token, newValue, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getIndex() index} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for index + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withIndex(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "index"); + if (this.index == value) return this; + return validate(new ImmutableQueryOptions(this.wait, this.token, value, this.near, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getNear() near} attribute. + * @param value The value for near + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withNear(String value) { + Optional newValue = Optional.of(value); + return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, newValue, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getNear() near} attribute. + * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. + * @param optional A value for near + * @return A modified copy of {@code this} object + */ + public final ImmutableQueryOptions withNear(Optional optional) { + Optional value = Preconditions.checkNotNull(optional, "near"); + if (this.near == value) return this; + return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, value, this.consistencyMode)); + } + + /** + * Copy the current immutable object by setting a value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for consistencyMode + * @return A modified copy of the {@code this} object + */ + public final ImmutableQueryOptions withConsistencyMode(ConsistencyMode value) { + if (this.consistencyMode == value) return this; + return validate(new ImmutableQueryOptions( + this.wait, + this.token, + this.index, + this.near, + Preconditions.checkNotNull(value, "consistencyMode"))); + } + + /** + * This instance is equal to all instances of {@code ImmutableQueryOptions} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableQueryOptions + && equalTo((ImmutableQueryOptions) another); + } + + private boolean equalTo(ImmutableQueryOptions another) { + return wait.equals(another.wait) + && token.equals(another.token) + && index.equals(another.index) + && near.equals(another.near) + && consistencyMode.equals(another.consistencyMode) + && isBlocking == another.isBlocking + && hasToken == another.hasToken; + } + + /** + * Computes a hash code from attributes: {@code wait}, {@code token}, {@code index}, {@code near}, {@code consistencyMode}, {@code isBlocking}, {@code hasToken}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + wait.hashCode(); + h = h * 17 + token.hashCode(); + h = h * 17 + index.hashCode(); + h = h * 17 + near.hashCode(); + h = h * 17 + consistencyMode.hashCode(); + h = h * 17 + Booleans.hashCode(isBlocking); + h = h * 17 + Booleans.hashCode(hasToken); + return h; + } + + /** + * Prints the immutable value {@code QueryOptions...} with all non-generated + * and non-auxiliary attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return MoreObjects.toStringHelper("QueryOptions") + .add("wait", wait) + .add("token", token) + .add("index", index) + .add("near", near) + .add("consistencyMode", consistencyMode) + .add("isBlocking", isBlocking) + .add("hasToken", hasToken) + .toString(); + } + + private static ImmutableQueryOptions validate(ImmutableQueryOptions instance) { + instance.validate(); + return instance; + } + + /** + * Creates an immutable copy of a {@link QueryOptions} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable QueryOptions instance + */ + public static ImmutableQueryOptions copyOf(QueryOptions instance) { + if (instance instanceof ImmutableQueryOptions) { + return (ImmutableQueryOptions) instance; + } + return ImmutableQueryOptions.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableQueryOptions ImmutableQueryOptions}. + * @return A new ImmutableQueryOptions builder + */ + public static ImmutableQueryOptions.Builder builder() { + return new ImmutableQueryOptions.Builder(); + } + + /** + * Builds instances of type {@link ImmutableQueryOptions ImmutableQueryOptions}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private Optional wait = Optional.absent(); + private Optional token = Optional.absent(); + private Optional index = Optional.absent(); + private Optional near = Optional.absent(); + private ConsistencyMode consistencyMode; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code QueryOptions} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(QueryOptions instance) { + Preconditions.checkNotNull(instance, "instance"); + Optional waitOptional = instance.getWait(); + if (waitOptional.isPresent()) { + wait(waitOptional); + } + Optional tokenOptional = instance.getToken(); + if (tokenOptional.isPresent()) { + token(tokenOptional); + } + Optional indexOptional = instance.getIndex(); + if (indexOptional.isPresent()) { + index(indexOptional); + } + Optional nearOptional = instance.getNear(); + if (nearOptional.isPresent()) { + near(nearOptional); + } + consistencyMode(instance.getConsistencyMode()); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getWait() wait} to wait. + * @param wait The value for wait + * @return {@code this} builder for chained invocation + */ + public final Builder wait(String wait) { + this.wait = Optional.of(wait); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getWait() wait} to wait. + * @param wait The value for wait + * @return {@code this} builder for use in a chained invocation + */ + public final Builder wait(Optional wait) { + this.wait = Preconditions.checkNotNull(wait, "wait"); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getToken() token} to token. + * @param token The value for token + * @return {@code this} builder for chained invocation + */ + public final Builder token(String token) { + this.token = Optional.of(token); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getToken() token} to token. + * @param token The value for token + * @return {@code this} builder for use in a chained invocation + */ + public final Builder token(Optional token) { + this.token = Preconditions.checkNotNull(token, "token"); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getIndex() index} to index. + * @param index The value for index + * @return {@code this} builder for chained invocation + */ + public final Builder index(BigInteger index) { + this.index = Optional.of(index); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getIndex() index} to index. + * @param index The value for index + * @return {@code this} builder for use in a chained invocation + */ + public final Builder index(Optional index) { + this.index = Preconditions.checkNotNull(index, "index"); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getNear() near} to near. + * @param near The value for near + * @return {@code this} builder for chained invocation + */ + public final Builder near(String near) { + this.near = Optional.of(near); + return this; + } + + /** + * Initializes the optional value {@link QueryOptions#getNear() near} to near. + * @param near The value for near + * @return {@code this} builder for use in a chained invocation + */ + public final Builder near(Optional near) { + this.near = Preconditions.checkNotNull(near, "near"); + return this; + } + + /** + * Initializes the value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute. + *

If not set, this attribute will have a default value as returned by the initializer of {@link QueryOptions#getConsistencyMode() consistencyMode}. + * @param consistencyMode The value for consistencyMode + * @return {@code this} builder for use in a chained invocation + */ + public final Builder consistencyMode(ConsistencyMode consistencyMode) { + this.consistencyMode = Preconditions.checkNotNull(consistencyMode, "consistencyMode"); + return this; + } + + /** + * Builds a new {@link ImmutableQueryOptions ImmutableQueryOptions}. + * @return An immutable instance of QueryOptions + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableQueryOptions build() throws IllegalStateException { + return ImmutableQueryOptions.validate(new ImmutableQueryOptions(this)); + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java new file mode 100644 index 0000000..bccdd5c --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java @@ -0,0 +1,29 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.Optional; + +import javax.ws.rs.client.WebTarget; + +public class Options { + private Options(){}; + + static WebTarget optionallyAdd(WebTarget input, String key, Optional val) { + return val.isPresent() ? input.queryParam(key, val.get()) : input; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java new file mode 100644 index 0000000..56f97f6 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java @@ -0,0 +1,23 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.Function; + +import javax.ws.rs.client.WebTarget; + +public interface ParamAdder extends Function {} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java new file mode 100644 index 0000000..63d201e --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java @@ -0,0 +1,100 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.option; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; + +import java.math.BigInteger; + +import javax.ws.rs.client.WebTarget; + +import com.google.common.base.Optional; + +/** + * Container for common query options used by the Consul API. + */ + +public abstract class QueryOptions implements ParamAdder { + + public static final QueryOptions BLANK = ImmutableQueryOptions.builder().build(); + + public abstract Optional getWait(); + public abstract Optional getToken(); + public abstract Optional getIndex(); + public abstract Optional getNear(); + + + public ConsistencyMode getConsistencyMode() { + return ConsistencyMode.DEFAULT; + } + + + public boolean isBlocking() { + return getWait().isPresent(); + } + + + public boolean hasToken() { + return getToken().isPresent(); + } + + + void validate() { + if (isBlocking()) { + checkArgument(getIndex().isPresent(), "If wait is specified, index must also be specified"); + } + } + + public static ImmutableQueryOptions.Builder blockSeconds(int seconds, BigInteger index) { + return blockBuilder("s", seconds, index); + } + + public static ImmutableQueryOptions.Builder blockMinutes(int minutes, BigInteger index) { + return blockBuilder("m", minutes, index); + } + + private static ImmutableQueryOptions.Builder blockBuilder(String identifier, int qty, BigInteger index) { + return ImmutableQueryOptions.builder() + .wait(String.format("%s%s", qty, identifier)) + .index(index); + } + + @Override + public WebTarget apply(WebTarget input) { + + WebTarget added = input; + switch (getConsistencyMode()) { + case CONSISTENT: + added = added.queryParam("consistent", ""); + break; + case STALE: + added = added.queryParam("stale", ""); + break; + } + + if (isBlocking()) { + added = added.queryParam("wait", getWait().get()) + .queryParam("index", String.valueOf(getIndex().get())); + } + + added = optionallyAdd(added, "token", getToken()); + added = optionallyAdd(added, "near", getToken()); + + return added; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java new file mode 100644 index 0000000..58af732 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java @@ -0,0 +1,45 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.google.common.base.Optional; +import com.google.common.io.BaseEncoding; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +/** + * For use with JSON fields that Consul Base 64 encodes. + */ +public class Base64EncodingDeserializer extends JsonDeserializer> { + + /** + * {@inheritDoc} + */ + @Override + public Optional deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.getValueAsString(); + + if (StringUtils.isNotEmpty(value)) { + return Optional.of(new String(BaseEncoding.base64().decode(value))); + } + return Optional.absent(); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java new file mode 100644 index 0000000..ab184c1 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java @@ -0,0 +1,246 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import javax.ws.rs.ServerErrorException; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openo.msb.wrapper.consul.ConsulException; +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.ParamAdder; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +/** + * A collection of stateless utility methods for use in constructing + * requests and responses to the Consul HTTP API. + */ +public class ClientUtil { + + /** + * Applies all key/values from the params map to query string parameters. + * + * @param webTarget The JAX-RS target to apply the query parameters. + * @param params Map of parameters. + * @return The new target with the parameters applied. + */ + public static WebTarget queryParams(WebTarget webTarget, Map params) { + WebTarget target = webTarget; + + if(params != null) { + for(Map.Entry entry : params.entrySet()) { + target = target.queryParam(entry.getKey(), entry.getValue()); + } + } + + return target; + } + + /** + * Given a {@link org.openo.msb.wrapper.consul.option.ParamAdder} object, adds the + * appropriate query string parameters to the request being built. + * + * @param webTarget The base {@link javax.ws.rs.client.WebTarget}. + * @param paramAdder will add specific params to the target. + * @return A {@link javax.ws.rs.client.WebTarget} with all appropriate query + * string parameters. + */ + public static WebTarget addParams(WebTarget webTarget, ParamAdder paramAdder) { + return paramAdder == null ? webTarget : paramAdder.apply(webTarget); + } + + /** + * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, + * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. + * + * @param target The base {@link javax.ws.rs.client.WebTarget}. + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param type The generic type to marshall the resulting data to. + * @param The result type. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. + */ + public static ConsulResponse response(WebTarget target, CatalogOptions catalogOptions, + QueryOptions queryOptions, + GenericType type) { + target = addParams(target, catalogOptions); + target = addParams(target, queryOptions); + + return response(target, type); + } + + /** + * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, + * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. + * + * @param target The base {@link javax.ws.rs.client.WebTarget}. + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param type The generic type to marshall the resulting data to. + * @param The result type. + */ + public static void response(WebTarget target, CatalogOptions catalogOptions, + QueryOptions queryOptions, + GenericType type, + ConsulResponseCallback callback) { + + target = addParams(target, catalogOptions); + target = addParams(target, queryOptions); + + response(target, type, callback); + } + + /** + * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall + * the result JSON into, complete the HTTP GET request. + * + * @param webTarget The JAX-RS target. + * @param responseType The class to marshall the JSON into. + * @param The class to marshall the JSON into. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing the result. + */ + public static ConsulResponse response(WebTarget webTarget, GenericType responseType) { + Response response = webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).get(); + + return consulResponse(responseType, response); + } + + /** + * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall + * the result JSON into, complete the HTTP GET request. + * + * @param webTarget The JAX-RS target. + * @param responseType The class to marshall the JSON into. + * @param callback The callback object to handle the result on a different thread. + * @param The class to marshall the JSON into. + */ + public static void response(WebTarget webTarget, final GenericType responseType, + final ConsulResponseCallback callback) { + webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).async().get(new InvocationCallback() { + + @Override + public void completed(Response response) { + try { + callback.onComplete(consulResponse(responseType, response)); + } catch (Exception ex) { + callback.onFailure(ex); + } + } + + @Override + public void failed(Throwable throwable) { + callback.onFailure(throwable); + } + }); + } + + /** + * Extracts Consul specific headers and adds them to a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} + * object, which also contains the returned JSON entity. + * + * @param responseType The class to marshall the JSON to. + * @param response The HTTP response. + * @param The class to marshall the JSON to. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} object. + */ + private static ConsulResponse consulResponse(GenericType responseType, Response response) { + handleErrors(response); + + String indexHeaderValue = response.getHeaderString("X-Consul-Index"); + String lastContactHeaderValue = response.getHeaderString("X-Consul-Lastcontact"); + String knownLeaderHeaderValue = response.getHeaderString("X-Consul-Knownleader"); + + BigInteger index = new BigInteger(indexHeaderValue); + long lastContact = lastContactHeaderValue == null ? -1 : Long.valueOf(lastContactHeaderValue); + boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean.valueOf(knownLeaderHeaderValue); + + ConsulResponse consulResponse = new ConsulResponse(readResponse(response, responseType), lastContact, knownLeader, index); + + response.close(); + + return consulResponse; + } + + /** + * Converts a {@link Response} object to the generic type provided, or an empty + * representation if appropriate + * + * @param response response + * @param responseType response type + * @param + * @return the re + */ + private static T readResponse(Response response, GenericType responseType) { + if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { + // would be nice I knew a better way to do this + if (responseType.getRawType() == List.class) { + return (T) ImmutableList.of(); + } else if (responseType.getRawType() == Optional.class) { + return (T) Optional.absent(); + } else if(responseType.getRawType() == Map.class) { + return (T) ImmutableMap.of(); + } else { + // Not sure if this case will be reached, but if it is it'll be nice to know + throw new IllegalStateException("Cannot determine empty representation for " + responseType.getRawType()); + } + } + return response.readEntity(responseType); + } + + /** + * Since Consul returns plain text when an error occurs, check for + * unsuccessful HTTP status code, and throw an exception with the text + * from Consul as the message. + * + * @param response The HTTP response. + */ + public static void handleErrors(Response response) { + + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL + || response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { + // not an error + return; + } + + try { + final String message = response.hasEntity() ? response.readEntity(String.class) : null; + if (response.getStatusInfo().getFamily() == Response.Status.Family.SERVER_ERROR) { + throw new ServerErrorException(message, response); + } else { + throw new WebApplicationException(message, response); + } + } catch (Exception e) { + throw new ConsulException(e.getLocalizedMessage(), e); + } finally { + response.close(); + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java new file mode 100644 index 0000000..64feeac --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java @@ -0,0 +1,34 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.guava.GuavaModule; + +public class Jackson { + + public static final ObjectMapper MAPPER = newObjectMapper(); + + private static ObjectMapper newObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new GuavaModule()); + return mapper; + } + + private Jackson() {} + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java new file mode 100644 index 0000000..c438967 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java @@ -0,0 +1,35 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import javax.ws.rs.ext.ContextResolver; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class ObjectMapperContextResolver implements ContextResolver { + + private final ObjectMapper objectMapper; + public ObjectMapperContextResolver(final ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public ObjectMapper getContext(final Class type) { + return objectMapper; + } + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java new file mode 100644 index 0000000..17438f9 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java @@ -0,0 +1,43 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +/** + * Deserializes Consul time values with "s" suffix to {@link Long} objects. + */ +public class SecondsDeserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String value = p.getValueAsString(); + + if (StringUtils.isNotEmpty(value)) { + value = value.replaceAll("[a-zA-Z]", ""); + return Long.valueOf(value); + } else { + return null; + } + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java new file mode 100644 index 0000000..1420e18 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java @@ -0,0 +1,34 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Serializes a time field (e.g. TTL) as seconds. + */ +public class SecondsSerializer extends JsonSerializer { + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(String.format("%ss", value)); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java new file mode 100644 index 0000000..802c048 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java @@ -0,0 +1,37 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.google.common.primitives.UnsignedLongs; + +import java.io.IOException; + +/** + * @author sgardner + * @since 2015.02.28 + */ +public class UnsignedLongDeserializer extends JsonDeserializer { + @Override + public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String sValue = jp.getValueAsString(); + return UnsignedLongs.decode(sValue); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java new file mode 100644 index 0000000..098f71d --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java @@ -0,0 +1,33 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.serviceListener; + +import org.openo.msb.api.MicroServiceInfo; +import org.openo.msb.api.Service; + + +public interface IMicroServiceChangeListener { + public void onSave(Service microServiceInfo,String serverPort); + + public void onChange(String serviceName,String version,Service microServiceInfo,String serverPort); + + public void onStatusChange(String serviceName,String url,String version,String protocol,String status); + + public void onDelete(String serviceName, String url,String version,String protocol,String serverPort); + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java new file mode 100644 index 0000000..d41a0d0 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java @@ -0,0 +1,306 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.serviceListener; + +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.ApiRouteInfo; +import org.openo.msb.api.CustomRouteInfo; +import org.openo.msb.api.IuiRouteInfo; +import org.openo.msb.api.Node; +import org.openo.msb.api.RouteServer; +import org.openo.msb.api.Service; +import org.openo.msb.wrapper.ApiRouteServiceWrapper; +import org.openo.msb.wrapper.CustomRouteServiceWrapper; +import org.openo.msb.wrapper.IuiRouteServiceWrapper; +import org.openo.msb.wrapper.util.RegExpTestUtil; +import org.openo.msb.wrapper.util.RouteUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class MicroServiceChangeListener implements IMicroServiceChangeListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceChangeListener.class); + + @Override + public void onSave(Service microServiceInfo,String serverPort) { + + if("UI".equals(microServiceInfo.getProtocol())){ + IuiRouteInfo iuiRouteInfo = this.buildIuiRouteInfo(microServiceInfo); + if(null != iuiRouteInfo){ + IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); + } + } + else{ + + if(ifApiRouteUrl(microServiceInfo.getUrl())){ + ApiRouteInfo apiRouteInfo = this.buildApiRouteInfo(microServiceInfo); + if(null != apiRouteInfo){ + ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfo,serverPort); + } + } + else{ + CustomRouteInfo customRouteInfo = this.buildCustomRouteInfo(microServiceInfo); + if(null != customRouteInfo){ + CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfo,serverPort); + } + } + } + + + } + + @Override + public void onChange(String serviceName, String version, Service microServiceInfo,String serverPort) { + + if("UI".equals(microServiceInfo.getProtocol())){ + if(serviceName.startsWith("iui_")||serviceName.startsWith("IUI_")){ + serviceName=serviceName.substring(4); + } + IuiRouteInfo iuiRouteInfo = this.buildIuiRouteInfo(microServiceInfo); + if(null != iuiRouteInfo){ + IuiRouteServiceWrapper.getInstance().updateIuiRouteInstance(serviceName, iuiRouteInfo); + } + } + else{ + + if(ifApiRouteUrl(microServiceInfo.getUrl())){ + ApiRouteInfo apiRouteInfo = this.buildApiRouteInfo(microServiceInfo); + if(null != apiRouteInfo){ + ApiRouteServiceWrapper.getInstance().updateApiRouteInstance(serviceName, version, apiRouteInfo,serverPort); + } + } + else{ + if(!serviceName.startsWith("/")){ + serviceName="/"+serviceName; + } + CustomRouteInfo customRouteInfo = this.buildCustomRouteInfo(microServiceInfo); + if(null != customRouteInfo){ + CustomRouteServiceWrapper.getInstance().updateCustomRouteInstance(serviceName,customRouteInfo,serverPort); + } + } + } + + } + + @Override + public void onStatusChange(String serviceName,String url,String version,String protocol,String status) { + if("UI".equals(protocol)){ + + if(serviceName.startsWith("iui_")||serviceName.startsWith("IUI_")){ + serviceName=serviceName.substring(4); + } + IuiRouteServiceWrapper.getInstance().updateIuiRouteStatus(serviceName, status); + + } + else{ + if(ifApiRouteUrl(url)){ + ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName, version, status); + } + else{ + if(!serviceName.startsWith("/")){ + serviceName="/"+serviceName; + } + CustomRouteServiceWrapper.getInstance().updateCustomRouteStatus(serviceName, status); + } + } + + + + } + + @Override + public void onDelete(String serviceName,String url, String version,String protocol,String serverPort) { + + if("UI".equals(protocol)){ + if(serviceName.startsWith("iui_")||serviceName.startsWith("IUI_")){ + serviceName=serviceName.substring(4); + } + IuiRouteServiceWrapper.getInstance().deleteIuiRoute(serviceName, "*"); + + } + else{ + if(ifApiRouteUrl(url)){ + ApiRouteServiceWrapper.getInstance().deleteApiRoute(serviceName, version, "*",serverPort); + } + else{ + + + if(!serviceName.startsWith("/")){ + serviceName="/"+serviceName; + } + + CustomRouteServiceWrapper.getInstance().deleteCustomRoute(serviceName, "*",serverPort); + } + } + } + + + /** + * @Title ifApiRouteUrl + * @Description TODO(According to judge whether the API registration URL format) + * @param url + * @return + * @return boolean + */ + private boolean ifApiRouteUrl(String url){ + return RegExpTestUtil.apiRouteUrlRegExpTest(url); + } + + + /** + * From MicroServiceInfo to ApiRouteInfo + * @param microServiceInfo + * @return + */ + private ApiRouteInfo buildApiRouteInfo(Service microServiceInfo){ + + ApiRouteInfo apiRouteInfo = new ApiRouteInfo(); + apiRouteInfo.setUrl(microServiceInfo.getUrl()); + + Set nodes=microServiceInfo.getNodes(); + RouteServer[] routeServers=new RouteServer[nodes.size()]; + + + int i=0; + for(Node node:nodes){ + RouteServer routeServer = new RouteServer(node.getIp(),node.getPort()); + routeServers[i]=routeServer; + i++; + } + + + apiRouteInfo.setServers(routeServers); + String[] rangs=StringUtils.split(microServiceInfo.getVisualRange(), "|"); + if(RouteUtil.contain(rangs, "0")){ + apiRouteInfo.setVisualRange("0"); + } + else{ + apiRouteInfo.setVisualRange("1"); + } + + + if("ip_hash".equals(microServiceInfo.getLb_policy())){ + apiRouteInfo.setUseOwnUpstream("1"); + } + + + + apiRouteInfo.setServiceName(microServiceInfo.getServiceName()); + apiRouteInfo.setVersion(microServiceInfo.getVersion()); + //TODO:set json and metrics defaultValue + String version="".equals(microServiceInfo.getVersion())?"":"/"+microServiceInfo.getVersion(); + apiRouteInfo.setApiJson(microServiceInfo.getUrl()+"/swagger.json"); + apiRouteInfo.setMetricsUrl("/admin/metrics"); + return apiRouteInfo; + } + + + /** + * From MicroServiceInfo to CustomRouteInfo + * @param microServiceInfo + * @return + */ + private CustomRouteInfo buildCustomRouteInfo(Service microServiceInfo){ + + CustomRouteInfo customRouteInfo = new CustomRouteInfo(); + customRouteInfo.setUrl(microServiceInfo.getUrl()); + + Set nodes=microServiceInfo.getNodes(); + RouteServer[] routeServers=new RouteServer[nodes.size()]; + + + int i=0; + for(Node node:nodes){ + RouteServer routeServer = new RouteServer(node.getIp(),node.getPort()); + routeServers[i]=routeServer; + i++; + } + + customRouteInfo.setServers(routeServers); + String[] rangs=StringUtils.split(microServiceInfo.getVisualRange(), "|"); + if(RouteUtil.contain(rangs, "0")){ + customRouteInfo.setVisualRange("0"); + } + else{ + customRouteInfo.setVisualRange("1"); + } + + if("ip_hash".equals(microServiceInfo.getLb_policy())){ + customRouteInfo.setUseOwnUpstream("1"); + } + + String serviceName; + if(!microServiceInfo.getServiceName().startsWith("/")){ + serviceName="/"+microServiceInfo.getServiceName(); + } + else{ + serviceName=microServiceInfo.getServiceName(); + } + customRouteInfo.setServiceName(serviceName); + + return customRouteInfo; + } + + + /** + * From MicroServiceInfo to IuiRouteInfo + * @param microServiceInfo + * @return + */ + private IuiRouteInfo buildIuiRouteInfo(Service microServiceInfo){ + + IuiRouteInfo iuiRouteInfo = new IuiRouteInfo(); + iuiRouteInfo.setUrl(microServiceInfo.getUrl()); + + Set nodes=microServiceInfo.getNodes(); + RouteServer[] routeServers=new RouteServer[nodes.size()]; + + + int i=0; + for(Node node:nodes){ + RouteServer routeServer = new RouteServer(node.getIp(),node.getPort()); + routeServers[i]=routeServer; + i++; + } + + iuiRouteInfo.setServers(routeServers); + String[] rangs=StringUtils.split(microServiceInfo.getVisualRange(), "|"); + if(RouteUtil.contain(rangs, "0")){ + iuiRouteInfo.setVisualRange("0"); + } + else{ + iuiRouteInfo.setVisualRange("1"); + } + + if("ip_hash".equals(microServiceInfo.getLb_policy())){ + iuiRouteInfo.setUseOwnUpstream("1"); + } + + String serviceName=microServiceInfo.getServiceName(); + if(serviceName.startsWith("iui_")||serviceName.startsWith("IUI_")){ + serviceName=serviceName.substring(4); + } + + + iuiRouteInfo.setServiceName(serviceName); + + return iuiRouteInfo; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java new file mode 100644 index 0000000..25c0888 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java @@ -0,0 +1,66 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; + +public final class FileUtil { + + /** + * Read all the files under a folder + */ + public static File[] readFileFolder(String filepath) throws FileNotFoundException, IOException { + File file = new File(filepath); + if (file.isDirectory()) { + File[] filelist = file.listFiles(); + return filelist; + } + + return null; + } + + public static String readFile(String Path) throws IOException{ + BufferedReader reader = null; + String fileContent = ""; + try { + FileInputStream fileInputStream = new FileInputStream(Path); + InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8"); + reader = new BufferedReader(inputStreamReader); + String tempString = null; + while ((tempString = reader.readLine()) != null) { + fileContent += tempString; + } + reader.close(); + } catch (IOException e) { + throw e; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + throw e; + } + } + } + return fileContent; + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java new file mode 100644 index 0000000..531b0d4 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java @@ -0,0 +1,120 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.util.List; + +import org.openo.msb.api.ApiRouteInfo; +import org.openo.msb.api.RouteServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + + +public class JacksonJsonUtil { + + private static final Logger logger = LoggerFactory.getLogger(JacksonJsonUtil.class); + + private static ObjectMapper mapper; + + + public static synchronized ObjectMapper getMapperInstance() { + if (mapper == null) { + mapper = new ObjectMapper(); + } + return mapper; + } + + /** + * from java object to json + * @param obj + * @return json + * @throws Exception + */ + public static String beanToJson(Object obj) throws Exception { + String json=null; + try { + ObjectMapper objectMapper = getMapperInstance(); + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + json =objectMapper.writeValueAsString(obj); + } catch (Exception e) { + logger.error("Class beanToJson faild"); + throw new Exception("Class beanToJson faild"); + } + return json; + } + + + + /** + * from json to java object + * @param json + * @param cls + * @return + * @throws Exception + */ + public static Object jsonToBean(String json, Class cls) throws Exception { + Object vo =null; + try { + ObjectMapper objectMapper = getMapperInstance(); + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + vo = objectMapper.readValue(json, cls); + + } catch (Exception e) { + logger.error(cls+" JsonTobean faild"); + throw new Exception(cls+" JsonTobean faild"); + } + return vo; + } + + /** + * from json to java List + * @param json + * @return + * @throws Exception + */ + public static List jsonToListBean(String json) throws Exception { + List vo =null; + try { + + ObjectMapper objectMapper = getMapperInstance(); + + + vo = objectMapper.readValue(json, new TypeReference>() {}); + + } catch (Exception e) { + throw new Exception( "JSON_TO_BEAN_FAILD"); + } + return vo; + } + + public static void main(String[] args) { + RouteServer server=new RouteServer("127.0.0.1","80"); + try { + String json=beanToJson(server); + System.out.println(json); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java new file mode 100644 index 0000000..7075249 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java @@ -0,0 +1,221 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + + + +public final class JedisUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(JedisUtil.class); + private static String host = "127.0.0.1"; + private static int port = 6379; + private static int connectionTimeout = 2000; + private static int DEFAULT_DB_INDEX = 0; + + private static JedisPool jedisPool = null; + + public static String serverIp="127.0.0.1"; + + public static int serverPort=10080; + + public static String propertiesName="redis.properties"; + + public static String propertiesPath=""; + + + +public static void main(String[] args) { + +} + + private JedisUtil() { + // private constructor + + } + + private static void initialPool() { + try { + JedisPoolConfig config = new JedisPoolConfig(); + +// String pathtest=JedisUtil.class.getResource("").getPath(); +// String path ="/"+ pathtest.substring(0, pathtest.indexOf("assembly")).replace("file:/", "") +"assembly/"+defaultWorkspace; + + File propertiesFile = new File(propertiesPath); + + if (propertiesFile.exists()) { + + + BufferedInputStream inputStream =new BufferedInputStream(new FileInputStream(propertiesPath)); + ResourceBundle bundle =new PropertyResourceBundle(inputStream); + + if (bundle == null) { + throw new IllegalArgumentException( + "[redis.properties] is not found!"); + } + + + // 设置连接池基本信息 + String strHost = bundle.getString("redis.host"); + if(StringUtils.isNotEmpty(strHost)){ + host = strHost; + } + String strPort = bundle.getString("redis.port"); + if(StringUtils.isNotEmpty(strPort)){ + port = Integer.valueOf(strPort); + } + + + String strTimeout = bundle.getString("redis.connectionTimeout"); + if (StringUtils.isNotEmpty(strTimeout) ){ + connectionTimeout = Integer.valueOf(strTimeout); + } + +// serverIp=bundle.getString("server.ip"); + serverPort=Integer.valueOf(bundle.getString("server.port")); + + String strDbIndex = bundle.getString("redis.db_index"); + if (StringUtils.isNotEmpty(strDbIndex)) { + DEFAULT_DB_INDEX = Integer.valueOf(strDbIndex); + } + + String strMaxTotal = bundle.getString("redis.pool.maxTotal"); + if (StringUtils.isNotEmpty(strMaxTotal)) { + config.setMaxTotal(Integer.valueOf(strMaxTotal)); + } + + String strMaxIdle = bundle.getString("redis.pool.maxIdle"); + if (StringUtils.isNotEmpty(strMaxIdle)) { + config.setMaxIdle(Integer.valueOf(strMaxIdle)); + } + + String strMaxWaitMillis = bundle.getString("redis.pool.maxWaitMillis"); + if (StringUtils.isNotEmpty(strMaxWaitMillis)) { + config.setMaxWaitMillis(Long.valueOf(strMaxWaitMillis)); + } + + String strTestOnBorrow = bundle + .getString("redis.pool.testOnBorrow"); + if (StringUtils.isNotEmpty(strTestOnBorrow)) { + config.setTestOnBorrow(Boolean.valueOf(strTestOnBorrow)); + } + + String strTestOnReturn = bundle + .getString("redis.pool.testOnReturn"); + if (StringUtils.isNotEmpty(strTestOnReturn)) { + config.setTestOnReturn(Boolean.valueOf(strTestOnReturn)); + } + + } + + LOGGER.info("Redis server info: " + host + ":" + port); + LOGGER.info("nginx server info: " + serverIp + ":" + serverPort); + + +// ResourceBundle bundle = ResourceBundle.getBundle("conf.redis"); + + jedisPool = new JedisPool(config, host, port, connectionTimeout); + } catch (Exception e) { + LOGGER.error("Initiate Jedis pool failed!", e); + } + } + /** + * From the connection pool to obtain jedis instance, use the default database index number 0 + * @return + */ + public synchronized static Jedis borrowJedisInstance() { + if (jedisPool == null) { + initialPool(); + } + try { + if (jedisPool != null) { + Jedis resource = jedisPool.getResource(); + resource.select(DEFAULT_DB_INDEX); + return resource; + } else { + return null; + } + } catch (Exception e) { + LOGGER.error("Get Jedis from pool failed!", e); + return null; + } + } + /** + * From the connection pool to obtain jedis instance, using the specified database index number + * @return + */ + public synchronized static Jedis borrowJedisInstance(final int dbIndex) { + if (jedisPool == null) { + initialPool(); + } + try { + if (jedisPool != null) { + Jedis resource = jedisPool.getResource(); + resource.select(dbIndex); + return resource; + } else { + return null; + } + } catch (Exception e) { + LOGGER.error("Get Jedis from pool failed!", e); + return null; + } + } + + /** + * returned to the pool jedis instance + * @param jedis + */ + public static void returnJedisInstance(final Jedis jedis) { + if (jedis != null) { + jedis.close(); + } + } + + + /** + * @Title getJedis + * @Description TODO(From the connection pool to obtain jedis instance) + * @throws Exception + * @return Jedis + */ + public static Jedis getJedis() throws Exception{ + + + Jedis jedis = borrowJedisInstance(); + if (jedis == null) { + throw new Exception("fetch from jedis pool failed,null object!"); + + } + + return jedis; + + } + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java new file mode 100644 index 0000000..b07737b --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java @@ -0,0 +1,24 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +public class MetricsUtil { + + public static String adminContextPath = "http://127.0.0.1:8086/admin/metrics"; + + public static final int SC_OK = 200; +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java new file mode 100644 index 0000000..ed22745 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java @@ -0,0 +1,423 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.sql.Date; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.MicroServiceFullInfo; +import org.openo.msb.api.MicroServiceInfo; +import org.openo.msb.api.Node; +import org.openo.msb.api.NodeInfo; +import org.openo.msb.api.Service; +import org.openo.msb.wrapper.serviceListener.IMicroServiceChangeListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.Jedis; + +public class MicroServiceDB { + + private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceDB.class); + + private static MicroServiceDB instance = new MicroServiceDB(); + + private List serviceListenerlist = + new ArrayList(); + + private MicroServiceDB() {} + + public static MicroServiceDB getInstance() { + return instance; + } + + + public void addServiceChangeListener(IMicroServiceChangeListener listener) { + synchronized (serviceListenerlist) { + serviceListenerlist.add(listener); + } + } + + + public void removeServiceChangeListener(IMicroServiceChangeListener listener) { + synchronized (serviceListenerlist) { + serviceListenerlist.remove(listener); + } + } + + + public MicroServiceFullInfo[] getAllMicroServiceInstances() throws Exception { + Jedis jedis = null; + MicroServiceFullInfo[] microServiceList; + try { + jedis = JedisUtil.getJedis(); + + String routekey = + MicroServiceUtil.getPrefixedKey("","*", MicroServiceUtil.SUFFIX_PATH_INFO); + Set serviceSet = jedis.keys(routekey); + microServiceList = new MicroServiceFullInfo[serviceSet.size()]; + + Pattern redisKeyPattern = MicroServiceUtil.getRedisKeyPattern(); + int i = 0; + for (String servicePath : serviceSet) { + Matcher matcher = redisKeyPattern.matcher(servicePath); + if (matcher.matches()) { + microServiceList[i] = getMicroServiceByJedis(jedis, matcher.group("servicename"),matcher.group("version"), ""); + i++; + } + } + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new Exception("call redis throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return microServiceList; + } + + public void saveMicroServiceInfo2Redis(MicroServiceInfo microServiceInfo,String serverPort) throws Exception { + // 1.1 set info + String serviceInfokey = + MicroServiceUtil.getServiceInfoKey(serverPort,microServiceInfo.getServiceName(), + microServiceInfo.getVersion()); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("url", microServiceInfo.getUrl()); + serviceInfoMap.put("protocol", microServiceInfo.getProtocol()); + serviceInfoMap.put("visualRange",microServiceInfo.getVisualRange()); + serviceInfoMap.put("lb_policy",microServiceInfo.getLb_policy()); + serviceInfoMap.put("status", "0"); + + + + // 1.2 set lb info + String serviceLBkey = + MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(), + microServiceInfo.getVersion(), MicroServiceUtil.ROUTE_PATH_LOADBALANCE); + + + Jedis jedis = null; + try { + jedis = JedisUtil.getJedis(); + // 2.1 save info + jedis.hmset(serviceInfokey, serviceInfoMap); + + + for(Node node:microServiceInfo.getNodes()){ + + String key=serviceLBkey+":"+node.getIp()+"-"+node.getPort(); + + Map nodeMap = new HashMap(); + + nodeMap.put("ip", node.getIp()); + nodeMap.put("port", node.getPort()); + nodeMap.put("ttl", Integer.toString(node.getTtl())); + long expiration_time=System.currentTimeMillis()+node.getTtl()*1000; + nodeMap.put("expiration", Long.toString(expiration_time)); + + if(jedis.keys(key).isEmpty()){ + nodeMap.put("created_at", Long.toString(System.currentTimeMillis())); + } +// else{ +// Map nodeLBmap = jedis.hgetAll(key); +// nodeMap.put("created_at", nodeLBmap.get("created_at")); +// } + nodeMap.put("updated_at", Long.toString(System.currentTimeMillis())); + + jedis.hmset(key, nodeMap); + } + +// jedis.sadd(serviceLBkey, nodeArray); + + } catch (Exception e) { + LOGGER.error("save to redis throw exception", e); + throw new Exception("save to redis throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + + + } + + public void updateMicroServiceStatus(String serviceName, String version,String status) throws Exception{ + + + String serviceInfokey = MicroServiceUtil.getServiceInfoKey("",serviceName, version); + Map serviceInfoMap = new HashMap(); + serviceInfoMap.put("status", status); + + + Jedis jedis = null; + try { + jedis = JedisUtil.borrowJedisInstance(); + if (jedis == null) { + throw new Exception("fetch from jedis pool failed,null object!"); + } + jedis.hmset(serviceInfokey, serviceInfoMap); + } + catch (Exception e) { + LOGGER.error("update MicroService status throw exception", e); + throw new Exception("update MicroService status throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + } + + + public void updateMicroServiceNode2Redis(String serviceName, String version,String ip,String port,int ttl) throws Exception { + String serviceLBkey = + MicroServiceUtil.getPrefixedKey("",serviceName,version, MicroServiceUtil.ROUTE_PATH_LOADBALANCE); + + + Jedis jedis = null; + try { + jedis = JedisUtil.getJedis(); + + + String nodeKey=serviceLBkey+":"+ip+"-"+port; + Map nodeLBmap = jedis.hgetAll(nodeKey); + + if(nodeLBmap.isEmpty()){ + throw new NullPointerException(" MicroService Node not fond "); + } + + + nodeLBmap.put("ttl", Integer.toString(ttl)); + long expiration_time=System.currentTimeMillis()+ttl*1000; + nodeLBmap.put("expiration", Long.toString(expiration_time)); + nodeLBmap.put("updated_at", Long.toString(System.currentTimeMillis())); + + jedis.hmset(nodeKey, nodeLBmap); + + + } + catch (NullPointerException e){ + throw e; + } + catch (Exception e) { + LOGGER.error("update MicroService Node throw exception", e); + throw new Exception("update MicroService Node throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + } + + + public void noticeUpdateApiListener(String serviceName,String version,Service microServiceInfo,String serverPort) { + if (isNeedNotify(microServiceInfo)) { + for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { + serviceListener.onChange(serviceName,version, microServiceInfo,serverPort); + } + } + + } + + public void noticeUpdateStatusListener(Service microServiceInfo,String status) { + + for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { + serviceListener.onStatusChange(microServiceInfo.getServiceName(),microServiceInfo.getUrl(), + microServiceInfo.getVersion(),microServiceInfo.getProtocol(),status); + } + } + + + + public void noticeApiListener(Service microServiceInfo, String type,String serverPort) { + if (isNeedNotify(microServiceInfo)) { + + if ("ADD".equals(type)) { + for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { + serviceListener.onSave(microServiceInfo,serverPort); + } + } else if ("DELETE".equals(type)) { + for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { + serviceListener.onDelete(microServiceInfo.getServiceName(),microServiceInfo.getUrl(), + microServiceInfo.getVersion(),microServiceInfo.getProtocol(),serverPort); + } + } + + } + } + + + public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort) + throws Exception { + if (null == version || "null".equals(version)) { + version = ""; + } + + Jedis jedis = null; + MicroServiceFullInfo microServiceInfo = null; + + try { + jedis = JedisUtil.getJedis(); + + microServiceInfo= getMicroServiceByJedis(jedis,serviceName,version, serverPort); + + + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new Exception("call redis throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + return microServiceInfo; + + } + + private MicroServiceFullInfo getMicroServiceByJedis(Jedis jedis,String serviceName, String version,String serverPort){ + MicroServiceFullInfo microServiceInfo = null; + String serviceInfoKey = MicroServiceUtil.getServiceInfoKey(serverPort,serviceName, version); + Map infomap = jedis.hgetAll(serviceInfoKey); + if (!infomap.isEmpty()) { + microServiceInfo = new MicroServiceFullInfo(); + microServiceInfo.setServiceName(serviceName); + microServiceInfo.setVersion(version); + microServiceInfo.setUrl(infomap.get("url")); + microServiceInfo.setProtocol(infomap.get("protocol")); + microServiceInfo.setVisualRange(infomap.get("visualRange")); + microServiceInfo.setStatus(infomap.get("status")); + microServiceInfo.setLb_policy(infomap.get("lb_policy")); + + String nodeLBkey = + MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(), + microServiceInfo.getVersion(), + MicroServiceUtil.ROUTE_PATH_LOADBALANCE); + + Set nodeKeys=jedis.keys(nodeLBkey+":*"); + + Set nodes=new HashSet(); + for(String nodeKey:nodeKeys){ + Map nodeLBmap = jedis.hgetAll(nodeKey); + NodeInfo nodeInfo=new NodeInfo(); + nodeInfo.setNodeId(serviceName+"_"+nodeLBmap.get("ip")+"_"+nodeLBmap.get("port")); + nodeInfo.setIp(nodeLBmap.get("ip")); + nodeInfo.setPort(nodeLBmap.get("port")); + nodeInfo.setTtl(Integer.parseInt(nodeLBmap.get("ttl"))); + nodeInfo.setCreated_at(new Date(Long.parseLong(nodeLBmap.get("created_at")))); + nodeInfo.setUpdated_at(new Date(Long.parseLong(nodeLBmap.get("updated_at")))); + nodeInfo.setExpiration(new Date(Long.parseLong(nodeLBmap.get("expiration")))); + + nodes.add(nodeInfo); + } + + microServiceInfo.setNodes(nodes); + } + + + + + return microServiceInfo; + } + + + public void deleteMicroService(String serviceName, String version,String serverPort) throws Exception { + if (null == version || "null".equals(version)) { + version = ""; + } + + Jedis jedis = null; + try { + jedis = JedisUtil.getJedis(); + String routekey = MicroServiceUtil.getPrefixedKey(serverPort,serviceName, version, "*"); + Set infoSet = jedis.keys(routekey); + + String[] paths = new String[infoSet.size()]; + + infoSet.toArray(paths); + + jedis.del(paths); + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new Exception("call redis throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + } + + public void deleteNode(String serviceName, String version, String ip,String port) throws Exception { + if (null == version || "null".equals(version)) { + version = ""; + } + + Jedis jedis = null; + try { + jedis = JedisUtil.getJedis(); + String serviceLBkey = + MicroServiceUtil.getPrefixedKey("",serviceName, version, + MicroServiceUtil.ROUTE_PATH_LOADBALANCE,ip+"-"+port); + jedis.del(serviceLBkey); + } catch (Exception e) { + LOGGER.error("call redis throw exception", e); + throw new Exception("call redis throw exception:"+e.getMessage()); + } finally { + JedisUtil.returnJedisInstance(jedis); + } + + } + + + /** + * Determine whether the service needs to send a notification + * TODO: filter according to the agreement, + * the only notice of agreement for REST \ UI interface MSB - REST + * @param protocol + * @return + */ + private boolean isNeedNotifyByProtocol(String protocol) { + return "UI".equalsIgnoreCase(protocol) ||("REST".equalsIgnoreCase(protocol)); + } + + /** + * Determine whether the service needs to send a notification + * TODO: according to the visual range filter conditions + * @param visualRange + * @return + */ + private boolean isNeedNotifyByVisualRange(String visualRange) { + String[] rangeArray=StringUtils.split(visualRange, "|"); + return RouteUtil.contain(RouteUtil.visualRangeMatches, rangeArray); + } + + /** + * According to the MicroServiceInfo entity information to judge whether need to send a notification + * @param microServiceInfo + * @return + */ + private boolean isNeedNotify(Service microServiceInfo) { + if (null != microServiceInfo) { + return isNeedNotifyByProtocol(microServiceInfo.getProtocol()) && + isNeedNotifyByVisualRange(microServiceInfo.getVisualRange()); + } else { + return false; + } + } + + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java new file mode 100644 index 0000000..67fd60f --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java @@ -0,0 +1,96 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; + + +public class MicroServiceUtil { + public static final String PREFIX_PATH = "discover:microservices"; + + public static final String PREFIX_PATH_PORT = "discover:"; + + public static final String SUFFIX_PATH_INFO = "info"; + + public static final String REDIS_KEY_PATTERN = + "discover:microservices:(?[^:]+)(:(?[^:]*))?:info"; + + public static final String REQUEST_SUCCESS = "SUCCESS"; + + public static final String REQUEST_FAIL = "FAIL"; + + public static final String ROUTE_PATH_LOADBALANCE = "lb"; // 负载均衡路径名 + + + public static String getPrefixedKey(String... paths) { + StringBuffer sb = new StringBuffer(); + + if(paths[0].trim().equals("") || paths[0].equals(String.valueOf(JedisUtil.serverPort))){ + sb.append(PREFIX_PATH); + } + else{ + sb.append(PREFIX_PATH_PORT).append(paths[0]); + } + + for (int i = 1; i < paths.length; i++) { + sb.append(":"); + sb.append(paths[i]); + } + return sb.toString(); + } + + + public static String getServiceInfoKey(String serverPort,String serviceName, String version) { + return getPrefixedKey(serverPort,serviceName, version, SUFFIX_PATH_INFO); + } + + + + + + public static Pattern getRedisKeyPattern() { + return Pattern.compile(REDIS_KEY_PATTERN); + } + + public static String getRealIp(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) { + // After the reverse proxy can have multiple IP value for many times, the first IP is the real IP + int index = ip.indexOf(","); + if (index != -1) { + return ip.substring(0, index); + } else { + return ip; + } + } + ip = request.getHeader("X-Real-IP"); + + if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) { + return ip; + } + + + return request.getRemoteAddr(); + + } + + +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java new file mode 100644 index 0000000..88e83b0 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java @@ -0,0 +1,88 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import java.util.regex.Pattern; + +public class RegExpTestUtil { + + + + public static boolean hostRegExpTest(String host){ + + String hostReg = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)" + +":(\\d{1,5})$"; + return Pattern.matches(hostReg, host); + + } + + public static boolean ipRegExpTest(String ip){ + + String hostReg = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"; + return Pattern.matches(hostReg, ip); + + } + + public static boolean portRegExpTest(String port){ + + String hostReg = "^\\d{1,5}$"; + return Pattern.matches(hostReg, port); + + } + +public static boolean versionRegExpTest(String version){ + + String versionReg = "^v\\d+(\\.\\d+)?$"; + return Pattern.matches(versionReg, version); + + } + +public static boolean urlRegExpTest(String url){ + if(url.equals("/")) return true; + + String urlReg = "^\\/.*((?!\\/).)$"; + return Pattern.matches(urlReg, url); + +} + +public static boolean apiRouteUrlRegExpTest(String url){ + + String urlReg = "^\\/"+RouteUtil.API_ROOT_PATH+"\\/.*$"; + return Pattern.matches(urlReg, url); + +} + +public static boolean iuiRouteUrlRegExpTest(String url){ + + String urlReg = "^\\/"+RouteUtil.IUI_ROOT_PATH+"\\/.*$"; + return Pattern.matches(urlReg, url); + +} + + + + + public static void main(String[] args) { + System.out.println(urlRegExpTest("/api ")); +// System.out.println("api".startsWith("/")); + } +} diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java new file mode 100644 index 0000000..5f60bd8 --- /dev/null +++ b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java @@ -0,0 +1,135 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 org.openo.msb.wrapper.util; + +import org.apache.commons.lang3.StringUtils; +import org.openo.msb.api.DiscoverInfo; + + +public class RouteUtil { + + public static String IUI_ROOT_PATH="iui"; + + public static String API_ROOT_PATH="api"; + + public static final String ROUTE_PATH="msb:routing"; + + public static final String APIROUTE="api"; + + public static final String IUIROUTE="iui"; + + public static final String CUSTOMROUTE="custom"; + + public static final String P2PROUTE="p2p"; + + + public static final String ROUTE_PATH_INFO="info"; + + public static final String ROUTE_PATH_LOADBALANCE="lb"; + + public static final String APIROUTE_PATH_LIFE="life"; + + + public static final String REQUEST_SUCCESS = "SUCCESS"; + + public static final String REQUEST_FAIL = "FAIL"; + + public static String PROTOCOL_LIST="REST,UI,MQ,FTP,SNMP,TCP,UDP"; + + public static DiscoverInfo discoverInfo=new DiscoverInfo(); + + + public static String[] visualRangeRange={"0","1"}; + + public static String[] controlRangeMatches={"0","1","2"}; + + public static String[] statusRangeMatches={"0","1"}; + + public static String[] useOwnUpstreamRangeMatches={"0","1"}; + + public static String[] visualRangeMatches={"1"}; + + /** + * @Title: getPrefixedKey + * @Description: TODO(Add base path prefix radis assembly path) + * @param: @param serviceName + * @param: @param version + * @param: @param type + * @param: @return + * @return: String + */ + + public static String getPrefixedKey(String...paths){ + StringBuffer sb= new StringBuffer(); + + if(paths[0].trim().equals("") || paths[0].equals(String.valueOf(JedisUtil.serverPort))){ + sb.append(ROUTE_PATH); + } + else{ + sb.append(paths[0]); + } + + for (int i = 1; i < paths.length; i++) { + sb.append(":"); + sb.append(paths[i]); + } + return sb.toString(); + } + + + public static Object[] concat(Object[] a, Object[] b) { + Object[] c= new Object[a.length+b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + public static boolean contain(String[] array,String str){ + for(int i=0;i