aboutsummaryrefslogtreecommitdiffstats
path: root/apiroute/apiroute-service/src/main/java/org/onap
diff options
context:
space:
mode:
authorHuabingZhao <zhao.huabing@zte.com.cn>2017-07-25 15:18:33 +0800
committerHuabingZhao <zhao.huabing@zte.com.cn>2017-07-25 18:11:59 +0800
commit672f3d40be83d9e380fd7be4b674d5e8d5fa36de (patch)
tree43105e1d5e2ba8e8accea8648e57e1cf87db3f00 /apiroute/apiroute-service/src/main/java/org/onap
parent41d3db15a8e1a0496f9c2a5e15db2998a32bb9bf (diff)
Divide the MSB source codes into two repos
Change-Id: Ie76d545b214a8ce5191f215350a623e1529983d9 Issue-id: MSB-5 Signed-off-by: HuabingZhao <zhao.huabing@zte.com.cn>
Diffstat (limited to 'apiroute/apiroute-service/src/main/java/org/onap')
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteApp.java131
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java90
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/SyncDataManager.java135
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/ApiRouteInfo.java107
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java39
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java24
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java55
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java25
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/MicroServiceFullInfo.java195
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java98
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/PublishFullAddress.java48
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteInfo.java179
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java83
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java28
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java28
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/UnprocessableEntityException.java18
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java65
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheck.java132
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/OpenRestyHealthCheck.java39
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/RedisHealthCheck.java160
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java214
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java164
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java163
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java229
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapper.java273
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapper.java217
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapper.java416
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapper.java221
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapper.java398
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/CatalogClient.java87
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/Consul.java97
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/HealthClient.java112
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseCallback.java33
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseHeader.java27
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/OriginalConsulResponse.java27
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ConsulCache.java301
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCache.java65
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCache.java39
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilter.java98
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilter.java96
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilter.java48
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilter.java121
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTask.java90
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTask.java128
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchTask.java87
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandler.java36
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/Service.java39
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealth.java30
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/util/Http.java281
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOConstants.java6
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOFactory.java18
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/RedisAccessWrapper.java133
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/IRouteDAO.java18
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/RouteDAOImpl.java63
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Metadata.java48
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Node.java32
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/RouteInfo.java79
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Spec.java52
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/IServiceDAO.java17
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/ServiceDAOImpl.java59
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Metadata.java50
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Node.java32
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/ServiceInfo.java76
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Spec.java44
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/BaseQueue.java36
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/QueueManager.java65
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceConsumer.java167
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceData.java53
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListCache.java35
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListConsumer.java209
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListQueue.java59
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceQueue.java45
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/ApiRouteService.java159
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/CustomRouteService.java152
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/IuiRouteService.java151
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullService.java220
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java37
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListener.java779
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/RouteNotify.java77
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/CommonUtil.java76
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ConfigUtil.java446
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java78
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtil.java117
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpGetResult.java19
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/Jackson.java28
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtil.java110
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JedisUtil.java208
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java78
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java115
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RouteUtil.java345
-rw-r--r--apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ServiceFilter.java515
91 files changed, 10922 insertions, 0 deletions
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteApp.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteApp.java
new file mode 100644
index 0000000..5c3096f
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteApp.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute;
+import io.dropwizard.Application;
+import io.dropwizard.assets.AssetsBundle;
+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 org.onap.msb.apiroute.health.ApiRouteHealthCheck;
+import org.onap.msb.apiroute.resources.ApiRouteResource;
+import org.onap.msb.apiroute.resources.CustomRouteResource;
+import org.onap.msb.apiroute.resources.IuiRouteResource;
+import org.onap.msb.apiroute.resources.MicroServiceResource;
+import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+public class ApiRouteApp extends Application<ApiRouteAppConfig> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class);
+
+ public static void main(String[] args) throws Exception {
+ new ApiRouteApp().run(args);
+
+ InitRouteServiceWrapper.getInstance().initFilterConfig();
+
+ InitRouteServiceWrapper.getInstance().initDataSynchro();
+
+ InitRouteServiceWrapper.getInstance().initHealthCheck();
+ }
+
+
+ @Override
+ public String getName() {
+ return " MicroService Bus ";
+ }
+
+ @Override
+ public void initialize(Bootstrap<ApiRouteAppConfig> bootstrap) {
+ super.initialize(bootstrap);
+
+ }
+
+ @Override
+ public void run(ApiRouteAppConfig configuration, Environment environment) throws Exception {
+
+
+ ConfigUtil.getInstance().initRootPath();
+
+
+ String iuiRootPath=ConfigUtil.getInstance().getIUI_ROOT_PATH();
+
+ // new AssetsBundle("/iui-metrics", "/"+iuiRootPath+"/microservices/metrics","index.html", "iui-metrics").run(environment);
+
+ new AssetsBundle("/iui-route", "/"+iuiRootPath+"/microservices", "index.html","iui-microservices").run(environment);
+
+ new AssetsBundle("/api-doc", "/"+iuiRootPath+"/microservices/api-doc","index.html", "api-doc").run(environment);
+
+ new AssetsBundle("/ext", "/"+iuiRootPath+"/microservices/ext","index.html", "ext").run(environment);
+
+
+
+
+ final ApiRouteHealthCheck healthCheck =new ApiRouteHealthCheck();
+ environment.healthChecks().register("consulCheck", healthCheck);
+
+ environment.jersey().register(new ApiRouteResource());
+ environment.jersey().register(new IuiRouteResource());
+ environment.jersey().register(new CustomRouteResource());
+ environment.jersey().register(new MicroServiceResource());
+
+ // initSwaggerConfig(environment, configuration);
+
+ ConfigUtil.getInstance().initConsulIp();
+ ConfigUtil.getInstance().initDiscoverInfo(configuration);
+ // InitRouteServiceWrapper.getInstance().initMetricsConfig(configuration);
+
+
+ }
+
+
+
+
+
+
+ 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("ApiRoute RESTful API");
+ config.setVersion("1.0.0");
+ config.setResourcePackage("org.onap.msb.apiroute.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.warn("getApplicationContextPath: " + basePath);
+ config.setBasePath(basePath);
+ config.setScan(true);
+ }
+
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java
new file mode 100644
index 0000000..4c998e0
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.
+ */
+/**
+* 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.onap.msb.apiroute;
+
+import io.dropwizard.Configuration;
+
+import javax.validation.Valid;
+
+import org.hibernate.validator.constraints.NotEmpty;
+import org.onap.msb.apiroute.api.DiscoverInfo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ApiRouteAppConfig extends Configuration {
+ @NotEmpty
+ private String defaultWorkspace = "apiroute-works";
+
+ @NotEmpty
+ private String defaultName = "Stranger";
+
+
+ @Valid
+ private DiscoverInfo discoverInfo;
+
+
+ @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/onap/msb/apiroute/SyncDataManager.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/SyncDataManager.java
new file mode 100644
index 0000000..865778e
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/SyncDataManager.java
@@ -0,0 +1,135 @@
+package org.onap.msb.apiroute;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.http.HttpEntity;
+import org.onap.msb.apiroute.wrapper.consulextend.Consul;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.CheckServiceDataEmptyAndAutoStopWatchFilter;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.CheckTagAndAutoStopWatchFilter;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.ServiceModifyIndexFilter;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchCatalogServicesTask;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchServiceHealthTask;
+import org.onap.msb.apiroute.wrapper.consulextend.expose.WriteBufferHandler;
+import org.onap.msb.apiroute.wrapper.queue.ServiceConsumer;
+import org.onap.msb.apiroute.wrapper.queue.ServiceData;
+import org.onap.msb.apiroute.wrapper.queue.ServiceListConsumer;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SyncDataManager {
+ private static Consul consul;
+ private static WatchCatalogServicesTask serviceListWatchTask;
+ private final static Map<String, WatchServiceHealthTask> serviceWatchTaskMap = new ConcurrentHashMap<String, WatchServiceHealthTask>();
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(SyncDataManager.class);
+
+ private SyncDataManager() {
+ }
+
+ public static void initSyncTask(final String ip, final int port) {
+ consul = Consul.builder().withHostAndPort(ip, port).build();
+ startWatchServiceList();
+ startQueueConsumer();
+ }
+
+ public static void startWatchServiceList() {
+
+ LOGGER.info("===========start to WatchServiceList============");
+
+ // create service list watch task
+ serviceListWatchTask = new WatchCatalogServicesTask(
+ consul.catalogClient(), RouteUtil.WATCH_SECOND);
+
+ // first,write data to serviceListQueue buffer.
+ // second,async thread will read data from serviceListQueue buffer.
+ serviceListWatchTask.addHandler(new WriteBufferHandler<HttpEntity>(
+ ServiceData.DataType.service_list));
+
+ // start watch
+ serviceListWatchTask.startWatch();
+ }
+
+ public static void startQueueConsumer() {
+ LOGGER.info("===========start to QueueConsumer Thread============");
+
+ // start ServiceListConsumer
+ new Thread(new ServiceListConsumer(), "ServiceListConsumerThread")
+ .start();
+
+ // start Service Consumer
+ int serviceQueneNum = RouteUtil.SERVICE_DATA_QUEUE_NUM;
+ for (int i = 0; i < serviceQueneNum; i++) {
+ new Thread(new ServiceConsumer(i), "ServiceConsumerThread" + i)
+ .start();
+ }
+
+ }
+
+ public static void startWatchService(final String serviceName) {
+
+ LOGGER.info("===========start to Watch Service[" + serviceName
+ + "]============");
+ // create service watch task
+ WatchServiceHealthTask serviceWatchTask = new WatchServiceHealthTask(
+ consul.healthClient(), serviceName, RouteUtil.WATCH_SECOND);
+
+ // 1.service Data Empty filter
+ serviceWatchTask
+ .addFilter(new CheckServiceDataEmptyAndAutoStopWatchFilter(
+ serviceName));
+
+ // 2.service change filter
+ serviceWatchTask.addFilter(new ServiceModifyIndexFilter());
+
+ // 3.apigateway tag filter:check tag and auto stop watch
+ serviceWatchTask.addFilter(new CheckTagAndAutoStopWatchFilter(
+ serviceName));
+
+ // start watch
+ serviceWatchTask.startWatch();
+
+ // save
+ serviceWatchTaskMap.put(serviceName, serviceWatchTask);
+ }
+
+ public static void stopWatchServiceList() {
+ if (serviceListWatchTask != null) {
+ serviceListWatchTask.removeAllFilter();
+ serviceListWatchTask.removeAllHandler();
+ serviceListWatchTask.stopWatch();
+ }
+ }
+
+ public static void stopWatchService(String serviceName) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("stop " + serviceName + " service watch!");
+ }
+
+ WatchServiceHealthTask watchTask = serviceWatchTaskMap.get(serviceName);
+ if (watchTask != null) {
+ watchTask.removeAllFilter();
+ watchTask.removeAllHandler();
+ watchTask.stopWatch();
+ }
+ serviceWatchTaskMap.remove(serviceName);
+ }
+
+ public static boolean resetIndex(String serviceName) {
+
+ WatchServiceHealthTask watchTask = serviceWatchTaskMap.get(serviceName);
+
+ if (watchTask != null) {
+ return watchTask.resetIndex();
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("reset modify index.did not find:" + serviceName);
+ }
+
+ return false;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/ApiRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/ApiRouteInfo.java
new file mode 100644
index 0000000..1465000
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/ApiRouteInfo.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Objects;
+
+
+public class ApiRouteInfo extends RouteInfo {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(example = "v1", required = true)
+ private String version;
+
+
+ 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="";
+
+
+
+ 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 getApiJsonType() {
+ return apiJsonType;
+ }
+ public void setApiJsonType(String apiJsonType) {
+ this.apiJsonType = apiJsonType;
+ }
+ public String getMetricsUrl() {
+ return metricsUrl;
+ }
+ public void setMetricsUrl(String metricsUrl) {
+ this.metricsUrl = metricsUrl;
+ }
+
+
+
+
+ @Override
+ public Object clone() throws CloneNotSupportedException
+ {
+ return super.clone();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ApiRouteInfo that = (ApiRouteInfo) o;
+ return Objects.equals(isEnable_ssl(), that.isEnable_ssl()) &&
+ Objects.equals(getServiceName(), that.getServiceName()) &&
+ Objects.equals(version, that.version) &&
+ Objects.equals(getUrl(), that.getUrl()) &&
+ Objects.equals(apiJson, that.apiJson) &&
+ Objects.equals(apiJsonType, that.apiJsonType) &&
+ Objects.equals(metricsUrl, that.metricsUrl) &&
+ Objects.equals(getControl(), that.getControl()) &&
+ Objects.equals(getStatus(), that.getStatus()) &&
+ Objects.equals(getVisualRange(), that.getVisualRange()) &&
+ Objects.equals(getUseOwnUpstream(), that.getUseOwnUpstream()) &&
+ Arrays.equals(getServers(), that.getServers()) &&
+ Objects.equals(getHost(), that.getHost()) &&
+ Objects.equals(getNamespace(), that.getNamespace()) &&
+ Objects.equals(getPublish_port(), that.getPublish_port()) &&
+ Objects.equals(getConsulServiceName(), that.getConsulServiceName()) &&
+ Objects.equals(getPublishProtocol(), that.getPublishProtocol());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getServiceName(), version, getUrl(), apiJson, apiJsonType, metricsUrl, getControl(), getStatus(), getVisualRange(), getServers(), getHost(), getNamespace(), getPublish_port(), isEnable_ssl(), getConsulServiceName(), getPublishProtocol());
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java
new file mode 100644
index 0000000..709a995
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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<Date> {
+
+ @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/onap/msb/apiroute/api/CustomRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java
new file mode 100644
index 0000000..788ce00
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+
+public class CustomRouteInfo extends RouteInfo{
+
+ private static final long serialVersionUID = 1L;
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java
new file mode 100644
index 0000000..4a4708b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return this.ip+":"+this.port;
+ }
+
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java
new file mode 100644
index 0000000..b3f3cf6
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+
+
+public class IuiRouteInfo extends RouteInfo{
+
+ private static final long serialVersionUID = 1L;
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/MicroServiceFullInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/MicroServiceFullInfo.java
new file mode 100644
index 0000000..ca0b235
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/MicroServiceFullInfo.java
@@ -0,0 +1,195 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+import java.util.Set;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class MicroServiceFullInfo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+
+ @ApiModelProperty(required = true)
+ private String serviceName;
+
+ @ApiModelProperty(example = "v1")
+ private String version="";
+
+ @ApiModelProperty(value = "Target Service URL,start with /",example = "/api/serviceName/v1", required = true)
+ private String url="";
+
+ @ApiModelProperty(value = "Service Protocol", allowableValues = "REST,UI, MQ, FTP,SNMP,TCP,UDP", example = "REST",required = true)
+ private String protocol = "";
+
+ @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="";
+
+ private String namespace="";
+
+ private String host="";
+
+ private String path="";
+
+ private String publish_port="";
+
+ @ApiModelProperty(value = "enable ssl", allowableValues = "true,false", example = "false")
+ private boolean enable_ssl=false; //true:https:开启SSL加密, false:http
+
+ private String custom; //PORTAL协议标志
+
+ private Set<Node> nodes;
+
+ @ApiModelProperty(value = "Service Status", allowableValues = "0,1", example = "1")
+ private String status = "1"; //0:disable 1:enable
+
+
+
+
+ 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;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+
+ public String getHost() {
+ return host;
+ }
+ public void setHost(String host) {
+ this.host = host;
+ }
+ public String getPath() {
+ return path;
+ }
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+
+
+ public Set<Node> getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(Set<Node> nodes) {
+ this.nodes = nodes;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+ public void setStatus(String status) {
+ this.status = status;
+ }
+ public String getPublish_port() {
+ return publish_port;
+ }
+ public void setPublish_port(String publish_port) {
+ this.publish_port = publish_port;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MicroServiceFullInfo that = (MicroServiceFullInfo) o;
+ return Objects.equals(serviceName, that.serviceName) &&
+ Objects.equals(version, that.version) &&
+ Objects.equals(url, that.url) &&
+ Objects.equals(protocol, that.protocol) &&
+ Objects.equals(visualRange, that.visualRange) &&
+ Objects.equals(lb_policy, that.lb_policy) &&
+ Objects.equals(namespace, that.namespace) &&
+ Objects.equals(host, that.host) &&
+ Objects.equals(path, that.path) &&
+ Objects.equals(publish_port, that.publish_port) &&
+ Objects.equals(enable_ssl, that.enable_ssl) &&
+ Objects.equals(nodes, that.nodes) &&
+ Objects.equals(status, that.status);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(serviceName, version, url, protocol, visualRange, lb_policy, namespace, host, path, publish_port, enable_ssl, nodes, status);
+ }
+ public boolean isEnable_ssl() {
+ return enable_ssl;
+ }
+ public void setEnable_ssl(boolean enable_ssl) {
+ this.enable_ssl = enable_ssl;
+ }
+ public String getCustom() {
+ return custom;
+ }
+ public void setCustom(String custom) {
+ this.custom = custom;
+ }
+
+
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java
new file mode 100644
index 0000000..c515820
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class Node implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(required = true)
+ private String ip;
+
+ @ApiModelProperty(required = true)
+ private String port;
+
+ private String status="passing"; //实例健康检查状态
+
+ private int ttl=-1;
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ 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;
+ }
+
+ public Node(String ip,String port){
+ this.ip = ip;
+ this.port = port;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Node node = (Node) o;
+ return Objects.equals(ttl, node.ttl) &&
+ Objects.equals(ip, node.ip) &&
+ Objects.equals(port, node.port) &&
+ Objects.equals(status, node.status);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip, port, status, ttl);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/PublishFullAddress.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/PublishFullAddress.java
new file mode 100644
index 0000000..3f62897
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/PublishFullAddress.java
@@ -0,0 +1,48 @@
+package org.onap.msb.apiroute.api;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PublishFullAddress implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+
+ private String ip;
+
+ private String port;
+
+
+ private String publish_protocol;
+
+ public String getPublish_protocol() {
+ return publish_protocol;
+ }
+
+ public void setPublish_protocol(String publish_protocol) {
+ this.publish_protocol = publish_protocol;
+ }
+
+
+ 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 PublishFullAddress(){
+
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteInfo.java
new file mode 100644
index 0000000..5e36b9d
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteInfo.java
@@ -0,0 +1,179 @@
+package org.onap.msb.apiroute.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RouteInfo implements Serializable,Cloneable {
+ 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"; //lb policy
+
+ @ApiModelProperty(required = true)
+ private RouteServer servers[];
+
+ private String host="";
+
+ private String namespace="";
+
+ private String publish_port="";
+
+ private boolean enable_ssl=false; //true:https:开启SSL加密, false:http
+
+ private String consulServiceName="";
+
+ private String publishProtocol="http";
+
+
+
+ public String getPublish_port() {
+ return publish_port;
+ }
+ public void setPublish_port(String publish_port) {
+ this.publish_port = publish_port;
+ }
+
+
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+
+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.clone();
+ }
+
+ public void setServers(RouteServer[] servers) {
+ this.servers = servers.clone();
+ }
+
+ 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;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+ public String getConsulServiceName() {
+ return consulServiceName;
+ }
+ public void setConsulServiceName(String consulServiceName) {
+ this.consulServiceName = consulServiceName;
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException
+ {
+ return super.clone();
+ }
+ public String getPublishProtocol() {
+ return publishProtocol;
+ }
+ public void setPublishProtocol(String publishProtocol) {
+ this.publishProtocol = publishProtocol;
+ }
+ public boolean isEnable_ssl() {
+ return enable_ssl;
+ }
+ public void setEnable_ssl(boolean enable_ssl) {
+ this.enable_ssl = enable_ssl;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RouteInfo that = (RouteInfo) o;
+ return Objects.equals(enable_ssl, that.enable_ssl) &&
+ Objects.equals(serviceName, that.serviceName) &&
+ Objects.equals(url, that.url) &&
+ Objects.equals(control, that.control) &&
+ Objects.equals(status, that.status) &&
+ Objects.equals(visualRange, that.visualRange) &&
+ Objects.equals(useOwnUpstream, that.useOwnUpstream) &&
+ Arrays.equals(servers, that.servers) &&
+ Objects.equals(host, that.host) &&
+ Objects.equals(namespace, that.namespace) &&
+ Objects.equals(publish_port, that.publish_port) &&
+ Objects.equals(consulServiceName, that.consulServiceName) &&
+ Objects.equals(publishProtocol, that.publishProtocol);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(serviceName, url, control, status, visualRange, useOwnUpstream, servers, host, namespace, publish_port, enable_ssl, consulServiceName, publishProtocol);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java
new file mode 100644
index 0000000..310e623
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+
+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;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RouteServer that = (RouteServer) o;
+ return Objects.equals(weight, that.weight) &&
+ Objects.equals(ip, that.ip) &&
+ Objects.equals(port, that.port);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip, port, weight);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java
new file mode 100644
index 0000000..de0d47a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java
new file mode 100644
index 0000000..34439d9
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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/onap/msb/apiroute/api/exception/UnprocessableEntityException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/UnprocessableEntityException.java
new file mode 100644
index 0000000..28cfd17
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/UnprocessableEntityException.java
@@ -0,0 +1,18 @@
+package org.onap.msb.apiroute.api.exception;
+
+import javax.ws.rs.ClientErrorException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.http.HttpStatus;
+
+public class UnprocessableEntityException extends ClientErrorException{
+ private static final long serialVersionUID = -8266622745725405656L;
+
+ public UnprocessableEntityException(final String message) {
+ super(Response.status(HttpStatus.SC_UNPROCESSABLE_ENTITY).entity(message).type(MediaType.TEXT_PLAIN).build());
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java
new file mode 100644
index 0000000..82b5f21
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.
+ */
+/**
+* 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.onap.msb.apiroute.health;
+
+import org.onap.msb.apiroute.api.DiscoverInfo;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class ApiRouteHealthCheck extends HealthCheck {
+
+
+ public ApiRouteHealthCheck() {
+ }
+
+ @Override
+ protected Result check() throws Exception {
+ DiscoverInfo discoverInfo=ConfigUtil.getInstance().getDiscoverInfo();
+
+ String checkUrl =
+ (new StringBuilder().append("http://").append(discoverInfo.toString())
+ .append(RouteUtil.MSB_CHECK_URL)).toString();
+
+ int resultStatus = HttpClientUtil.httpGetStatus(checkUrl);
+
+ if(resultStatus==200){
+ return Result.healthy();
+ }
+ else{
+ return Result.unhealthy("check consul fail:[status]"+resultStatus);
+ }
+
+
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheck.java
new file mode 100644
index 0000000..916d2f8
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheck.java
@@ -0,0 +1,132 @@
+package org.onap.msb.apiroute.health;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.ApiRouteApp;
+import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
+import org.onap.msb.apiroute.wrapper.util.HttpGetResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class ConsulLinkHealthCheck extends HealthCheck implements Runnable {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(ConsulLinkHealthCheck.class);
+
+ private final static String CONSUL_IP_ENV = ConfigUtil.getInstance().getConsul_ip();
+
+ private static int failedLoopCheckNum = 12;
+ private static int failedTimer = 5 * 1000;
+
+ private static int normalTimer = 20 * 1000;
+ private static Result result = Result.healthy();
+
+ private String CHECK_IP = "127.0.0.1";
+ private String CHECK_PORT = "8500";
+ private String CHECK_URL = "http://" + CHECK_IP + ":" + CHECK_PORT
+ + "/v1/status/leader";
+
+ public static Result getResult() {
+ return result;
+ }
+
+ @Override
+ protected Result check() {
+ // TODO Auto-generated method stub
+
+ if (!StringUtils.isBlank(CONSUL_IP_ENV)) {
+ CHECK_IP = CONSUL_IP_ENV;
+ CHECK_URL = "http://" + CHECK_IP + ":" + CHECK_PORT
+ + "/v1/status/leader";
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("check consul URL:" + CHECK_URL);
+ }
+
+ try {
+
+ HttpGetResult result = HttpClientUtil
+ .httpGetStatusAndBody(CHECK_URL);
+
+ //response format:"127.0.0.1:8300"
+ if (result.getStatusCode() == 200 && result.getBody() != null
+ && result.getBody().contains(":8300")) {
+ return Result.healthy();
+ } else {
+ return Result.unhealthy("check consul link " + CHECK_URL
+ + " fail:" + result.getStatusCode()+":"+result.getBody());
+ }
+
+ } catch (Exception e) {
+ LOGGER.warn(
+ "ConsulLinkHealthCheck:" + CHECK_URL + " execption", e);
+ return Result.unhealthy("check consul link " + CHECK_URL
+ + " exception:{}");
+ }
+
+ }
+
+ return Result.healthy();
+ }
+
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ while (true) {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("consul link check starttime:"
+ + System.currentTimeMillis());
+ }
+
+ result = checkWithPolicy();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("consul link check result:" + result.isHealthy()
+ + " message:" + result.getMessage());
+
+ LOGGER.debug("consul link check endtime:"
+ + System.currentTimeMillis());
+ }
+
+ try {
+ Thread.sleep(normalTimer);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("loop check consul,thread sleep excepiton", e);
+ }
+ }
+ }
+
+ private Result checkWithPolicy() {
+ int failedNum = 0;
+ Result temp = Result.healthy();
+
+ do {
+ // check again
+ temp = check();
+
+ // healthy break;
+ if (temp.isHealthy()) {
+ break;
+ }
+
+ // unhealthy go on
+ failedNum++;
+
+ try {
+ Thread.sleep(failedTimer);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("loop check consul,thread sleep excepiton", e);
+ }
+
+ } while (failedNum <= failedLoopCheckNum);
+
+ return temp;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/OpenRestyHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/OpenRestyHealthCheck.java
new file mode 100644
index 0000000..fb0379f
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/OpenRestyHealthCheck.java
@@ -0,0 +1,39 @@
+package org.onap.msb.apiroute.health;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class OpenRestyHealthCheck extends HealthCheck {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(OpenRestyHealthCheck.class);
+ private String CHECK_IP="127.0.0.1";
+ private String CHECK_PORT="80";
+ private String CHECK_URL = "http://"+CHECK_IP+":"+CHECK_PORT+"/api/microservices/v1/apiRoute/discoverInfo";
+
+ @Override
+ protected Result check() throws Exception {
+ // TODO Auto-generated method stub
+
+ if(!StringUtils.isBlank(System.getenv("HTTP_OVERWRITE_PORT")))
+ {
+ CHECK_PORT=System.getenv("HTTP_OVERWRITE_PORT");
+ CHECK_URL = "http://"+CHECK_IP+":"+CHECK_PORT+"/api/microservices/v1/apiRoute/discoverInfo";
+ LOGGER.info("check openresty URL:"+CHECK_URL);
+ }
+
+ int resultStatus = HttpClientUtil.httpGetStatus(CHECK_URL);
+
+ if (resultStatus == 200) {
+ return Result.healthy();
+ } else {
+ return Result
+ .unhealthy("check openresty fail:" + resultStatus);
+ }
+
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/RedisHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/RedisHealthCheck.java
new file mode 100644
index 0000000..7cef3d0
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/RedisHealthCheck.java
@@ -0,0 +1,160 @@
+package org.onap.msb.apiroute.health;
+
+import java.text.SimpleDateFormat;
+
+import org.onap.msb.apiroute.wrapper.util.JedisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import redis.clients.jedis.Jedis;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class RedisHealthCheck extends HealthCheck implements Runnable {
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(RedisHealthCheck.class);
+
+ public static boolean writeCheckFlag = true;
+ private static Result result = Result.healthy();
+
+ private static int failedLoopCheckNum = 12;
+ private static int failedTimer = 5 * 1000;
+
+ private static int normalTimer = 20 * 1000;
+
+ public static Result getResult() {
+ return result;
+ }
+
+ @Override
+ protected Result check() {
+
+ // check write
+ if (writeCheckFlag) {
+ Result writeCheckResult = checkWrite();
+ if (writeCheckResult.isHealthy()) {
+ writeCheckFlag = false;
+ }
+
+ // write failed
+ if (!writeCheckResult.isHealthy()) {
+ return writeCheckResult;
+ }
+ }
+
+ // check read
+ Result readCheckResult = checkRead();
+
+ // read failed
+ if (!readCheckResult.isHealthy()) {
+ return readCheckResult;
+ }
+
+ return Result.healthy();
+ }
+
+ private Result checkRead() {
+ Jedis jedisHandle = null;
+
+ Result healthRst = Result.healthy();
+ try {
+
+ jedisHandle = JedisUtil.borrowJedisInstance();
+ jedisHandle.get("healthchek:checktime");
+
+ } catch (Exception e) {
+ LOGGER.warn("RedisHealthCheck exception", e);
+ healthRst = Result.unhealthy(e);
+ } finally {
+ JedisUtil.returnJedisInstance(jedisHandle);
+ }
+
+ return healthRst;
+ }
+
+ private Result checkWrite() {
+ Jedis jedisHandle = null;
+
+ Result healthRst = Result.healthy();
+ try {
+
+ long currentTime = System.currentTimeMillis();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String date = sdf.format(currentTime);
+
+ jedisHandle = JedisUtil.borrowJedisInstance();
+ String statusCode = jedisHandle.set("healthchek:checktime", date);
+
+ if (statusCode != null && statusCode.equals("OK")) {
+ healthRst = Result.healthy("check redis:" + statusCode);
+ } else {
+ healthRst = Result.unhealthy("check redis:" + statusCode);
+ }
+
+ } catch (Exception e) {
+ LOGGER.warn("RedisHealthCheck exception", e);
+ healthRst = Result.unhealthy(e);
+ } finally {
+ JedisUtil.returnJedisInstance(jedisHandle);
+ }
+
+ return healthRst;
+ }
+
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ while (true) {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("redis check starttime:"
+ + System.currentTimeMillis());
+ }
+
+ result = checkWithPolicy();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("redis check result:" + result.isHealthy()
+ + " message:" + result.getMessage());
+
+ LOGGER.debug("redis check endtime:"
+ + System.currentTimeMillis());
+ }
+
+ try {
+ Thread.sleep(normalTimer);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("loop check redis,thread sleep excepiton", e);
+ }
+ }
+ }
+
+ private Result checkWithPolicy() {
+ int failedNum = 0;
+ Result temp = Result.healthy();
+
+ do {
+ // check again
+ temp = check();
+
+ // healthy break;
+ if (temp.isHealthy()) {
+ break;
+ }
+
+ // unhealthy go on
+ failedNum++;
+
+ try {
+ Thread.sleep(failedTimer);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("loop check redis,thread sleep excepiton", e);
+ }
+
+ } while (failedNum <= failedLoopCheckNum);
+
+ return temp;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java
new file mode 100644
index 0000000..e969e7a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java
@@ -0,0 +1,214 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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 java.util.List;
+
+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.Response.ResponseBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.http.HttpStatus;
+import org.onap.msb.apiroute.api.ApiRouteInfo;
+import org.onap.msb.apiroute.api.DiscoverInfo;
+import org.onap.msb.apiroute.wrapper.ApiRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.IuiRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.CommonUtil;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil;
+
+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 List<ApiRouteInfo> getApiRoutes(@ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ return ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(routeWay);
+ }
+
+ @POST
+ @Path("/")
+ @ApiOperation(value = "add one ApiRoute ", code = HttpStatus.SC_CREATED,response = ApiRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().saveApiRouteInstance4Rest(apiRouteInfo,routeWay);
+ 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_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "ApiRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "ApiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ return ApiRouteServiceWrapper.getInstance().getApiRouteInstance(serviceName,version,host,publish_port,routeWay);
+
+ }
+
+ @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_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().saveApiRouteInstance4Rest(apiRouteInfo,routeWay);
+ 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,
+ @ApiParam(value = "ApiRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "ApiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(serviceName, version,host,publish_port,routeWay);
+ }
+
+
+ @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() {
+
+ return ApiRouteServiceWrapper.getInstance().getAllApiDocs();
+ }
+
+
+ @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 ConfigUtil.getInstance().getDiscoverInfo();
+ }
+
+ @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_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "ApiRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "ApiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName,version,host,publish_port,status,routeWay);
+ 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(@ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) throws Exception {
+
+ ResponseBuilder response = Response.ok( ApiRouteServiceWrapper.getInstance().getAllrouteByJson(routeWay));
+ return response.header("Content-Disposition", "attachment; filename=\"RouteService.json\"").build();
+
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java
new file mode 100644
index 0000000..92b3408
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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 java.util.List;
+
+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.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.onap.msb.apiroute.api.CustomRouteInfo;
+import org.onap.msb.apiroute.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 List<CustomRouteInfo> getCustomRoutes(@ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ return CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(routeWay);
+ }
+
+ @POST
+ @Path("/instance")
+ @ApiOperation(value = "add one CustomRoute ", code = HttpStatus.SC_CREATED,response = CustomRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ CustomRouteInfo new_customRouteInfo = CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance4Rest(customRouteInfo,routeWay);
+ 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_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "CustomRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "CustomRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+
+ return CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(serviceName,host,publish_port,routeWay);
+
+ }
+
+ @PUT
+ @Path("/instance")
+ @ApiOperation(value = "update one CustomRoute by serviceName", code = HttpStatus.SC_CREATED,response = CustomRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay
+ ) {
+
+ CustomRouteInfo new_customRouteInfo= CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance4Rest(customRoute,routeWay);
+
+ 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,
+ @ApiParam(value = "CustomRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "CustomRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(serviceName,host,publish_port,routeWay);
+
+ }
+
+ @PUT
+ @Path("/status")
+ @ApiOperation(value = "update one CustomRoute status by serviceName ",code = HttpStatus.SC_CREATED, response = CustomRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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 host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "CustomRoute status,1:abled 0:disabled", required = true) @QueryParam("status") String status,
+ @ApiParam(value = "CustomRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ CustomRouteInfo new_customRouteInfo = CustomRouteServiceWrapper.getInstance().updateCustomRouteStatus(serviceName,host,publish_port,status,routeWay);
+ return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_customRouteInfo).build();
+
+
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java
new file mode 100644
index 0000000..fea6645
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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 java.util.List;
+
+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.http.HttpStatus;
+import org.onap.msb.apiroute.api.IuiRouteInfo;
+import org.onap.msb.apiroute.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 List<IuiRouteInfo> getIuiRoutes(@ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ return IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(routeWay);
+ }
+
+ @POST
+ @Path("/")
+ @ApiOperation(value = "add one iuiRoute ", code = HttpStatus.SC_CREATED,response = IuiRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+ IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance4Rest(iuiRouteInfo,routeWay);
+ 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_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "iuiRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "iuiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ return IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(serviceName,host,publish_port,routeWay);
+
+ }
+
+ @PUT
+ @Path("/{serviceName}")
+ @ApiOperation(value = "update one iuiRoute by serviceName", code = HttpStatus.SC_CREATED,response = IuiRouteInfo.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, 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,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance4Rest(iuiRouteInfo,routeWay);
+ 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,
+ @ApiParam(value = "iuiRoute host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "iuiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(serviceName,host,publish_port,routeWay);
+
+ }
+
+ @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_UNPROCESSABLE_ENTITY, 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 host", required = false) @QueryParam("host") String host,
+ @ApiParam(value = "iuiRoute status,1:abled 0:disabled", required = true) @PathParam("status") String status,
+ @ApiParam(value = "iuiRoute Publish port", required = false) @QueryParam("publish_port") @DefaultValue("")String publish_port,
+ @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) {
+
+ IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().updateIuiRouteStatus(serviceName,host,publish_port,status,routeWay);
+ 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/onap/msb/apiroute/resources/MicroServiceResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java
new file mode 100644
index 0000000..5beb209
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java
@@ -0,0 +1,229 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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 java.util.List;
+
+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.http.HttpStatus;
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
+import org.onap.msb.apiroute.health.ConsulLinkHealthCheck;
+import org.onap.msb.apiroute.health.RedisHealthCheck;
+import org.onap.msb.apiroute.wrapper.MicroServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.codahale.metrics.annotation.Timed;
+import com.codahale.metrics.health.HealthCheck.Result;
+
+@Path("/services")
+// @Api(tags = {"MSB-Service Resource"})
+@Produces(MediaType.APPLICATION_JSON)
+public class MicroServiceResource {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
+
+ @Context
+ UriInfo uriInfo; // actual uri info
+
+ @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 List<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_UNPROCESSABLE_ENTITY, 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) MicroServiceFullInfo 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_UNPROCESSABLE_ENTITY, 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) {
+
+
+ return MicroServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version);
+
+
+ }
+
+ @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_UNPROCESSABLE_ENTITY, 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) MicroServiceFullInfo microServiceInfo,
+ @Context HttpServletRequest request) {
+
+ String ip=MicroServiceUtil.getRealIp(request);
+ MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo,
+ false,ip,"");
+ 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_UNPROCESSABLE_ENTITY, 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_UNPROCESSABLE_ENTITY, 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) {
+
+ MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version);
+
+ }
+
+ @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_UNPROCESSABLE_ENTITY, 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();
+
+ }
+
+ @GET
+ @Path("/health")
+ @ApiOperation(value = "apigateway healthy check ", code = HttpStatus.SC_OK, response = String.class)
+ @ApiResponses(value = { @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "check fail", response = String.class) })
+ @Produces(MediaType.TEXT_PLAIN)
+ @Timed
+ public Response health() {
+
+ // redis
+ Result rst = RedisHealthCheck.getResult();
+ if (!rst.isHealthy()) {
+ LOGGER.warn("health check failed:"+rst.getMessage());
+ throw new ExtendedInternalServerErrorException(rst.getMessage());
+ }
+
+ //consul
+ rst = ConsulLinkHealthCheck.getResult();
+ if (!rst.isHealthy()) {
+ LOGGER.warn("health check failed:"+rst.getMessage());
+ throw new ExtendedInternalServerErrorException(rst.getMessage());
+ }
+
+ return Response.ok("apigateway healthy check:ok").build();
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapper.java
new file mode 100644
index 0000000..80dc607
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapper.java
@@ -0,0 +1,273 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+
+import org.onap.msb.apiroute.api.ApiRouteInfo;
+import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
+import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException;
+import org.onap.msb.apiroute.wrapper.service.ApiRouteService;
+import org.onap.msb.apiroute.wrapper.util.CommonUtil;
+import org.onap.msb.apiroute.wrapper.util.FileUtil;
+import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+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;
+ }
+
+
+ public List<ApiRouteInfo> getAllApiRouteInstances(String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ try {
+ String apiRedisKey=RouteUtil.getMutiRedisKey(RouteUtil.APIROUTE, routeWay);
+
+ return ApiRouteService.getInstance().getMultiApiRouteInstances(apiRedisKey);
+
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+ }
+
+
+
+ /**
+ * @Title: getApiRouteInstance
+ * @Description: TODO(Through the name + version for a single service object information)
+ * @param: @param serviceName
+ * @param: @param version
+ * @param: @return
+ * @return: ApiRouteInfo
+ */
+ public ApiRouteInfo getApiRouteInstance(String serviceName, String version, String host,String publish_port,String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ if ("null".equals(version)) {
+ version = "";
+ }
+
+ RouteUtil.checkServiceNameAndVersion(serviceName,version);
+
+ String apiRedisPrefixedKey=RouteUtil.getAPIRedisPrefixedKey(serviceName, version, host, publish_port, routeWay);
+
+ ApiRouteInfo apiRouteInfo;
+ try {
+ apiRouteInfo = ApiRouteService.getInstance().getApiRouteInstance(apiRedisPrefixedKey);
+ } catch (Exception e) {
+ LOGGER.error("get ApiRouteInstance throw exception", e);
+ throw new ExtendedInternalServerErrorException("get ApiRouteInstance throw exception" + e.getMessage());
+ }
+
+
+
+ if (null == apiRouteInfo) {
+ throw new ExtendedNotFoundException("Api RouteInfo not found");
+ }
+
+ return apiRouteInfo;
+
+ }
+
+
+
+ /**
+ * @Title updateApiRouteStatus
+ * @Description TODO(update ApiRoute Status)
+ * @param serviceName
+ * @param version
+ * @param status
+ * @return
+ * @return RouteResult
+ */
+ public synchronized ApiRouteInfo updateApiRouteStatus(String serviceName, String version,String host,String publish_port,
+ String status,String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ if ("null".equals(version)) {
+ version = "";
+ }
+
+ RouteUtil.checkServiceNameAndVersion(serviceName,version);
+
+ RouteUtil.checkServiceStatus(status);
+
+
+ String apiRedisPrefixedKey=RouteUtil.getAPIRedisPrefixedKey(serviceName, version, host, publish_port, routeWay);
+
+ try {
+ ApiRouteService.getInstance().updateApiRouteStatus2Redis(apiRedisPrefixedKey, status);
+ } catch (Exception e) {
+ LOGGER.error("update ApiRoute status throw exception", e);
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+ ApiRouteInfo new_apiRouteInfo = getApiRouteInstance(serviceName, version,host,publish_port,routeWay);
+ return new_apiRouteInfo;
+ }
+
+
+ /**
+ * @Title: saveApiRouteInstance
+ * @Description: TODO(save ApiRouteInstance)
+ * @param: @param apiRouteInfo
+ * @param: @return
+ * @return: ApiRouteInfo
+ */
+ public synchronized ApiRouteInfo saveApiRouteInstance4Rest(ApiRouteInfo apiRouteInfo,String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ RouteUtil.checkRouterInfoFormat(apiRouteInfo);
+
+ try {
+ saveApiRouteInstance(apiRouteInfo,routeWay);
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException("save apiRouteInfo fail: [serviceName]"+apiRouteInfo.getServiceName()+"[version]"+apiRouteInfo.getVersion()+" [routeWay]"+routeWay+e.getMessage());
+ }
+
+ return apiRouteInfo;
+ }
+
+
+
+ public synchronized void saveApiRouteInstance(ApiRouteInfo apiRouteInfo,String routeWay) throws Exception {
+ try {
+ String apiRedisPrefixedKey=RouteUtil.getAPIRedisPrefixedKey(apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(), apiRouteInfo.getHost(), apiRouteInfo.getPublish_port(), routeWay);
+
+ ApiRouteService.getInstance().saveApiRouteService2Redis(apiRouteInfo, apiRedisPrefixedKey);
+ LOGGER.info("save apiRouteInfo [serviceName]"+apiRouteInfo.getServiceName()+"[version]"+apiRouteInfo.getVersion()+" [routeWay]"+routeWay+" success");
+ } catch (Exception e) {
+ LOGGER.error("save apiRouteInfo [serviceName]"+apiRouteInfo.getServiceName()+"[version]"+apiRouteInfo.getVersion()+" [routeWay]"+routeWay+" throw exception", e);
+ throw e;
+ }
+
+
+ }
+
+
+
+ /**
+ * @Title: deleteApiRoute
+ * @Description: TODO(delete one ApiRoute)
+ * @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 host,String publish_port,String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ if ("null".equals(version)) {
+ version = "";
+ }
+
+ RouteUtil.checkServiceNameAndVersion(serviceName,version);
+
+ String apiRedisPrefixedKey=RouteUtil.getAPIRedisPrefixedKey(serviceName, version, host, publish_port, routeWay);
+
+
+ try {
+ ApiRouteService.getInstance()
+ .deleteApiRouteService2Redis(apiRedisPrefixedKey);
+ LOGGER.info("delete apiRouteInfo [serviceName]"+serviceName+"[version]"+version+" [host]"+host +" [publish_port]"+publish_port+" [routeWay]"+routeWay+" success");
+
+ }
+ catch (ExtendedNotFoundException e) {
+ throw e;
+ }catch (Exception e) {
+ LOGGER.error("delete apiRouteInfo [serviceName]"+serviceName+"[version]"+version+" [host]"+host +" [publish_port]"+publish_port+" [routeWay]"+routeWay+" throw exception", e);
+
+ throw new ExtendedInternalServerErrorException("delete apiRouteInfo [serviceName]"+serviceName+"[version]"+version+e.getMessage());
+ }
+
+
+ }
+
+
+ /**
+ * @Title: getAllApiDocs
+ * @Description: TODO(For local ext\initSwaggerJson directory of all the json file directory)
+ * @param: @return
+ * @return: String[]
+ */
+ public String[] getAllApiDocs() {
+ URL apiDocsPath = ApiRouteServiceWrapper.class.getResource("/ext/initSwaggerJson");
+ if (apiDocsPath != null) {
+ String path = apiDocsPath.getPath();
+
+ try {
+ return FileUtil.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 getAllrouteByJson(String routeWay){
+
+ Object[] apirouteArray= ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(routeWay).toArray();
+ Object[] iuirouteArray= IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(routeWay).toArray();
+ Object[] customrouteArray= CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(routeWay).toArray();
+
+ Object[] temprouteArray =CommonUtil.concat(apirouteArray, iuirouteArray);
+ Object[] allrouteArray=CommonUtil.concat(temprouteArray, customrouteArray);
+
+
+ String allrouteJson;
+ try {
+ allrouteJson = JacksonJsonUtil.beanToJson(allrouteArray);
+ } catch (Exception e) {
+ LOGGER.error("exportService beanToJson throw Exception", e);
+ throw new ExtendedInternalServerErrorException("exportService beanToJson throw Exception:"+ e.getMessage());
+ }
+ return allrouteJson;
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapper.java
new file mode 100644
index 0000000..50747b6
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapper.java
@@ -0,0 +1,217 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper;
+
+import java.util.List;
+
+import org.onap.msb.apiroute.api.CustomRouteInfo;
+import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
+import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException;
+import org.onap.msb.apiroute.wrapper.service.CustomRouteService;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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(get AllCustomRoute Service)
+ * @param: @return
+ * @return: CustomRouteInfo[]
+ */
+ public List<CustomRouteInfo> getAllCustomRouteInstances(String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ try {
+ String customRedisKey = RouteUtil.getMutiRedisKey(RouteUtil.CUSTOMROUTE, routeWay);
+ return CustomRouteService.getInstance().getMultiCustomRouteInstances(customRedisKey);
+
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+
+ }
+
+
+
+ /**
+ * @Title: getCustomRouteInstance
+ * @Description: TODO(get CustomRouteInstance by serviceName)
+ * @param: @param serviceName
+ * @param: @return
+ * @return: CustomRouteInfo
+ */
+ public CustomRouteInfo getCustomRouteInstance(String serviceName, String host,
+ String publish_port, String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ String customRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE, serviceName, host, publish_port,
+ routeWay);
+
+ CustomRouteInfo customRouteInfo;
+ try {
+ customRouteInfo =
+ CustomRouteService.getInstance().getCustomRouteInstance(customRedisPrefixedKey);
+ } catch (Exception e) {
+ LOGGER.error("get customRouteInstance throw exception", e);
+ throw new ExtendedInternalServerErrorException("get customRouteInstance throw exception"+ e.getMessage());
+ }
+
+
+ if (null == customRouteInfo) {
+ throw new ExtendedNotFoundException("customRoute Info not found");
+
+ }
+
+ return customRouteInfo;
+
+ }
+
+
+ /**
+ * @Title updateCustomRouteStatus
+ * @Description TODO(update one CustomRoute Status)
+ * @param serviceName
+ * @param status
+ * @return
+ * @return RouteResult
+ */
+ public synchronized CustomRouteInfo updateCustomRouteStatus(String serviceName, String host,
+ String publish_port, String status, String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ RouteUtil.checkServiceStatus(status);
+
+ String customRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE, serviceName, host, publish_port,
+ routeWay);
+
+
+ try {
+ CustomRouteService.getInstance()
+ .updateCustomRouteStatus2Redis(customRedisPrefixedKey, status);
+ } catch (Exception e) {
+ LOGGER.error("update CustomRoute status throw exception", e);
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+ CustomRouteInfo new_customRouteInfo =
+ getCustomRouteInstance(serviceName, host, publish_port, routeWay);
+
+ return new_customRouteInfo;
+ }
+
+ /**
+ * @Title: saveCustomRouteInstance
+ * @Description: TODO(save one CustomRouteInstance)
+ * @param: @param CustomRouteInfo
+ * @param: @return
+ * @return: CustomRouteInfo
+ */
+ public synchronized CustomRouteInfo saveCustomRouteInstance4Rest(CustomRouteInfo customRouteInfo,
+ String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ RouteUtil.checkRouterInfoFormat(customRouteInfo);
+
+ try {
+ saveCustomRouteInstance(customRouteInfo, routeWay);
+
+ } catch (Exception e) {
+
+ throw new ExtendedInternalServerErrorException("save CustomRouteInfo fail: [serviceName]"+customRouteInfo.getServiceName()+e.getMessage());
+ }
+
+ return customRouteInfo;
+
+ }
+
+
+ public synchronized CustomRouteInfo saveCustomRouteInstance(CustomRouteInfo customRouteInfo,
+ String routeWay) throws Exception {
+ try {
+ String customRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE, customRouteInfo.getServiceName(),
+ customRouteInfo.getHost(), customRouteInfo.getPublish_port(), routeWay);;
+
+
+ CustomRouteService.getInstance().saveCustomRouteService2Redis(customRouteInfo,
+ customRedisPrefixedKey);
+ LOGGER.info("save CustomRouteInfo [serviceName]"+customRouteInfo.getServiceName()+" [host]"+customRouteInfo.getHost() +" [publish_port]"+customRouteInfo.getPublish_port()+" [routeWay]"+routeWay+" success");
+
+ } catch (Exception e) {
+ LOGGER.error("save CustomRouteInfo [serviceName]"+customRouteInfo.getServiceName()+" [host]"+customRouteInfo.getHost() +" [publish_port]"+customRouteInfo.getPublish_port()+" [routeWay]"+routeWay+" throw exception", e);
+
+ throw e;
+ }
+
+ return customRouteInfo;
+
+ }
+
+
+ /**
+ * @Title: deleteCustomRoute
+ * @Description: TODO(delete one CustomRoute)
+ * @param: @param type
+ * @param: @param serviceName
+ * @param: @param delKey
+ * @param: @return
+ * @return: void
+ */
+ public synchronized void deleteCustomRoute(String serviceName, String host, String publish_port,
+ String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ String customRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE, serviceName, host, publish_port,
+ routeWay);
+
+ try {
+ CustomRouteService.getInstance().deleteCustomRouteService2Redis(customRedisPrefixedKey);
+ LOGGER.info("delete CustomRouteInfo [serviceName]"+serviceName+" [host]"+host +" [publish_port]"+publish_port+" [routeWay]"+routeWay+" success");
+
+ } catch (ExtendedNotFoundException e) {
+ throw e;
+ } catch (Exception e) {
+ LOGGER.error("delete CustomRouteInfo [serviceName]"+serviceName+" [host]"+host +" [publish_port]"+publish_port+" [routeWay]"+routeWay+" throw exception", e);
+ throw new ExtendedInternalServerErrorException("delete CustomRouteInfo [serviceName]"+serviceName+e.getMessage());
+ }
+
+
+
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapper.java
new file mode 100644
index 0000000..76be3d2
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapper.java
@@ -0,0 +1,416 @@
+package org.onap.msb.apiroute.wrapper;
+
+import io.dropwizard.jetty.HttpConnectorFactory;
+import io.dropwizard.server.SimpleServerFactory;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.ApiRouteApp;
+import org.onap.msb.apiroute.ApiRouteAppConfig;
+import org.onap.msb.apiroute.SyncDataManager;
+import org.onap.msb.apiroute.api.ApiRouteInfo;
+import org.onap.msb.apiroute.api.CustomRouteInfo;
+import org.onap.msb.apiroute.api.DiscoverInfo;
+import org.onap.msb.apiroute.api.IuiRouteInfo;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException;
+import org.onap.msb.apiroute.health.ConsulLinkHealthCheck;
+import org.onap.msb.apiroute.health.RedisHealthCheck;
+import org.onap.msb.apiroute.wrapper.serviceListener.MicroServiceChangeListener;
+import org.onap.msb.apiroute.wrapper.serviceListener.RouteNotify;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.onap.msb.apiroute.wrapper.util.FileUtil;
+import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil;
+import org.onap.msb.apiroute.wrapper.util.JedisUtil;
+import org.onap.msb.apiroute.wrapper.util.RegExpTestUtil;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import redis.clients.jedis.Jedis;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+public class InitRouteServiceWrapper {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(InitRouteServiceWrapper.class);
+
+
+ private static InitRouteServiceWrapper instance = new InitRouteServiceWrapper();
+
+ private InitRouteServiceWrapper() {}
+
+ public static InitRouteServiceWrapper getInstance() {
+ return instance;
+ }
+
+
+ /**
+ * The listener registration service changes
+ */
+ public void registerServiceChangeListener() {
+
+ RouteNotify.getInstance().addServiceChangeListener(new MicroServiceChangeListener());
+
+ }
+
+ public void initFilterConfig(){
+ //route init
+ ConfigUtil.getInstance().initRouteWay();
+ ConfigUtil.getInstance().initApiGatewayPort();
+ ConfigUtil.getInstance().initRouteNameSpaceMatches();
+ ConfigUtil.getInstance().initRouteLabelsMatches();
+ ConfigUtil.getInstance().initNodeMetaQueryParam();
+
+ }
+
+ public void initDataSynchro(){
+
+ registerServiceChangeListener();
+
+ boolean ifRedisConnect=startCheckRedisConnect();
+
+ if(ifRedisConnect){
+ initRouteInfoFromJson();
+ runConsulClientApp();
+ }
+ }
+
+ public void initHealthCheck()
+ {
+ LOGGER.info("start check consul link thread");
+ Thread tConsul= new Thread(new ConsulLinkHealthCheck(),"_healthcheck_consul_");
+ tConsul.setDaemon(true);
+ tConsul.start();
+
+ LOGGER.info("start check redis thread");
+ Thread tRedies= new Thread(new RedisHealthCheck(),"_healthcheck_redis_");
+ tRedies.setDaemon(true);
+ tRedies.start();
+ }
+
+
+
+
+ public boolean startCheckRedisConnect() {
+
+ int n = 0;
+ while (true) {
+ if (!checkRedisConnect()) {
+ n++;
+ LOGGER.warn(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) {
+ LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit...");
+ return false;
+ }
+ } else {
+ LOGGER.warn(" Initial Route Configuration——redis connection success...");
+ return true;
+ }
+ }
+
+
+ }
+
+
+ // Open the consul to monitor subscription service
+ public void runConsulClientApp() {
+
+ String consulIP;
+ int consulPort;
+ String consulConfSource="Default";
+
+
+ DiscoverInfo discoverInfo = ConfigUtil.getInstance().getDiscoverInfo();
+
+ if (discoverInfo.isEnabled()) {
+ LOGGER.warn("starting to initial consul Configuration");
+ String[] routeWay = ConfigUtil.getInstance().getRouteWay();
+ try {
+ String sys_consulIp=ConfigUtil.getInstance().getConsul_ip();
+ if (StringUtils.isNotBlank(sys_consulIp)) {
+ consulIP = sys_consulIp.trim();
+ consulPort = RouteUtil.consulDeafultPort;
+ consulConfSource="env:CONSUL_IP";
+ } else {
+ consulIP = discoverInfo.getIp();
+ consulPort = discoverInfo.getPort();
+ consulConfSource="init discoverInfo";
+ }
+
+ LOGGER.warn("init consul sync Address from [ "+consulConfSource+" ]:" + consulIP + ":" + consulPort);
+
+ // 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");
+ discoverApiService.setHost("msb");
+
+ RouteServer[] servers = new RouteServer[1];
+ servers[0] = new RouteServer(discoverInfo.getIp(), String.valueOf(discoverInfo.getPort()));
+ discoverApiService.setServers(servers);
+
+
+ for (int i = 0; i < routeWay.length; i++) {
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance4Rest(discoverApiService,
+ routeWay[i]);
+ }
+
+
+
+ // iui
+ IuiRouteInfo discoverIUIService = new IuiRouteInfo();
+ discoverIUIService.setServiceName("msdiscover");
+ discoverIUIService.setUrl("/iui/microservices");
+ discoverIUIService.setHost("msb");
+ discoverIUIService.setServers(servers);
+
+ for (int i = 0; i < routeWay.length; i++) {
+ IuiRouteServiceWrapper.getInstance()
+ .saveIuiRouteInstance(discoverIUIService, routeWay[i]);
+ }
+
+
+ /*
+ * ConsulClientApp consulClientApp = new ConsulClientApp(consulIP, consulPort);
+ * consulClientApp.startServiceListen();
+ */
+
+ // SyncDataManager syncDataManager = new SyncDataManager();
+ // Monitor serviceList change
+ SyncDataManager.initSyncTask(consulIP, consulPort);
+
+
+ LOGGER.warn("start monitor consul service--" + consulIP + ":" + consulPort);
+ } catch (Exception e) {
+ LOGGER.error("start monitor consul service fail:" + e.getMessage());
+ }
+ }
+
+
+
+ }
+
+
+
+ /**
+ * @Title: initRouteInfoFromJson
+ * @Description: TODO(According to the JSON file configuration initialization route data)
+ * @return: void
+ */
+ public void initRouteInfoFromJson() {
+ LOGGER.info("starting to initial Route Configuration");
+ URL apiDocsPath = InitRouteServiceWrapper.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) {
+
+ String[] routeWay = ConfigUtil.getInstance().getRouteWay();
+ String iuiRootPath = ConfigUtil.getInstance().getIUI_ROOT_PATH();
+
+ try {
+ List<ApiRouteInfo> routeList =
+ JacksonJsonUtil.jsonToListBean(fileContent, new TypeReference<List<ApiRouteInfo>>() {});
+ for (ApiRouteInfo route : routeList) {
+ String url = route.getUrl();
+
+ if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) {
+
+ for (int i = 0; i < routeWay.length; i++) {
+ try {
+
+ CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(
+ route.getServiceName(), route.getHost(), "", routeWay[i]);
+
+ } 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());
+ customRouteInfo.setHost(route.getHost());
+
+
+
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfo,
+ routeWay[i]);
+
+ }
+ }
+ } else {
+
+ if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/") || url.startsWith("/admin/microservices/")) {
+
+ for (int i = 0; i < routeWay.length; i++) {
+ try {
+
+ ApiRouteServiceWrapper.getInstance().getApiRouteInstance(route.getServiceName(),
+ route.getVersion(), route.getHost(), route.getPublish_port(), routeWay[i]);
+
+ } catch (ExtendedNotFoundException e) {
+ LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName());
+
+ if (url.startsWith("/api/microservices")) {
+ if (StringUtils.isNotBlank(System.getenv("dwApp_server_connector_port"))) {
+ replaceApigatewayPort(route.getServers(),
+ System.getenv("dwApp_server_connector_port"));
+ }
+ }
+
+ if (url.startsWith("/admin/microservices")) {
+ replaceApigatewayPort(route.getServers(),ConfigUtil.getInstance().getServerPort());
+ }
+
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance4Rest(route, routeWay[i]);
+
+ }
+ }
+
+
+ } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) {
+
+ for (int i = 0; i < routeWay.length; i++) {
+ try {
+
+ IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(route.getServiceName(),
+ route.getHost(), "", routeWay[i]);
+
+ } 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());
+ iuiRouteInfo.setHost(route.getHost());
+
+
+ if (url.equals("/iui/microservices")) {
+ iuiRouteInfo.setUrl("/" + iuiRootPath + "/microservices");
+ if (StringUtils.isNotBlank(System.getenv("dwApp_server_connector_port"))) {
+ replaceApigatewayPort(iuiRouteInfo.getServers(),
+ System.getenv("dwApp_server_connector_port"));
+ }
+ } else {
+ iuiRouteInfo.setUrl(route.getUrl());
+ }
+
+ IuiRouteServiceWrapper.getInstance()
+ .saveIuiRouteInstance(iuiRouteInfo, routeWay[i]);
+
+
+ }
+ }
+
+ } 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);
+ }
+
+ }
+
+ private void replaceApigatewayPort(RouteServer[] servers, String apigatewayPort) {
+ for (int i = 0; i < servers.length; i++) {
+ servers[i].setPort(apigatewayPort);
+ }
+ }
+
+ public void initMetricsConfig(ApiRouteAppConfig configuration) {
+
+ SimpleServerFactory simpleServerFactory =
+ (SimpleServerFactory) configuration.getServerFactory();
+ HttpConnectorFactory httpConnectorFactory =
+ (HttpConnectorFactory) simpleServerFactory.getConnector();
+ String metricsUrl =
+ "http://127.0.0.1:" + httpConnectorFactory.getPort()
+ + simpleServerFactory.getAdminContextPath() + "/metrics";
+ ConfigUtil.getInstance().setMetricsUrl(metricsUrl);
+ }
+
+
+ private boolean checkRedisConnect() {
+ Jedis jedis = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ return true;
+ } catch (Exception e) {
+ LOGGER.error("checkRedisConnect call redis throw exception", e);
+ }finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+
+ return false;
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapper.java
new file mode 100644
index 0000000..d66de21
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapper.java
@@ -0,0 +1,221 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper;
+
+import java.util.List;
+
+import org.onap.msb.apiroute.api.IuiRouteInfo;
+import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
+import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException;
+import org.onap.msb.apiroute.wrapper.service.IuiRouteService;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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(get All IuiRouteServices)
+ * @param: @return
+ * @return: IuiRouteInfo[]
+ */
+ public List<IuiRouteInfo> getAllIuiRouteInstances(String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ try {
+ String iuiRedisKey = RouteUtil.getMutiRedisKey(RouteUtil.IUIROUTE, routeWay);
+
+ return IuiRouteService.getInstance().getMultiIuiRouteInstances(iuiRedisKey);
+
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+
+ }
+
+
+
+ /**
+ * @Title: getIuiRouteInstance
+ * @Description: TODO(get one IuiRouteInstance by serviceName)
+ * @param: @param serviceName
+ * @param: @return
+ * @return: IuiRouteInfo
+ */
+ public IuiRouteInfo getIuiRouteInstance(String serviceName, String host, String publish_port,
+ String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ String iuiRedisPrefixedKey =
+ RouteUtil
+ .getRedisPrefixedKey(RouteUtil.IUIROUTE, serviceName, host, publish_port, routeWay);
+
+ IuiRouteInfo iuiRouteInfo;
+ try {
+ iuiRouteInfo = IuiRouteService.getInstance().getIuiRouteInstance(iuiRedisPrefixedKey);
+ } catch (Exception e) {
+ LOGGER.error("get IuiRouteInstance throw exception", e);
+ throw new ExtendedInternalServerErrorException("get IuiRouteInstance throw exception"
+ + e.getMessage());
+ }
+
+
+
+ if (null == iuiRouteInfo) {
+ throw new ExtendedNotFoundException("iui RouteInfo not found");
+ }
+
+ return iuiRouteInfo;
+ }
+
+
+
+ /**
+ * @Title updateIuiRouteStatus
+ * @Description TODO(update one IuiRoute Status)
+ * @param serviceName
+ * @param status
+ * @return
+ * @return RouteResult
+ */
+ public synchronized IuiRouteInfo updateIuiRouteStatus(String serviceName, String host,
+ String publish_port, String status, String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ RouteUtil.checkServiceStatus(status);
+
+ try {
+ String iuiRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.IUIROUTE, serviceName, host, publish_port,
+ routeWay);
+
+ IuiRouteService.getInstance().updateIuiRouteStatus2Redis(iuiRedisPrefixedKey, status);
+
+
+ } catch (Exception e) {
+ LOGGER.error("update IuiRoute status throw exception", e);
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+ IuiRouteInfo new_iuiRouteInfo = getIuiRouteInstance(serviceName, host, publish_port, routeWay);
+
+ return new_iuiRouteInfo;
+ }
+
+ /**
+ * @Title: saveIuiRouteInstance
+ * @Description: TODO(save one IuiRouteInstance)
+ * @param: @param IuiRouteInfo
+ * @param: @return
+ * @return: IuiRouteInfo
+ */
+ public synchronized IuiRouteInfo saveIuiRouteInstance4Rest(IuiRouteInfo iuiRouteInfo,
+ String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ RouteUtil.checkRouterInfoFormat(iuiRouteInfo);
+
+
+ try {
+ saveIuiRouteInstance(iuiRouteInfo, routeWay);
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException("save iuiRouteInfo fail: [serviceName]"
+ + iuiRouteInfo.getServiceName() + e.getMessage());
+ }
+
+ return iuiRouteInfo;
+ }
+
+
+ public synchronized void saveIuiRouteInstance(IuiRouteInfo iuiRouteInfo, String routeWay)
+ throws Exception {
+ try {
+ String iuiRedisPrefixedKey =
+ RouteUtil.getRedisPrefixedKey(RouteUtil.IUIROUTE, iuiRouteInfo.getServiceName(),
+ iuiRouteInfo.getHost(), iuiRouteInfo.getPublish_port(), routeWay);
+
+ IuiRouteService.getInstance().saveIuiRouteService2Redis(iuiRouteInfo, iuiRedisPrefixedKey);
+ LOGGER.info("save iuiRouteInfo [serviceName]" + iuiRouteInfo.getServiceName() + " [host]"
+ + iuiRouteInfo.getHost() + " [publish_port]" + iuiRouteInfo.getPublish_port()
+ + " [routeWay]" + routeWay + " success");
+
+ } catch (Exception e) {
+ LOGGER.error("save iuiRouteInfo [serviceName]" + iuiRouteInfo.getServiceName() + " [host]"
+ + iuiRouteInfo.getHost() + " [publish_port]" + iuiRouteInfo.getPublish_port()
+ + " [routeWay]" + routeWay + " throw exception", e);
+ throw e;
+ }
+ }
+
+
+
+ /**
+ * @Title: deleteIuiRoute
+ * @Description: TODO(delete one IuiRoute)
+ * @param: @param type
+ * @param: @param serviceName
+ * @param: @param delKey
+ * @param: @return
+ * @return: void
+ */
+ public synchronized void deleteIuiRoute(String serviceName, String host, String publish_port,
+ String routeWay) {
+
+ RouteUtil.checkRouteWay(routeWay);
+
+ String iuiRedisPrefixedKey =
+ RouteUtil
+ .getRedisPrefixedKey(RouteUtil.IUIROUTE, serviceName, host, publish_port, routeWay);
+
+ try {
+ IuiRouteService.getInstance().deleteIuiRouteService2Redis(iuiRedisPrefixedKey);
+ LOGGER.info("delete iuiRouteInfo [serviceName]" + serviceName + " [host]" + host
+ + " [publish_port]" + publish_port + " [routeWay]" + routeWay + " success");
+
+ } catch (ExtendedNotFoundException e) {
+ throw e;
+ } catch (Exception e) {
+ LOGGER.error("delete iuiRouteInfo [serviceName]" + serviceName + " [host]" + host
+ + " [publish_port]" + publish_port + " [routeWay]" + routeWay + " throw exception", e);
+ throw new ExtendedInternalServerErrorException("delete iuiRouteInfo [serviceName]" + serviceName +e.getMessage());
+ }
+
+
+
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapper.java
new file mode 100644
index 0000000..a30151e
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapper.java
@@ -0,0 +1,398 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.Node;
+import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
+import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException;
+import org.onap.msb.apiroute.api.exception.UnprocessableEntityException;
+import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper;
+import org.onap.msb.apiroute.wrapper.service.MicroServiceFullService;
+import org.onap.msb.apiroute.wrapper.serviceListener.RouteNotify;
+import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil;
+import org.onap.msb.apiroute.wrapper.util.RegExpTestUtil;
+import org.onap.msb.apiroute.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 List<MicroServiceFullInfo> getAllMicroServiceInstances() {
+
+ try {
+ return MicroServiceFullService.getInstance().getAllMicroServiceInstances();
+
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+ }
+
+ public Set<String> getAllMicroServiceKey() {
+ int failedNum = 0;
+ int retryCount=3;
+ int failedTimer = 5 * 1000;
+
+ Set<String> serviceKeys=null;
+
+ do {
+
+ try {
+ serviceKeys= MicroServiceFullService.getInstance().getAllMicroServiceKey();
+ break;
+
+ } catch (Exception e) {
+
+ LOGGER.error(failedNum + "/"+retryCount+" : get AllMicroServiceKey fail"+e);
+ failedNum++;
+
+ try {
+ Thread.sleep(failedTimer);
+ } catch (InterruptedException ex) {
+ LOGGER.warn("get AllMicroServiceKey Thread.sleep throw except:" + ex.getMessage());
+ }
+ }
+
+ }while (failedNum <= retryCount);
+
+
+ return serviceKeys;
+
+ }
+
+
+
+
+ /**
+ * @Title: getMicroServiceInstance
+ * @Description: (getMicroServiceInstance)
+ * @param: @param serviceName
+ * @param: @param version
+ * @param: @return
+ * @return: ApiRouteInfo
+ */
+ public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version) {
+ if ("null".equals(version)) {
+ version = "";
+ }
+ serviceName = serviceName.replace("*", "/");
+
+ RouteUtil.checkServiceNameAndVersion(serviceName, version);
+
+ MicroServiceFullInfo microServiceInfo;
+ try {
+ microServiceInfo =
+ MicroServiceFullService.getInstance().getMicroServiceInstance(serviceName, version);
+
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException(e.getMessage());
+ }
+
+ if (null == microServiceInfo) {
+ String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version;
+ throw new ExtendedNotFoundException(errInfo);
+
+ }
+
+ return microServiceInfo;
+ }
+
+
+
+ /**
+ * @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("*", "/");
+
+ RouteUtil.checkServiceNameAndVersion(serviceName, version);
+
+ RouteUtil.checkServiceStatus(status);
+
+ try {
+
+ MicroServiceFullService.getInstance().updateMicroServiceStatus(serviceName, version, status);
+
+ MicroServiceFullInfo newMicroServiceInfo =
+ MicroServiceFullService.getInstance().getMicroServiceInstance(serviceName, version);
+
+ // Notify the listeners
+ RouteNotify.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(
+ MicroServiceFullInfo microServiceInfo, boolean createOrUpdate, String requestIP,
+ String serverPort) {
+
+ RouteUtil.checkMicroServiceInfoFormat(microServiceInfo, requestIP);
+
+ try {
+
+ if (createOrUpdate == false) {
+ deleteServiceAndnoticeRoute(microServiceInfo);
+ }
+
+ saveServiceAndnoticeRoute(microServiceInfo);
+
+
+ MicroServiceFullInfo newMicroServiceInfo =
+ MicroServiceFullService.getInstance().getMicroServiceInstance(
+ microServiceInfo.getServiceName(), microServiceInfo.getVersion());
+
+
+ return newMicroServiceInfo;
+
+ } catch (UnprocessableEntityException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException("save MicroServiceInfo fail :[serviceName]" + microServiceInfo.getServiceName()
+ + "[version]" + microServiceInfo.getVersion()+ e.getMessage());
+ }
+
+ }
+
+
+ public synchronized void deleteMicroService4AllVersion(String serviceName) {
+ try {
+
+ List<MicroServiceFullInfo> microServiceList4AllVersion =
+ MicroServiceFullService.getInstance().getAllVersionsOfTheService(serviceName);
+
+ if (microServiceList4AllVersion.size() == 0) {
+ LOGGER.info("delete MicroServiceInfo for All Version Fail:serviceName-" + serviceName
+ + " not fond");
+ } else {
+ for (MicroServiceFullInfo microServiceInfo : microServiceList4AllVersion) {
+ deleteServiceAndnoticeRoute(microServiceInfo);
+ }
+ }
+
+ } catch (Exception e) {
+ LOGGER.error("delete MicroServiceInfo for all version :serviceName-" + serviceName +" throw exception", e);
+
+ }
+ }
+
+
+ public synchronized void deleteMicroService(String serviceName, String version) {
+ if ("null".equals(version)) {
+ version = "";
+ }
+ serviceName = serviceName.replace("*", "/");
+
+ RouteUtil.checkServiceNameAndVersion(serviceName, version);
+
+ try {
+
+ MicroServiceFullInfo microServiceInfo =
+ MicroServiceFullService.getInstance().getMicroServiceInstance(serviceName, version);
+
+ if (microServiceInfo == null) {
+ LOGGER.error("delete MicroServiceInfo FAIL:serviceName-" + serviceName + ",version-"+ version + " not fond ");
+ } else {
+
+ deleteServiceAndnoticeRoute(microServiceInfo);
+ }
+
+
+ } catch (ExtendedNotFoundException e) {
+ throw e;
+ } catch (Exception e) {
+
+ throw new ExtendedInternalServerErrorException("delete MicroServiceInfo serviceName-" + serviceName + ",version-" + version+e.getMessage());
+
+ }
+
+
+ }
+
+ public synchronized void deleteMicroServiceInstance(String serviceName, String version,
+ String ip, String port) {
+ if ("null".equals(version)) {
+ version = "";
+ }
+ serviceName = serviceName.replace("*", "/");
+
+ RouteUtil.checkServiceNameAndVersion(serviceName, version);
+
+ if (!RegExpTestUtil.ipRegExpTest(ip)) {
+ throw new UnprocessableEntityException("delete MicroServiceInfo FAIL:IP(" + ip+ ")is not a valid IP address");
+ }
+
+ if (!RegExpTestUtil.portRegExpTest(port)) {
+ throw new UnprocessableEntityException("delete MicroServiceInfo FAIL:Port(" + port + ")is not a valid Port address");
+ }
+
+
+ try {
+ MicroServiceFullInfo microServiceInfo =
+ MicroServiceFullService.getInstance().getMicroServiceInstance(serviceName, version);
+
+ if (microServiceInfo == null) {
+ throw new UnprocessableEntityException("delete MicroServiceInfo FAIL:serviceName-"+ serviceName + ",version-" + version + " not fond ");
+ }
+
+ Set<Node> 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
+ deleteServiceAndnoticeRoute(microServiceInfo);
+ } else {
+ // delete Node
+ MicroServiceFullService.getInstance().saveMicroServiceInfo2Redis(microServiceInfo);
+ RouteNotify.getInstance().noticeRouteListener4Update(serviceName, version,
+ microServiceInfo);
+ }
+
+ break;
+ }
+ }
+
+ if (!ifFindBNode) {
+ throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-"+ serviceName + ",version-" + version +",node-" + ip + ":" + port + " not fond ");
+ }
+
+
+ } catch (ExtendedNotFoundException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ExtendedInternalServerErrorException("delete MicroServiceInfo :serviceName-"+ serviceName + ",version-" + version+",node-" + ip + ":" + port +"throw exception"+e.getMessage());
+
+ }
+
+ }
+
+
+ public void deleteServiceAndnoticeRoute(MicroServiceFullInfo service) throws Exception {
+
+ try {
+ // Delete the redis record
+ MicroServiceFullService.getInstance().deleteMicroService(service.getServiceName(),
+ service.getVersion());
+ LOGGER.info("delete MicroServiceInfo And notice to Route success:[serviceName]"+ service.getServiceName() + "[version]" + service.getVersion());
+
+ // Notify the listeners
+ RouteNotify.getInstance().noticeRouteListener4Delete(service);
+
+ } catch (Exception e) {
+ LOGGER.error("delete MicroService And synchro to Route:[serviceName]"+ service.getServiceName() + "[version]" + service.getVersion()+" throw exception", e);
+ throw e;
+ }
+ }
+
+ public void saveServiceAndnoticeRoute(MicroServiceFullInfo service) throws Exception {
+
+ try {
+ // save the redis record
+ MicroServiceFullService.getInstance().saveMicroServiceInfo2Redis(service);
+
+ LOGGER.info("save MicroServiceInfo And notice to Route success:[serviceName]"+ service.getServiceName() + "[version]" + service.getVersion());
+
+ // Notify the listeners
+ RouteNotify.getInstance().noticeRouteListener4Add(service);
+
+
+ } catch (Exception e) {
+ LOGGER.error("save MicroServiceInfo And synchro to Route fail :[serviceName]" + service.getServiceName()+ "[version]" + service.getVersion() + " throw exception", e);
+ throw e;
+ }
+ }
+
+ public Set<String> getAllVersion(String serviceName) {
+ Set<String> serviceVersionSet = new HashSet<String>();
+ try {
+ String pattern = MicroServiceUtil.getServiceKey(serviceName, "*");
+ Set<String> serviceKeySet = RedisAccessWrapper.filterKeys(pattern);
+
+
+ Pattern serviceKeyRegexPattern = MicroServiceUtil.getServiceKeyRegexPattern();
+ for (String serviceKey : serviceKeySet) {
+ Matcher matcher = serviceKeyRegexPattern.matcher(serviceKey);
+ if (matcher.matches()) {
+ serviceVersionSet.add(matcher.group("version"));
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("getAllVersion [serviceName]:" + serviceName + " throw exception", e);
+ }
+
+ return serviceVersionSet;
+
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/CatalogClient.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/CatalogClient.java
new file mode 100644
index 0000000..94a709d
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/CatalogClient.java
@@ -0,0 +1,87 @@
+package org.onap.msb.apiroute.wrapper.consulextend;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+import org.onap.msb.apiroute.wrapper.consulextend.util.Http;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+/**
+ * HTTP Client for /v1/catalog/ endpoints.
+ */
+public class CatalogClient {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(CatalogClient.class);
+
+ private static final TypeReference<HttpEntity> TYPE_SERVICES_MAP = new TypeReference<HttpEntity>() {
+ };
+
+
+ private static final String CATALOG_URI_8500 = "/v1/catalog";
+ private static final String CATAlOG_URI_10081 = "/api/catalog/v1";
+
+ private static final String GET_SERVICES_URI = "/services";
+
+ private static final Http httpClient = Http.getInstance();
+
+ private HttpHost targetHost = null;
+ private String catalogUri = CATAlOG_URI_10081;
+
+ CatalogClient(final HttpHost targetHost) {
+ this.targetHost = targetHost;
+ if (targetHost.getPort() == 8500) {
+ catalogUri = CATALOG_URI_8500;
+ }
+ }
+
+ /**
+ * Retrieves all services for a given datacenter with
+ * {@link com.orbitz.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 com.orbitz.consul.model.ConsulResponse} containing a map
+ * of service name to list of tags.
+ */
+ public void getServices(CatalogOptions catalogOptions,
+ QueryOptions queryOptions,
+ ConsulResponseCallback<HttpEntity> callback) {
+
+ // prepare access path
+ // path:10081 vs 8500
+ String path = targetHost.toString() + catalogUri + GET_SERVICES_URI;
+
+ // params:wait,index,dc......
+ String params = Http.optionsFrom(catalogOptions, queryOptions);
+
+ // node meta: ns,external,internal.....
+ String node_meta = ConfigUtil.getInstance().getNodeMetaQueryParam();
+
+ // add params
+ path = (params != null && !params.isEmpty()) ? path += "?" + params
+ : path;
+
+ // add node_meta
+ if (node_meta != null && !node_meta.isEmpty()) {
+ path = path.contains("?") ? path +"&"+ node_meta : path + "?"
+ + node_meta;
+ }
+
+ // async watch services
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("get all services:" + path);
+ }
+ httpClient.asyncGetDelayHandle(path, TYPE_SERVICES_MAP, callback);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/Consul.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/Consul.java
new file mode 100644
index 0000000..cf8196a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/Consul.java
@@ -0,0 +1,97 @@
+package org.onap.msb.apiroute.wrapper.consulextend;
+
+import org.apache.http.HttpHost;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+
+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 static final Logger LOGGER = LoggerFactory
+ .getLogger(Consul.class);
+
+ private final CatalogClient catalogClient;
+ private final HealthClient healthClient;
+
+ private Consul(CatalogClient catalogClient, HealthClient healthClient) {
+ this.catalogClient = catalogClient;
+ this.healthClient = healthClient;
+ }
+
+ /**
+ * Get the Catalog HTTP client.
+ * <p>
+ * /v1/catalog
+ *
+ * @return The Catalog HTTP client.
+ */
+ public CatalogClient catalogClient() {
+ return catalogClient;
+ }
+
+ /**
+ * Get the Health HTTP client.
+ * <p>
+ * /v1/health
+ *
+ * @return The Health HTTP client.
+ */
+ public HealthClient healthClient() {
+ return healthClient;
+ }
+
+ /**
+ * Creates a new {@link Builder} object.
+ *
+ * @return A new Consul builder.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Used to create a default Consul client.
+ *
+ * @return A default {@link Consul} client.
+ */
+ @VisibleForTesting
+ public static Consul newClient() {
+ return builder().build();
+ }
+
+ public static class Builder {
+
+ private HttpHost targetHost;
+
+ {
+ targetHost = new HttpHost(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT);
+ }
+
+ Builder() {
+
+ }
+
+ public Builder withHostAndPort(String hostname, int port) {
+ this.targetHost = new HttpHost(hostname, port);
+ return this;
+ }
+
+ public Consul build() {
+ LOGGER.info("********build consul:"+targetHost.toString()+"****************");
+ CatalogClient catalogClient = new CatalogClient(targetHost);
+ HealthClient healthClient = new HealthClient(targetHost);
+ return new Consul(catalogClient,healthClient);
+ }
+
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/HealthClient.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/HealthClient.java
new file mode 100644
index 0000000..899a57a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/HealthClient.java
@@ -0,0 +1,112 @@
+package org.onap.msb.apiroute.wrapper.consulextend;
+
+import java.util.List;
+
+import org.apache.http.HttpHost;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.consulextend.util.Http;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+/**
+ * HTTP Client for /v1/health/ endpoints.
+ */
+public class HealthClient {
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(HealthClient.class);
+
+ private static final TypeReference<List<ServiceHealth>> TYPE_SERVICE_HEALTH_LIST = new TypeReference<List<ServiceHealth>>() {
+ };
+
+ private static final String HEALTH_URI_10081 = "/api/health/v1";
+ private static final String HEALTH_URI_8500 = "/v1/health";
+ private static final String GET_HEALTH_SERVICE_URI = "/service";
+
+// private static final String GET_HEALTH_SERVICE_URI = "/v1/health/service";
+
+// private static final String GET_HEALTH_SERVICE_URI = "/api/health/v1/service";
+
+ private final static Http httpClient = Http.getInstance();
+
+ private HttpHost targetHost = null;
+ private String healthUri = HEALTH_URI_10081;
+
+ HealthClient(final HttpHost targetHost) {
+ this.targetHost = targetHost;
+
+ if(targetHost.getPort() == 8500)
+ {
+ healthUri = HEALTH_URI_8500;
+ }
+ }
+
+ /**
+ * Asynchronously retrieves the healthchecks for all healthy service
+ * instances in a given datacenter with
+ * {@link com.orbitz.consul.option.QueryOptions}.
+ *
+ * GET /v1/health/service/{service}?dc={datacenter}&amp;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<List<ServiceHealth>> callback) {
+ // prepare access path
+ String path = targetHost.toString() + healthUri + GET_HEALTH_SERVICE_URI + "/"+ service;
+
+ String params = Http.optionsFrom(catalogOptions, queryOptions);
+ path = (params != null && !params.isEmpty()) ? path += "?"
+ + params : path; //query all nodes without filter for health
+
+ // async watch
+// LOGGER.info("get health paasing service:" + path);
+ httpClient.asyncGetDelayHandle(path, TYPE_SERVICE_HEALTH_LIST, callback);
+ }
+
+ /**
+ * Asynchronously retrieves the healthchecks for all nodes in a given
+ * datacenter with {@link com.orbitz.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<List<ServiceHealth>> callback) {
+
+ // prepare access path
+ String path = targetHost.toString() + healthUri + GET_HEALTH_SERVICE_URI + "/"+ service;
+ String params = Http.optionsFrom(catalogOptions, queryOptions);
+ path = (params != null && !params.isEmpty()) ? path += "?" + params
+ : path;
+
+ // async watch
+// LOGGER.debug("get service:" + path);
+ httpClient.asyncGetDelayHandle(path, TYPE_SERVICE_HEALTH_LIST, callback);
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseCallback.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseCallback.java
new file mode 100644
index 0000000..ab5b74a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseCallback.java
@@ -0,0 +1,33 @@
+package org.onap.msb.apiroute.wrapper.consulextend.async;
+
+import com.orbitz.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 <T> The Response type.
+ */
+public interface ConsulResponseCallback<T> {
+
+ /**
+ * Callback for a successful {@link com.orbitz.consul.model.ConsulResponse}.
+ *
+ * @param consulResponse The Consul response.
+ */
+ void onComplete(ConsulResponse<T> consulResponse);
+
+ /**
+ * Callback for a successful {@link com.orbitz.consul.model.ConsulResponse}.
+ *
+ * @param consulResponse The Consul response.
+ */
+ void onDelayComplete(OriginalConsulResponse<T> originalConsulResponse);
+
+ /**
+ * Callback for an unsuccessful request.
+ *
+ * @param throwable The exception thrown.
+ */
+ void onFailure(Throwable throwable);
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseHeader.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseHeader.java
new file mode 100644
index 0000000..ae8291a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseHeader.java
@@ -0,0 +1,27 @@
+package org.onap.msb.apiroute.wrapper.consulextend.async;
+
+import java.math.BigInteger;
+
+public class ConsulResponseHeader {
+ private final long lastContact;
+ private final boolean knownLeader;
+ private final BigInteger index;
+
+ public ConsulResponseHeader(long lastContact, boolean knownLeader, BigInteger index) {
+ this.lastContact = lastContact;
+ this.knownLeader = knownLeader;
+ this.index = index;
+ }
+
+ public long getLastContact() {
+ return lastContact;
+ }
+
+ public boolean isKnownLeader() {
+ return knownLeader;
+ }
+
+ public BigInteger getIndex() {
+ return index;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/OriginalConsulResponse.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/OriginalConsulResponse.java
new file mode 100644
index 0000000..dbad13b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/OriginalConsulResponse.java
@@ -0,0 +1,27 @@
+package org.onap.msb.apiroute.wrapper.consulextend.async;
+
+import org.apache.http.HttpResponse;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+public class OriginalConsulResponse<T> {
+ final HttpResponse response;
+ final TypeReference<T> responseType;
+
+ public OriginalConsulResponse(HttpResponse response, TypeReference<T> responseType) {
+ this.response = response;
+ this.responseType = responseType;
+
+ }
+
+ public HttpResponse getResponse() {
+ return response;
+ }
+
+ public TypeReference<T> getResponseType() {
+ return responseType;
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ConsulCache.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ConsulCache.java
new file mode 100644
index 0000000..809a8dc
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ConsulCache.java
@@ -0,0 +1,301 @@
+package org.onap.msb.apiroute.wrapper.consulextend.cache;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+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.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseHeader;
+import org.onap.msb.apiroute.wrapper.consulextend.async.OriginalConsulResponse;
+import org.onap.msb.apiroute.wrapper.consulextend.util.Http;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.orbitz.consul.ConsulException;
+import com.orbitz.consul.model.ConsulResponse;
+import com.orbitz.consul.option.ImmutableQueryOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+/**
+ * A cache structure that can provide an up-to-date read-only map backed by
+ * consul data
+ *
+ * @param <V>
+ */
+public class ConsulCache<T> {
+
+ enum State {
+ latent, starting, started, stopped
+ }
+
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(ConsulCache.class);
+
+ @VisibleForTesting
+ static final String BACKOFF_DELAY_PROPERTY = "com.orbitz.consul.cache.backOffDelay";
+ private static final long BACKOFF_DELAY_QTY_IN_MS = getBackOffDelayInMs(System
+ .getProperties());
+
+ private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(
+ null);
+ private final AtomicReference<State> state = new AtomicReference<State>(
+ State.latent);
+ private final CountDownLatch initLatch = new CountDownLatch(1);
+ private final ScheduledExecutorService executorService = Executors
+ .newSingleThreadScheduledExecutor();
+ private final CopyOnWriteArrayList<Listener<T>> listeners = new CopyOnWriteArrayList<Listener<T>>();
+
+ private final CallbackConsumer<T> callBackConsumer;
+ private final ConsulResponseCallback<T> responseCallback;
+
+ ConsulCache(CallbackConsumer<T> callbackConsumer) {
+
+ this.callBackConsumer = callbackConsumer;
+
+ this.responseCallback = new ConsulResponseCallback<T>() {
+ @Override
+ public void onComplete(ConsulResponse<T> consulResponse) {
+
+ if (consulResponse.isKnownLeader()) {
+ if (!isRunning()) {
+ return;
+ }
+ updateIndex(consulResponse);
+
+ for (Listener<T> l : listeners) {
+ l.notify(consulResponse);
+ }
+
+ if (state.compareAndSet(State.starting, State.started)) {
+ initLatch.countDown();
+ }
+
+ runCallback();
+ } else {
+ onFailure(new ConsulException(
+ "Consul cluster has no elected leader"));
+ }
+ }
+
+ @Override
+ public void onDelayComplete(
+ OriginalConsulResponse<T> originalConsulResponse) {
+
+ try {
+ // get header
+ ConsulResponseHeader consulResponseHeader = Http
+ .consulResponseHeader(originalConsulResponse
+ .getResponse());
+
+ if (consulResponseHeader.isKnownLeader()) {
+ if (!isRunning()) {
+ return;
+ }
+
+ boolean isConuslIndexChanged = isConuslIndexChanged(consulResponseHeader
+ .getIndex());
+ // consul index different
+ if (isConuslIndexChanged) {
+
+ updateIndex(consulResponseHeader.getIndex());
+
+ // get T type data
+ ConsulResponse<T> consulResponse = Http
+ .consulResponse(originalConsulResponse
+ .getResponseType(),
+ originalConsulResponse
+ .getResponse());
+
+ // notify customer to custom T data
+ for (Listener<T> l : listeners) {
+ l.notify(consulResponse);
+ }
+ }
+
+ if (state.compareAndSet(State.starting, State.started)) {
+ initLatch.countDown();
+ }
+
+ runCallback();
+
+ } else {
+ onFailure(new ConsulException(
+ "Consul cluster has no elected leader"));
+ }
+ } catch (Exception e) {
+ onFailure(e);
+ }
+
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+
+ if (!isRunning()) {
+ return;
+ }
+ LOGGER.error(
+ String.format(
+ "Error getting response from consul. will retry in %d %s",
+ BACKOFF_DELAY_QTY_IN_MS, TimeUnit.MILLISECONDS),
+ throwable);
+
+ executorService.schedule(new Runnable() {
+ @Override
+ public void run() {
+ runCallback();
+ }
+ }, BACKOFF_DELAY_QTY_IN_MS, TimeUnit.MILLISECONDS);
+ }
+ };
+ }
+
+ @VisibleForTesting
+ static long getBackOffDelayInMs(Properties properties) {
+ String backOffDelay = null;
+ try {
+ backOffDelay = properties.getProperty(BACKOFF_DELAY_PROPERTY);
+ if (!Strings.isNullOrEmpty(backOffDelay)) {
+ return Long.parseLong(backOffDelay);
+ }
+ } catch (Exception ex) {
+ LOGGER.warn(
+ backOffDelay != null ? String.format(
+ "Error parsing property variable %s: %s",
+ BACKOFF_DELAY_PROPERTY, backOffDelay) : String
+ .format("Error extracting property variable %s",
+ BACKOFF_DELAY_PROPERTY), ex);
+ }
+ return TimeUnit.SECONDS.toMillis(10);
+ }
+
+ 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);
+ }
+
+ private void updateIndex(ConsulResponse<T> consulResponse) {
+ if (consulResponse != null && consulResponse.getIndex() != null) {
+ this.latestIndex.set(consulResponse.getIndex());
+ }
+ }
+
+ public void updateIndex(BigInteger index) {
+ if (index != null) {
+ this.latestIndex.set(index);
+ }
+ }
+
+ protected static QueryOptions watchParams(final BigInteger index,
+ final int blockSeconds, QueryOptions queryOptions) {
+ checkArgument(!queryOptions.getIndex().isPresent()
+ && !queryOptions.getWait().isPresent(),
+ "Index and wait cannot be overridden");
+
+ return ImmutableQueryOptions.builder()
+ .from(watchDefaultParams(index, blockSeconds))
+ .token(queryOptions.getToken())
+ .consistencyMode(queryOptions.getConsistencyMode())
+ .near(queryOptions.getNear()).build();
+ }
+
+ private static QueryOptions watchDefaultParams(final BigInteger index,
+ final 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 <V>
+ */
+ protected interface CallbackConsumer<T> {
+ void consume(BigInteger index, ConsulResponseCallback<T> callback);
+ }
+
+ /**
+ * Implementers can register a listener to receive a new map when it changes
+ *
+ * @param <V>
+ */
+ public interface Listener<T> {
+ void notify(ConsulResponse<T> newValues);
+ }
+
+ public boolean addListener(Listener<T> listener) {
+ boolean added = listeners.add(listener);
+ return added;
+ }
+
+ public List<Listener<T>> getListeners() {
+ return Collections.unmodifiableList(listeners);
+ }
+
+ public boolean removeListener(Listener<T> listener) {
+ return listeners.remove(listener);
+ }
+
+ @VisibleForTesting
+ protected State getState() {
+ return state.get();
+ }
+
+ private boolean isConuslIndexChanged(final BigInteger index) {
+
+ if (index != null && !index.equals(latestIndex.get())) {
+
+ if (LOGGER.isDebugEnabled()) {
+ // 第一次不打印
+ if (latestIndex.get() != null) {
+ LOGGER.debug("consul index compare:new-" + index + " old-"
+ + latestIndex.get());
+ }
+
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCache.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCache.java
new file mode 100644
index 0000000..b46ffce
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCache.java
@@ -0,0 +1,65 @@
+package org.onap.msb.apiroute.wrapper.consulextend.cache;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.consulextend.HealthClient;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+public class ServiceHealthCache extends ConsulCache<List<ServiceHealth>> {
+ private ServiceHealthCache(CallbackConsumer<List<ServiceHealth>> callbackConsumer) {
+ super(callbackConsumer);
+ }
+
+ /**
+ * Factory method to construct a string/{@link ServiceHealth} map for a particular service.
+ * <p/>
+ * Keys will be a {@link HostAndPort} object made up of the service's address/port combo
+ *
+ * @param healthClient the {@link HealthClient}
+ * @param serviceName the name of the service
+ * @param passing include only passing services?
+ * @return a cache object
+ */
+ public static ServiceHealthCache newCache(
+ final HealthClient healthClient,
+ final String serviceName,
+ final boolean passing,
+ final CatalogOptions catalogOptions,
+ final int watchSeconds,
+ final QueryOptions queryOptions) {
+
+ CallbackConsumer<List<ServiceHealth>> callbackConsumer = new CallbackConsumer<List<ServiceHealth>>() {
+ @Override
+ public void consume(BigInteger index,
+ ConsulResponseCallback<List<ServiceHealth>> callback) {
+ // TODO Auto-generated method stub
+ QueryOptions params = watchParams(index, watchSeconds, queryOptions);
+ if (passing) {
+ healthClient.getHealthyServiceInstances(serviceName, catalogOptions, params, callback);
+ } else {
+ healthClient.getAllServiceInstances(serviceName, catalogOptions, params, callback);
+ }
+ }
+ };
+
+ return new ServiceHealthCache(callbackConsumer);
+ }
+
+ public static ServiceHealthCache newCache(
+ final HealthClient healthClient,
+ final String serviceName,
+ final boolean passing,
+ final CatalogOptions catalogOptions,
+ final int watchSeconds) {
+ return newCache(healthClient, serviceName, passing, catalogOptions, watchSeconds, QueryOptions.BLANK);
+ }
+
+ public static ServiceHealthCache newCache(final HealthClient healthClient, final String serviceName) {
+ return newCache(healthClient, serviceName, true, CatalogOptions.BLANK, 10);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCache.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCache.java
new file mode 100644
index 0000000..08c7369
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCache.java
@@ -0,0 +1,39 @@
+package org.onap.msb.apiroute.wrapper.consulextend.cache;
+
+import java.math.BigInteger;
+
+import org.apache.http.HttpEntity;
+import org.onap.msb.apiroute.wrapper.consulextend.CatalogClient;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+public class ServicesCatalogCache extends ConsulCache<HttpEntity> {
+
+ private ServicesCatalogCache(CallbackConsumer<HttpEntity> callbackConsumer) {
+ super(callbackConsumer);
+ }
+
+ public static ServicesCatalogCache newCache(
+ final CatalogClient catalogClient,
+ final CatalogOptions catalogOptions,
+ final QueryOptions queryOptions,
+ final int watchSeconds) {
+
+ CallbackConsumer<HttpEntity> callbackConsumer = new CallbackConsumer<HttpEntity>() {
+ @Override
+ public void consume(BigInteger index, ConsulResponseCallback<HttpEntity> callback) {
+ QueryOptions params = watchParams(index, watchSeconds, queryOptions);
+ catalogClient.getServices(catalogOptions, params,callback);
+ }
+ };
+
+ return new ServicesCatalogCache(callbackConsumer);
+
+ }
+
+ public static ServicesCatalogCache newCache(final CatalogClient catalogClient) {
+ return newCache(catalogClient, CatalogOptions.BLANK, QueryOptions.BLANK, 10);
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilter.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilter.java
new file mode 100644
index 0000000..01b5168
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilter.java
@@ -0,0 +1,98 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.msb.apiroute.SyncDataManager;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ImmutableService;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ImmutableServiceHealth;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.Service;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.queue.QueueManager;
+import org.onap.msb.apiroute.wrapper.queue.ServiceData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.ConsulResponse;
+import com.orbitz.consul.model.health.ImmutableNode;
+
+
+
+public class CheckServiceDataEmptyAndAutoStopWatchFilter implements
+ WatchTask.Filter<List<ServiceHealth>> {
+
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(CheckServiceDataEmptyAndAutoStopWatchFilter.class);
+ private final String serviceName;
+
+ public CheckServiceDataEmptyAndAutoStopWatchFilter(
+ final String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ @Override
+ public boolean filter(ConsulResponse<List<ServiceHealth>> object) {
+ // TODO Auto-generated method stub
+ boolean result = check(object);
+
+ if (!result) {
+ // create delete
+ writeServiceToQueue4Del();
+ // stop watch
+ SyncDataManager.stopWatchService(serviceName);
+ }
+
+ return result;
+ }
+
+ // when:
+ // 1)service had been deleted
+ // 2)service Health check was not passing
+ // single service return [],size==0
+ // stop this service watching task and create delete event
+ private boolean check(ConsulResponse<List<ServiceHealth>> object) {
+ boolean result = true;
+
+ if (object == null || object.getResponse() == null
+ || object.getResponse().size() == 0) {
+ LOGGER.info("check service-{},its data is empty",
+ serviceName);
+ return false;
+ }
+
+ return result;
+ }
+
+ private void writeServiceToQueue4Del() {
+ ServiceData<List<ServiceHealth>> data = new ServiceData<List<ServiceHealth>>();
+ data.setDataType(ServiceData.DataType.service);
+ data.setOperate(ServiceData.Operate.delete);
+
+ // tell the subsequent operation the service name which will be deleted
+ Service service = ImmutableService.builder().id("").port(0).address("")
+ .service(serviceName).addTags("").createIndex(0).modifyIndex(0).build();
+ ServiceHealth serviceHealth = ImmutableServiceHealth.builder()
+ .service(service)
+ .node(ImmutableNode.builder().node("").address("").build())
+ .build();
+ List<ServiceHealth> serviceHealthList = new ArrayList<ServiceHealth>();
+ serviceHealthList.add(serviceHealth);
+
+ data.setData(serviceHealthList);
+
+ LOGGER.info("put delete service["
+ + serviceName
+ + "] to service queue :because of deleted ");
+
+ try {
+ QueueManager.getInstance().putIn(data);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn(
+ "put delete service["
+ + serviceName
+ + "] to service queue interrupted because of deleted:",
+ e);
+ }
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilter.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilter.java
new file mode 100644
index 0000000..311edce
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilter.java
@@ -0,0 +1,96 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.msb.apiroute.SyncDataManager;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.queue.QueueManager;
+import org.onap.msb.apiroute.wrapper.queue.ServiceData;
+import org.onap.msb.apiroute.wrapper.queue.ServiceData.Operate;
+import org.onap.msb.apiroute.wrapper.util.ServiceFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.ConsulResponse;
+
+public class CheckTagAndAutoStopWatchFilter implements
+ WatchTask.Filter<List<ServiceHealth>> {
+
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(CheckTagAndAutoStopWatchFilter.class);
+
+ private final String serviceName;
+
+ public CheckTagAndAutoStopWatchFilter(final String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ // from consul,the response data:List<ServiceHealth>
+ // filter ServiceHealth list and find the ServiceHealths which satisfy the
+ // tags conditions
+ // 1)if all ServiceHealth don't satisfy,create delete event and stop watch
+ // 2)if have some ServiceHealths satisfy the tags conditions,create update
+ // event and send these ServiceHealths
+ @Override
+ public boolean filter(ConsulResponse<List<ServiceHealth>> object) {
+ // TODO Auto-generated method stub
+
+ // find #ServiceHealth# which satisfy the tag conditions
+ List<ServiceHealth> satisfyList = getSatisfyList(object);
+
+ // no satisfied ServiceHealth
+ if (satisfyList.isEmpty()) {
+
+ LOGGER.info("put delete service["
+ + serviceName
+ + "] to service queue :because of NO tag meet the conditions");
+
+ // create delete
+ writeServiceToQueue(object.getResponse(),
+ ServiceData.Operate.delete);
+ // stop watch
+ //SyncDataManager.stopWatchService(serviceName);
+ return false;
+ }
+
+ LOGGER.info("put update service["
+ + serviceName
+ + "] to service queue :which tags meet the conditions");
+
+ // put the satisfy list to queue
+ writeServiceToQueue(satisfyList, ServiceData.Operate.update);
+
+ return true;
+ }
+
+ private List<ServiceHealth> getSatisfyList(
+ ConsulResponse<List<ServiceHealth>> object) {
+ List<ServiceHealth> satisfyList = new ArrayList<ServiceHealth>();
+ for (ServiceHealth health : object.getResponse()) {
+
+ if (ServiceFilter.getInstance().isFilterCheck(health)) {
+ satisfyList.add(health);
+ }
+ }
+
+ return satisfyList;
+ }
+
+ private void writeServiceToQueue(List<ServiceHealth> serviceData,
+ Operate operate) {
+ ServiceData<List<ServiceHealth>> data = new ServiceData<List<ServiceHealth>>();
+ data.setOperate(operate);
+ data.setDataType(ServiceData.DataType.service);
+ data.setData(serviceData);
+
+
+ try {
+ QueueManager.getInstance().putIn(data);
+ } catch (InterruptedException e) {
+ LOGGER.warn("put " + operate + " service[" + serviceName
+ + "] to service queue interrupted ", e);
+ }
+
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilter.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilter.java
new file mode 100644
index 0000000..14ab2c7
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilter.java
@@ -0,0 +1,48 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.math.BigInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.ConsulResponse;
+
+public class ConsulIndexFilter<T> implements WatchTask.Filter<T> {
+
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(ConsulIndexFilter.class);
+
+ private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(
+ null);
+
+ @Override
+ public boolean filter(final ConsulResponse<T> object) {
+ // TODO Auto-generated method stub
+ return isChanged(object);
+ }
+
+ private boolean isChanged(final ConsulResponse<T> consulResponse) {
+
+ if (consulResponse != null && consulResponse.getIndex() != null
+ && !consulResponse.getIndex().equals(latestIndex.get())) {
+
+ if(LOGGER.isDebugEnabled()){
+ //第一次不打印
+ if (latestIndex.get()!=null) {
+ LOGGER.debug("consul index compare:new-"
+ + consulResponse.getIndex() + " old-"
+ + latestIndex.get());
+ }
+
+ }
+
+ this.latestIndex.set(consulResponse.getIndex());
+ return true;
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilter.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilter.java
new file mode 100644
index 0000000..38fb7c6
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilter.java
@@ -0,0 +1,121 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.Service;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.util.ServiceFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+import com.orbitz.consul.model.ConsulResponse;
+import com.orbitz.consul.model.health.HealthCheck;
+
+public class ServiceModifyIndexFilter implements WatchTask.Filter<List<ServiceHealth>> {
+
+ private final AtomicReference<ImmutableList<ServiceHealth>> lastResponse =
+ new AtomicReference<ImmutableList<ServiceHealth>>(ImmutableList.<ServiceHealth>of());
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ServiceModifyIndexFilter.class);
+
+
+ @Override
+ public boolean filter(ConsulResponse<List<ServiceHealth>> object) {
+ // TODO Auto-generated method stub
+
+ List<ServiceHealth> newList=object.getResponse();
+ if(realFilter(newList)){
+ lastResponse.set(ImmutableList.copyOf(newList));
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean realFilter(List<ServiceHealth> newList) {
+ // 1)判断list的size,不等则改变
+ if (newList.size() != lastResponse.get().size()) {
+ // 第一次不打印
+ if (lastResponse.get().size() != 0) {
+ LOGGER.info(newList.get(0).getService().getService()
+ + " instance count is different.new_count:" + newList.size() + " old_count:"
+ + lastResponse.get().size());
+ }
+
+ return true;
+ }
+
+
+ // 2)循环服务实例判断服务内容和健康检查是否改变
+ for (ServiceHealth newData : newList) {
+ ServiceHealth sameIdOldData = findSameIdInOldList(newData);
+ // 若在oldlist中不存在,则改变
+ if (sameIdOldData == null) {
+
+ LOGGER.info(newData.getService().getId()
+ + " is a new service instance.the createindex:"
+ + newData.getService().getCreateIndex()
+ + " the modifyIndex:"
+ + newData.getService().getModifyIndex());
+
+ return true;
+ }
+
+ // 若在oldlist中存在,则比较ModifyIndex的值和健康检查状态.不等则改变
+ if(!compareService(newData,sameIdOldData)){
+ LOGGER.info(newData.getService().getId() +" instance is change because of modifyIndex or health check" );
+ return true;
+ }
+ }
+
+ return false;
+
+
+ }
+
+
+ private boolean compareService(ServiceHealth oldData,ServiceHealth newData) {
+
+ return compareServiceInfo(oldData.getService(),newData.getService()) &&
+ compareServiceHealthStatus(oldData.getChecks(),newData.getChecks());
+
+ }
+
+
+
+ private boolean compareServiceInfo(Service oldServiceInfo, Service newServiceInfo) {
+ if (oldServiceInfo.getModifyIndex() != newServiceInfo.getModifyIndex()) {
+ LOGGER.info(newServiceInfo.getId() + " new_modifyIndex:"
+ + newServiceInfo.getModifyIndex() + " old_modifyIndex:"
+ + oldServiceInfo.getModifyIndex());
+ return false;
+ }
+ return true;
+ }
+
+ private boolean compareServiceHealthStatus(List<HealthCheck> oldData, List<HealthCheck> newData) {
+ boolean oldHealthCheck=ServiceFilter.getInstance().isFilterHealthCheck(oldData);
+ boolean newHealthCheck=ServiceFilter.getInstance().isFilterHealthCheck(newData);
+ return oldHealthCheck==newHealthCheck;
+
+ }
+
+
+ private ServiceHealth findSameIdInOldList(ServiceHealth newData) {
+ for (ServiceHealth oldData : lastResponse.get()) {
+ if (oldData.getService().getId().equals(newData.getService().getId())) {
+ return oldData;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean resetModifyIndex() {
+ // clear last response
+ lastResponse.set(ImmutableList.<ServiceHealth>of());
+ return true;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTask.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTask.java
new file mode 100644
index 0000000..c21295f
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTask.java
@@ -0,0 +1,90 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import org.apache.http.HttpEntity;
+import org.onap.msb.apiroute.wrapper.consulextend.CatalogClient;
+import org.onap.msb.apiroute.wrapper.consulextend.cache.ServicesCatalogCache;
+import org.onap.msb.apiroute.wrapper.consulextend.cache.ConsulCache.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+public class WatchCatalogServicesTask extends WatchTask<HttpEntity> {
+
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(WatchCatalogServicesTask.class);
+
+ private ServicesCatalogCache servicesCache = null;
+
+ public WatchCatalogServicesTask(
+ final CatalogClient catalogClient,
+ final CatalogOptions catalogOptions,
+ final QueryOptions queryOptions,
+ final int watchSeconds)
+ {
+ initCache(catalogClient,catalogOptions,queryOptions,watchSeconds);
+ }
+
+ public WatchCatalogServicesTask(
+ final CatalogClient catalogClient,
+ final int watchSeconds)
+ {
+ initCache(catalogClient,CatalogOptions.BLANK,QueryOptions.BLANK,watchSeconds);
+ }
+
+ public WatchCatalogServicesTask(
+ final CatalogClient catalogClient)
+ {
+ initCache(catalogClient,CatalogOptions.BLANK,QueryOptions.BLANK,10);
+ }
+
+ private ServicesCatalogCache initCache(final CatalogClient catalogClient,
+ final CatalogOptions catalogOptions,
+ final QueryOptions queryOptions,
+ final int watchSeconds) {
+ LOGGER.info("************create all services watch task*****************");
+ servicesCache = ServicesCatalogCache.newCache(catalogClient,
+ catalogOptions, queryOptions, watchSeconds);
+
+ servicesCache
+ .addListener((Listener<HttpEntity>) new InternalListener());
+
+ return servicesCache;
+ }
+
+ @Override
+ public boolean startWatch() {
+ // TODO Auto-generated method stub
+ if(servicesCache!=null)
+ {
+ try {
+ servicesCache.start();
+ LOGGER.info("************start all services watch task*****************");
+ return true;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("start service list watch failed:", e);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean stopWatch() {
+ // TODO Auto-generated method stub
+ if (servicesCache != null) {
+ try {
+ servicesCache.stop();
+ LOGGER.info("************stop all services watch task*****************");
+ return true;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("stop service list watch failed:", e);
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTask.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTask.java
new file mode 100644
index 0000000..b0d64a7
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTask.java
@@ -0,0 +1,128 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.consulextend.HealthClient;
+import org.onap.msb.apiroute.wrapper.consulextend.cache.ServiceHealthCache;
+import org.onap.msb.apiroute.wrapper.consulextend.cache.ConsulCache.Listener;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+
+public class WatchServiceHealthTask extends WatchTask<List<ServiceHealth>> {
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(WatchServiceHealthTask.class);
+
+ private ServiceHealthCache serviceHealthCache = null;
+ private String serviceName="";
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public WatchServiceHealthTask(final HealthClient healthClient,
+ final String serviceName,final boolean passing,
+ final CatalogOptions catalogOptions, final int watchSeconds,
+ final QueryOptions queryOptions) {
+ initCache(healthClient, serviceName, passing, catalogOptions,
+ watchSeconds, queryOptions);
+ }
+
+ public WatchServiceHealthTask(final HealthClient healthClient,
+ final String serviceName,final boolean passing,
+ final int watchSeconds)
+
+ {
+ initCache(healthClient, serviceName, passing, CatalogOptions.BLANK,
+ watchSeconds, QueryOptions.BLANK);
+ }
+
+ public WatchServiceHealthTask(final HealthClient healthClient,
+ final String serviceName, final int watchSeconds)
+
+ {
+ initCache(healthClient, serviceName, true, CatalogOptions.BLANK,
+ watchSeconds, QueryOptions.BLANK);
+ }
+
+ private ServiceHealthCache initCache(final HealthClient healthClient,
+ final String serviceName,final boolean passing,
+ final CatalogOptions catalogOptions, final int watchSeconds,
+ final QueryOptions queryOptions) {
+// LOGGER.info("************create {} watch task*****************",serviceName);
+ this.serviceName = serviceName;
+ serviceHealthCache = ServiceHealthCache.newCache(healthClient,
+ serviceName, passing, catalogOptions, watchSeconds,
+ queryOptions);
+
+ serviceHealthCache
+ .addListener((Listener<List<ServiceHealth>>) new InternalListener());
+
+ return serviceHealthCache;
+ }
+
+ public boolean startWatch() {
+
+ if(serviceHealthCache!=null)
+ {
+ try {
+ serviceHealthCache.start();
+ LOGGER.info("************start {} watch task*****************",serviceName);
+ return true;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("start service watch failed:", e);
+ }
+ }
+
+ return false;
+
+ }
+
+ public boolean stopWatch(){
+ if (serviceHealthCache != null) {
+ try {
+ serviceHealthCache.stop();
+ LOGGER.info("************stop {} watch task*****************",serviceName);
+ return true;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("stop service watch failed:", e);
+ }
+ }
+
+ return false;
+ }
+
+
+ public boolean resetIndex()
+ {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("reset " + serviceName + " consul index");
+ }
+
+ //reset consul index
+ serviceHealthCache.updateIndex(BigInteger.valueOf(0));
+
+
+ //reset modify index
+ for (WatchTask.Filter<List<ServiceHealth>> filter : getAllFilters()) {
+ if (filter instanceof ServiceModifyIndexFilter) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("reset " + serviceName + " modify index");
+ }
+ return ((ServiceModifyIndexFilter) filter).resetModifyIndex();
+ }
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("reset modify index.did not find filter:" + serviceName);
+ }
+
+ return false;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchTask.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchTask.java
new file mode 100644
index 0000000..2ada19d
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchTask.java
@@ -0,0 +1,87 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.onap.msb.apiroute.wrapper.consulextend.cache.ConsulCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.ConsulResponse;
+
+public abstract class WatchTask<T> {
+ private final CopyOnWriteArrayList<Filter<T>> filters = new CopyOnWriteArrayList<Filter<T>>();
+ private final CopyOnWriteArrayList<Handler<T>> handlers = new CopyOnWriteArrayList<Handler<T>>();
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(WatchTask.class);
+
+ //start
+ public abstract boolean startWatch();
+
+ //stop
+ public abstract boolean stopWatch();
+
+ // filters
+ public interface Filter<T> {
+ public boolean filter(final ConsulResponse<T> object);
+ }
+
+ public boolean addFilter(Filter<T> filter) {
+ boolean added = filters.add(filter);
+ return added;
+ }
+
+ public void removeAllFilter() {
+ filters.clear();
+ }
+
+
+ public final CopyOnWriteArrayList<Filter<T>> getAllFilters(){
+ return filters;
+ }
+
+ // handlers
+ public interface Handler<T> {
+ void handle(final ConsulResponse<T> object);
+ }
+
+ public boolean addHandler(Handler<T> handler) {
+ boolean added = handlers.add(handler);
+ return added;
+ }
+
+ public void removeAllHandler() {
+ handlers.clear();
+ }
+
+ // internal listener
+ protected class InternalListener implements ConsulCache.Listener<T> {
+ @Override
+ public void notify(ConsulResponse<T> newValues) {
+
+ long startTime = System.currentTimeMillis();
+
+ // filter
+ for (Filter<T> f : filters) {
+ // false,return
+ if (!f.filter(newValues)) {
+ return;
+ }
+ }
+
+ // handle
+ for (Handler<T> h : handlers) {
+ h.handle(newValues);
+ }
+
+ long endTime = System.currentTimeMillis();
+
+ if(endTime-startTime > 10*1000)
+ {
+ LOGGER.info("WatchTask THEAD WORK TIMEOUT");
+ }
+ }
+
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandler.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandler.java
new file mode 100644
index 0000000..6df10e3
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandler.java
@@ -0,0 +1,36 @@
+package org.onap.msb.apiroute.wrapper.consulextend.expose;
+
+import org.onap.msb.apiroute.wrapper.queue.QueueManager;
+import org.onap.msb.apiroute.wrapper.queue.ServiceData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.ConsulResponse;
+
+public class WriteBufferHandler<T> implements WatchTask.Handler<T> {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(WriteBufferHandler.class);
+ private final ServiceData.DataType dataType;
+
+
+ public WriteBufferHandler(final ServiceData.DataType dataType) {
+ this.dataType =dataType;
+ }
+
+ @Override
+ public void handle(ConsulResponse<T> object) {
+ // TODO Auto-generated method stub
+ ServiceData<T> data = new ServiceData<T>();
+ data.setDataType(dataType);
+ data.setData(object.getResponse());
+
+ try {
+ QueueManager.getInstance().putIn(data);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOGGER.warn("put data to buffer interrupted:", e);
+ }
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/Service.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/Service.java
new file mode 100644
index 0000000..fd7f3fa
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/Service.java
@@ -0,0 +1,39 @@
+package org.onap.msb.apiroute.wrapper.consulextend.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;
+import com.google.common.collect.ImmutableList;
+import org.immutables.value.Value;
+
+import java.util.List;
+
+@Value.Immutable
+@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<String> getTags();
+
+ @JsonProperty("Address")
+ public abstract String getAddress();
+
+ @JsonProperty("Port")
+ public abstract int getPort();
+
+ @JsonProperty("CreateIndex")
+ public abstract int getCreateIndex();
+
+ @JsonProperty("ModifyIndex")
+ public abstract int getModifyIndex();
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealth.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealth.java
new file mode 100644
index 0000000..a739b4b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealth.java
@@ -0,0 +1,30 @@
+package org.onap.msb.apiroute.wrapper.consulextend.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;
+import com.google.common.collect.ImmutableList;
+import com.orbitz.consul.model.health.HealthCheck;
+import com.orbitz.consul.model.health.Node;
+
+import org.immutables.value.Value;
+
+import java.util.List;
+@Value.Immutable
+@JsonSerialize(as = ImmutableServiceHealth.class)
+@JsonDeserialize(as = ImmutableServiceHealth.class)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public abstract class ServiceHealth {
+
+ @JsonProperty("Node")
+ public abstract Node getNode();
+
+ @JsonProperty("Service")
+ public abstract Service getService();
+
+ @JsonProperty("Checks")
+ @JsonDeserialize(as = ImmutableList.class, contentAs = HealthCheck.class)
+ public abstract List<HealthCheck> getChecks();
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/util/Http.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/util/Http.java
new file mode 100644
index 0000000..9f0980c
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/util/Http.java
@@ -0,0 +1,281 @@
+package org.onap.msb.apiroute.wrapper.consulextend.util;
+
+import java.io.IOException;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.eclipse.jetty.http.HttpStatus;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
+import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseHeader;
+import org.onap.msb.apiroute.wrapper.consulextend.async.OriginalConsulResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.orbitz.consul.ConsulException;
+import com.orbitz.consul.model.ConsulResponse;
+import com.orbitz.consul.option.CatalogOptions;
+import com.orbitz.consul.option.QueryOptions;
+import com.orbitz.consul.util.Jackson;
+
+public class Http {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Http.class);
+
+ private final static CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients
+ .custom().setMaxConnTotal(Integer.MAX_VALUE)
+ .setMaxConnPerRoute(Integer.MAX_VALUE).build();
+
+ private static Http instance = null;
+
+ private Http() {
+ }
+
+ public static Http getInstance() {
+ if (instance == null) {
+ instance = new Http();
+ httpAsyncClient.start();
+ }
+
+ return instance;
+ }
+
+ // async get data from consul,and handle response immediately
+ public <T> void asyncGet(String requestURI,
+ final TypeReference<T> responseType,
+ final ConsulResponseCallback<T> callback, final Integer... okCodes) {
+ // LOGGER.info("Async request:"+requestURI);
+
+ httpAsyncClient.execute(new HttpGet(requestURI),
+ new FutureCallback<HttpResponse>() {
+
+ public void completed(final HttpResponse response) {
+ callback.onComplete(consulResponse(responseType,
+ response));
+ }
+
+ public void failed(final Exception ex) {
+ callback.onFailure(ex);
+ }
+
+ public void cancelled() {
+ LOGGER.warn("cancelled async request");
+ }
+ });
+ }
+
+ // async get data from consul,and handle response delay
+ public <T> void asyncGetDelayHandle(String requestURI,
+ final TypeReference<T> responseType,
+ final ConsulResponseCallback<T> callback, final Integer... okCodes) {
+
+ httpAsyncClient.execute(new HttpGet(requestURI),
+ new FutureCallback<HttpResponse>() {
+
+ public void completed(final HttpResponse response) {
+ OriginalConsulResponse<T> originalConsulResponse = new OriginalConsulResponse<T>(
+ response, responseType);
+
+ //handle not 2xx code
+ if (!isSuccessful(response)) {
+
+ LOGGER.warn("response statuscode:"
+ + response.getStatusLine().getStatusCode());
+
+ callback.onFailure(new ConsulException(
+ "response statuscode:"
+ + response.getStatusLine()
+ .getStatusCode()));
+ } else {
+ callback.onDelayComplete(originalConsulResponse);
+ }
+
+ }
+
+ public void failed(final Exception ex) {
+ callback.onFailure(ex);
+ }
+
+ public void cancelled() {
+ LOGGER.warn("cancelled async request");
+ }
+ });
+ }
+
+ public static ConsulResponseHeader consulResponseHeader(
+ HttpResponse response) {
+ String indexHeaderValue = response.getFirstHeader("X-Consul-Index")
+ .getValue();
+ String lastContactHeaderValue = response.getFirstHeader(
+ "X-Consul-Lastcontact").getValue();
+ String knownLeaderHeaderValue = response.getFirstHeader(
+ "X-Consul-Knownleader").getValue();
+
+ BigInteger index = indexHeaderValue == null ? new BigInteger("0")
+ : new BigInteger(indexHeaderValue);
+ long lastContact = lastContactHeaderValue == null ? 0 : Long
+ .parseLong(lastContactHeaderValue);
+ boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean
+ .parseBoolean(knownLeaderHeaderValue);
+
+ return new ConsulResponseHeader(lastContact, knownLeader, index);
+ }
+
+ public static <T> ConsulResponse<T> consulResponse(
+ TypeReference<T> responseType, HttpResponse response) {
+
+ String indexHeaderValue = response.getFirstHeader("X-Consul-Index")
+ .getValue();
+ String lastContactHeaderValue = response.getFirstHeader(
+ "X-Consul-Lastcontact").getValue();
+ String knownLeaderHeaderValue = response.getFirstHeader(
+ "X-Consul-Knownleader").getValue();
+
+ BigInteger index = indexHeaderValue == null ? new BigInteger("0")
+ : new BigInteger(indexHeaderValue);
+ long lastContact = lastContactHeaderValue == null ? 0 : Long
+ .parseLong(lastContactHeaderValue);
+ boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean
+ .parseBoolean(knownLeaderHeaderValue);
+
+ ConsulResponse<T> consulResponse = new ConsulResponse<T>(readResponse(
+ response, responseType), lastContact, knownLeader, index);
+ return consulResponse;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <T> T readResponse(HttpResponse response,
+ TypeReference<T> responseType) {
+
+ // read streamed entity
+ T object;
+
+ // HttpEntity,read original data.
+ Type _type = responseType.getType();
+ if (_type instanceof Class
+ && (((Class) _type).isAssignableFrom(HttpEntity.class))) {
+ object = (T) response.getEntity();
+ return object;
+ }
+
+ // String,read original data.
+ if (_type instanceof Class
+ && (((Class) _type).isAssignableFrom(String.class))) {
+
+ try {
+
+ object = (T) IOUtils
+ .toString(response.getEntity().getContent());
+ response.getEntity().getContent().close();
+
+ } catch (UnsupportedOperationException e) {
+ object = (T) "";
+ LOGGER.warn("covert streamed entity to String exception:", e);
+ } catch (IOException e) {
+ object = (T) "";
+ LOGGER.warn("covert streamed entity to String exception:", e);
+ }
+
+ return object;
+ }
+
+ // change data type
+ try {
+ object = Jackson.MAPPER.readValue(
+ response.getEntity().getContent(), responseType);
+ } catch (IOException e) {
+ LOGGER.warn("covert streamed entity to object exception:", e);
+ object = readDefaultResponse(responseType);
+ }
+
+ return object;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T readDefaultResponse(TypeReference<T> responseType) {
+ Type _type = responseType.getType();
+ if (_type instanceof ParameterizedType
+ && ((ParameterizedType) _type).getRawType() == List.class) {
+ return (T) ImmutableList.of();
+ } else if (_type instanceof ParameterizedType
+ && ((ParameterizedType) _type).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 " + _type);
+ }
+ }
+
+ public static boolean isSuccessful(HttpResponse response,
+ Integer... okCodes) {
+ return HttpStatus.isSuccess(response.getStatusLine().getStatusCode())
+ || Sets.newHashSet(okCodes).contains(
+ response.getStatusLine().getStatusCode());
+ }
+
+ public static String optionsFrom(CatalogOptions catalogOptions,
+ QueryOptions queryOptions) {
+ String params = "";
+
+ if (catalogOptions != null) {
+ Map<String, Object> options = catalogOptions.toQuery();
+
+ if (options.containsKey("dc")) {
+ params += "dc=" + options.get("dc");
+ }
+ if (options.containsKey("tag")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "tag=" + options.get("tag");
+ }
+ }
+
+ if (queryOptions != null) {
+ Map<String, Object> options = queryOptions.toQuery();
+
+ if (options.containsKey("consistent")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "consistent=" + options.get("consistent");
+ }
+ if (options.containsKey("stale")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "stale=" + options.get("stale");
+ }
+ if (options.containsKey("wait")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "wait=" + options.get("wait");
+ }
+
+ if (options.containsKey("index")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "index=" + options.get("index");
+ }
+ if (options.containsKey("token")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "token=" + options.get("token");
+ }
+ if (options.containsKey("near")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "near=" + options.get("near");
+ }
+ if (options.containsKey("dc")) {
+ params += params.isEmpty() ? "" : "&";
+ params += "dc=" + options.get("dc");
+ }
+ }
+ return params;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOConstants.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOConstants.java
new file mode 100644
index 0000000..ab3b3f1
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOConstants.java
@@ -0,0 +1,6 @@
+package org.onap.msb.apiroute.wrapper.dao;
+
+public class DAOConstants {
+ public static final String ROUTE_KIND = "route";
+ public static final String SERVICE_KIND = "service";
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOFactory.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOFactory.java
new file mode 100644
index 0000000..0fb3e14
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOFactory.java
@@ -0,0 +1,18 @@
+package org.onap.msb.apiroute.wrapper.dao;
+
+import org.onap.msb.apiroute.wrapper.dao.route.IRouteDAO;
+import org.onap.msb.apiroute.wrapper.dao.route.RouteDAOImpl;
+import org.onap.msb.apiroute.wrapper.dao.service.IServiceDAO;
+import org.onap.msb.apiroute.wrapper.dao.service.ServiceDAOImpl;
+
+public class DAOFactory {
+ private static final IRouteDAO routeDAO = new RouteDAOImpl();
+ private static final IServiceDAO serviceDAO = new ServiceDAOImpl();
+
+ public static IRouteDAO getRouteDAO(){
+ return routeDAO;
+ }
+ public static IServiceDAO getServiceDAO(){
+ return serviceDAO;
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/RedisAccessWrapper.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/RedisAccessWrapper.java
new file mode 100644
index 0000000..06799b1
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/RedisAccessWrapper.java
@@ -0,0 +1,133 @@
+package org.onap.msb.apiroute.wrapper.dao;
+
+import org.onap.msb.apiroute.wrapper.util.JedisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.ScanParams;
+import redis.clients.jedis.ScanResult;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class RedisAccessWrapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RedisAccessWrapper.class);
+ //An iteration starts when the cursor is set to 0
+ private static final String REDIS_SCAN_POINTER_NEW_ITERATION = "0";
+ //An iteration terminated when the cursor returned by the server is 0
+ private static final String REDIS_SCAN_POINTER_ITERATION_END = "0";
+ private static final int REDIS_SCAN_COUNT = 50;
+
+
+ public static void save(String key,String value) throws Exception {
+ Jedis jedis = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ jedis.set(key,value);
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ }
+
+ public static String query(String key) throws Exception {
+ Jedis jedis = null;
+ String value = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ value = jedis.get(key);
+ }finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ return value;
+ }
+
+ public static long delete(String key) throws Exception {
+ Jedis jedis = null;
+ long reply = 0L;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ reply = jedis.del(key);
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ return reply;
+ }
+
+ public static boolean isExist(String key) throws Exception {
+ boolean isExist = false;
+ Jedis jedis = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ isExist = jedis.exists(key);
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ return isExist;
+ }
+
+ public static List<String> queryMultiKeys(String keyPattern) throws Exception {
+ Set<String> keySet = filterKeys(keyPattern);
+ List<String> valueList = new ArrayList<>();
+ Jedis jedis = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ for(String key : keySet){
+ String value = jedis.get(key);
+ if(value !=null && !"".equals(value)){
+ valueList.add(value);
+ }
+ }
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ return valueList;
+ }
+
+ public static long deleteMultiKeys(String keyPattern) throws Exception {
+ Set<String> keySet = filterKeys(keyPattern);
+ long replySum = 0L;
+ Jedis jedis = null;
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ for(String key : keySet){
+ long reply = jedis.del(key);
+ replySum = replySum + reply;
+ }
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ return replySum;
+ }
+
+ /**
+ * filter the keys according to the given pattern
+ * using "scan" instead of using "keys", incrementally iterate the keys space
+ * @param pattern the input filter pattern
+ * @return the matched keys set
+ */
+ public static Set<String> filterKeys(String pattern) throws Exception{
+ long start = System.currentTimeMillis();
+ Jedis jedis = null;
+ Set<String> filteredKeys = new HashSet<>();
+ ScanParams scanParams = new ScanParams();
+ scanParams.match(pattern);
+ scanParams.count(REDIS_SCAN_COUNT);
+ try {
+ jedis = JedisUtil.borrowJedisInstance();
+ ScanResult<String> scanResult = jedis.scan(REDIS_SCAN_POINTER_NEW_ITERATION,scanParams);
+ filteredKeys.addAll(scanResult.getResult());
+ while(!scanResult.getStringCursor().equals(REDIS_SCAN_POINTER_ITERATION_END)){
+ scanResult = jedis.scan(scanResult.getStringCursor(),scanParams);
+ filteredKeys.addAll(scanResult.getResult());
+ }
+ } finally {
+ JedisUtil.returnJedisInstance(jedis);
+ }
+ long end = System.currentTimeMillis();
+ long costTime = end-start;
+ LOGGER.info("filterKeys " + pattern + " count:" + filteredKeys.size() + " cost: " + costTime);
+ return filteredKeys;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/IRouteDAO.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/IRouteDAO.java
new file mode 100644
index 0000000..f2f51c1
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/IRouteDAO.java
@@ -0,0 +1,18 @@
+package org.onap.msb.apiroute.wrapper.dao.route;
+
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.dao.route.bean.RouteInfo;
+
+public interface IRouteDAO {
+ public void saveRoute(String key, RouteInfo routeInfo) throws Exception;
+
+ public RouteInfo queryRoute(String key) throws Exception;
+
+ public List<RouteInfo> queryMultiRoute(String keyPattern) throws Exception;
+
+ public long deleteRoute(String key) throws Exception;
+
+ public long deleteMultiRoute(String keyPattern) throws Exception;
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/RouteDAOImpl.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/RouteDAOImpl.java
new file mode 100644
index 0000000..83e868b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/RouteDAOImpl.java
@@ -0,0 +1,63 @@
+package org.onap.msb.apiroute.wrapper.dao.route;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.RouteInfo;
+import org.onap.msb.apiroute.wrapper.util.Jackson;
+
+public class RouteDAOImpl implements IRouteDAO{
+ public void saveRoute(String key, RouteInfo routeInfo) throws Exception {
+ String routeInfoStr = null;
+ // change orginal url from “/” to empty string accord to the rewrite rule while forwarding
+ if("/".equals(routeInfo.getSpec().getUrl())){
+ routeInfo.getSpec().setUrl("");
+ }
+ try {
+ routeInfoStr = Jackson.MAPPER.writeValueAsString(routeInfo);
+ } catch (JsonProcessingException e) {
+ throw new Exception("error occurred while parsing RouteInfo to json data",e);
+ }
+ RedisAccessWrapper.save(key, routeInfoStr);
+ }
+
+ public RouteInfo queryRoute(String key) throws Exception {
+ RouteInfo routeInfo = null;
+ String routeInfoStr = RedisAccessWrapper.query(key);
+ if (null == routeInfoStr || "".equals(routeInfoStr))
+ return null;
+ try {
+ routeInfo = Jackson.MAPPER.readValue(routeInfoStr, RouteInfo.class);
+ } catch (IOException e) {
+ throw new Exception("error occurred while parsing the redis json data to RouteInfo",e);
+ }
+ return routeInfo;
+ }
+
+ public List<RouteInfo> queryMultiRoute(String keyPattern) throws Exception {
+ List<String> routeInfoStrList = RedisAccessWrapper.queryMultiKeys(keyPattern);
+ List<RouteInfo> routeInfoList = new ArrayList<>();
+ for (String routeInfoStr : routeInfoStrList) {
+ RouteInfo routeInfo = null;
+ try {
+ routeInfo = Jackson.MAPPER.readValue(routeInfoStr, RouteInfo.class);
+ routeInfoList.add(routeInfo);
+ } catch (IOException e) {
+ throw new Exception("error occurred while parsing the redis json data to RouteInfo",e);
+ }
+ }
+ return routeInfoList;
+ }
+
+ public long deleteRoute(String key) throws Exception {
+ return RedisAccessWrapper.delete(key);
+ }
+
+ public long deleteMultiRoute(String keyPattern) throws Exception{
+ return RedisAccessWrapper.deleteMultiKeys(keyPattern);
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Metadata.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Metadata.java
new file mode 100644
index 0000000..3e11fcc
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Metadata.java
@@ -0,0 +1,48 @@
+package org.onap.msb.apiroute.wrapper.dao.route.bean;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Metadata {
+ private String name;
+ private String namespace;
+ private String uid = "";
+ //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+ //private Date creationTimestamp;
+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
+ private Date updateTimestamp;
+ private Map labels = new HashMap();
+ private String[] annotations = null;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Metadata metadata = (Metadata) o;
+ return Objects.equals(name, metadata.name) &&
+ Objects.equals(namespace, metadata.namespace) &&
+ Objects.equals(uid, metadata.uid) &&
+ //Objects.equals(creationTimestamp, metadata.creationTimestamp) &&
+ Objects.equals(updateTimestamp, metadata.updateTimestamp) &&
+ Objects.equals(labels, metadata.labels) &&
+ Objects.equals(annotations, metadata.annotations);
+ }
+
+ @Override
+ public int hashCode() {
+ //return Objects.hash(name, namespace, uid, creationTimestamp, updateTimestamp, labels, annotations);
+ return Objects.hash(name, namespace, uid, updateTimestamp, labels, annotations);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Node.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Node.java
new file mode 100644
index 0000000..a328c3c
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Node.java
@@ -0,0 +1,32 @@
+package org.onap.msb.apiroute.wrapper.dao.route.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Node {
+ private String ip;
+ private int port;
+ private int weight=0;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Node node = (Node) o;
+ return Objects.equals(port, node.port) &&
+ Objects.equals(weight, node.weight) &&
+ Objects.equals(ip, node.ip);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip, port, weight);
+ }
+ */
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/RouteInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/RouteInfo.java
new file mode 100644
index 0000000..e5ab7bf
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/RouteInfo.java
@@ -0,0 +1,79 @@
+package org.onap.msb.apiroute.wrapper.dao.route.bean;
+
+import org.onap.msb.apiroute.wrapper.dao.DAOConstants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+public class RouteInfo {
+ private String kind = DAOConstants.ROUTE_KIND;
+ private String apiVersion = "";
+ private String status = "";
+ private Metadata metadata;
+ private Spec spec;
+
+ /**
+ Example route:
+ {
+ "kind" : "route",
+ "apiVersion" : "v1",
+ "status" : "1"
+ "metadata" : {
+ "name" : "kubernetes",
+ "namespace" : "default",
+ "uid" : "0b6f198e-c6ab-11e6-86aa-fa163ee2118b",
+ "creationTimestamp" : "2016-12-20T11:54:21Z",
+ "updateTimestamp" : "",
+ "labels" : {
+ "component" : "apiserver",
+ "provider" : "kubernetes"
+ },
+ "annotations" : {}
+ },
+ "spec" : {
+ "visualRange" : 0,
+ "url" : "",
+ "publish_port" : "",
+ "host" : "",
+ "apijson" : "",
+ "apijsontype" : ""
+ "metricsUrl" : ""
+ "consulServiceName" : ""
+ "useOwnUpstream" : "" //是否使用该服务独立的upstream转发
+ "publishProtocol" : "", //发布地址使用http还是http协议
+ "enable_ssl" : "0|1", //转发时,使用http还是http转发。http:0/https:1
+ "controll" : "", //是否可以修改
+ "nodes" : [{
+ "ip" : 10.10.10.2,
+ "port" : 8080,
+ "weight" : ""
+ }
+ ],
+ }
+}
+ */
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RouteInfo that = (RouteInfo) o;
+ return Objects.equals(kind, that.kind) &&
+ Objects.equals(apiVersion, that.apiVersion) &&
+ Objects.equals(status, that.status) &&
+ Objects.equals(metadata, that.metadata) &&
+ Objects.equals(spec, that.spec);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(kind, apiVersion, status, metadata, spec);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Spec.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Spec.java
new file mode 100644
index 0000000..8e9a54b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Spec.java
@@ -0,0 +1,52 @@
+package org.onap.msb.apiroute.wrapper.dao.route.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Spec {
+ private String visualRange = "";
+ private String url = "";
+ private String publish_port;
+ private String host = "";
+ private String apijson = "";
+ private String apijsontype = "";
+ private String metricsUrl = "";
+ private String consulServiceName = "";
+ private String useOwnUpstream = "";
+ private String publish_protocol = "";
+ private boolean enable_ssl = false;
+ private String control = "";
+ private Node[] nodes;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Spec spec = (Spec) o;
+ return Objects.equals(enable_ssl, spec.enable_ssl) &&
+ Objects.equals(visualRange, spec.visualRange) &&
+ Objects.equals(url, spec.url) &&
+ Objects.equals(publish_port, spec.publish_port) &&
+ Objects.equals(host, spec.host) &&
+ Objects.equals(apijson, spec.apijson) &&
+ Objects.equals(apijsontype, spec.apijsontype) &&
+ Objects.equals(metricsUrl, spec.metricsUrl) &&
+ Objects.equals(consulServiceName, spec.consulServiceName) &&
+ Objects.equals(useOwnUpstream, spec.useOwnUpstream) &&
+ Objects.equals(publish_protocol, spec.publish_protocol) &&
+ Objects.equals(control, spec.control) &&
+ Arrays.equals(nodes, spec.nodes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(visualRange, url, publish_port, host, apijson, apijsontype, metricsUrl, consulServiceName, useOwnUpstream, publish_protocol, enable_ssl, control, nodes);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/IServiceDAO.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/IServiceDAO.java
new file mode 100644
index 0000000..d63f656
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/IServiceDAO.java
@@ -0,0 +1,17 @@
+package org.onap.msb.apiroute.wrapper.dao.service;
+
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.dao.service.bean.ServiceInfo;
+
+public interface IServiceDAO {
+ public void saveService(String key, ServiceInfo serviceInfo) throws Exception;
+
+ public ServiceInfo queryService(String key) throws Exception;
+
+ public List<ServiceInfo> queryMultiService(String keyPattern) throws Exception;
+
+ public long deleteService(String key) throws Exception;
+
+ public long deleteMultiService(String keyPattern) throws Exception;
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/ServiceDAOImpl.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/ServiceDAOImpl.java
new file mode 100644
index 0000000..e9f4586
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/ServiceDAOImpl.java
@@ -0,0 +1,59 @@
+package org.onap.msb.apiroute.wrapper.dao.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper;
+import org.onap.msb.apiroute.wrapper.dao.service.bean.ServiceInfo;
+import org.onap.msb.apiroute.wrapper.util.Jackson;
+
+public class ServiceDAOImpl implements IServiceDAO{
+ public void saveService(String key, ServiceInfo serviceInfo) throws Exception {
+ String serviceInfoStr = null;
+ try {
+ serviceInfoStr = Jackson.MAPPER.writeValueAsString(serviceInfo);
+ } catch (JsonProcessingException e) {
+ throw new Exception("error occurred while parsing ServiceInfo to json data",e);
+ }
+ RedisAccessWrapper.save(key, serviceInfoStr);
+ }
+
+ public ServiceInfo queryService(String key) throws Exception {
+ ServiceInfo serviceInfo = null;
+ String serviceInfoStr = RedisAccessWrapper.query(key);
+ if (null == serviceInfoStr || "".equals(serviceInfoStr))
+ return null;
+ try {
+ serviceInfo = Jackson.MAPPER.readValue(serviceInfoStr, ServiceInfo.class);
+ } catch (IOException e) {
+ throw new Exception("error occurred while parsing the redis json data to ServiceInfo",e);
+ }
+ return serviceInfo;
+ }
+
+ public List<ServiceInfo> queryMultiService(String keyPattern) throws Exception {
+ List<String> serviceInfoStrList = RedisAccessWrapper.queryMultiKeys(keyPattern);
+ List<ServiceInfo> routeInfoList = new ArrayList<>();
+ for (String serviceInfoStr : serviceInfoStrList) {
+ ServiceInfo serviceInfo = null;
+ try {
+ serviceInfo = Jackson.MAPPER.readValue(serviceInfoStr, ServiceInfo.class);
+ routeInfoList.add(serviceInfo);
+ } catch (IOException e) {
+ throw new Exception("error occurred while parsing the redis json data to ServiceInfo",e);
+ }
+ }
+ return routeInfoList;
+ }
+
+ public long deleteService(String key) throws Exception {
+ return RedisAccessWrapper.delete(key);
+ }
+
+ public long deleteMultiService(String keyPattern) throws Exception{
+ return RedisAccessWrapper.deleteMultiKeys(keyPattern);
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Metadata.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Metadata.java
new file mode 100644
index 0000000..6ce6126
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Metadata.java
@@ -0,0 +1,50 @@
+package org.onap.msb.apiroute.wrapper.dao.service.bean;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Metadata {
+ private String name;
+ private String namespace;
+ private String uid = "";
+ //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+ //private Date creationTimestamp;
+ // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
+ private Date updateTimestamp;
+ private Map labels = new HashMap();
+ //private String[] annotations = new String[]{};
+ private String[] annotations = null;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Metadata metadata = (Metadata) o;
+ return Objects.equals(name, metadata.name) &&
+ Objects.equals(namespace, metadata.namespace) &&
+ Objects.equals(uid, metadata.uid) &&
+ //Objects.equals(creationTimestamp, metadata.creationTimestamp) &&
+ Objects.equals(updateTimestamp, metadata.updateTimestamp) &&
+ Objects.equals(labels, metadata.labels) &&
+ Objects.equals(annotations, metadata.annotations);
+ }
+
+ @Override
+ public int hashCode() {
+ //return Objects.hash(name, namespace, uid, creationTimestamp, updateTimestamp, labels, annotations);
+ return Objects.hash(name, namespace, uid, updateTimestamp, labels, annotations);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Node.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Node.java
new file mode 100644
index 0000000..fecf4bd
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Node.java
@@ -0,0 +1,32 @@
+package org.onap.msb.apiroute.wrapper.dao.service.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Node {
+ private String ip;
+ private String port;
+ private int ttl=-1;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Node node = (Node) o;
+ return Objects.equals(port, node.port) &&
+ Objects.equals(ttl, node.ttl) &&
+ Objects.equals(ip, node.ip);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip, port, ttl);
+ }
+ */
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/ServiceInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/ServiceInfo.java
new file mode 100644
index 0000000..01ab3a9
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/ServiceInfo.java
@@ -0,0 +1,76 @@
+package org.onap.msb.apiroute.wrapper.dao.service.bean;
+
+import org.onap.msb.apiroute.wrapper.dao.DAOConstants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+public class ServiceInfo {
+ private String kind = DAOConstants.SERVICE_KIND;
+ private String apiVersion = "";
+ private String status = "";
+ private Metadata metadata;
+ private Spec spec;
+
+ /**
+ Example Service:
+ {
+ "kind" : "service",
+ "apiVersion" : "v1",
+ "metadata" : {
+ "name" : "kubernetes",
+ "namespace" : "default",
+ "uid" : "0b6f198e-c6ab-11e6-86aa-fa163ee2118b",
+ "creationTimestamp" : "2016-12-20T11:54:21Z",
+ "labels" : {
+ "component" : "apiserver",
+ "provider" : "kubernetes"
+ },
+ "annotations" : {}
+ },
+ "spec" : {
+ "visualRange" : 0,
+ "url" : "",
+ "path" : "",
+ "publish_port" : "",
+ "host" : "",
+ "protocol" : "",
+ "lb_policy" : "",
+ "enable_ssl" : "0|1", //转发时,使用http还是http转发。http:0/https:1
+ "nodes" : [{
+ "ip" : 10.10.10.2,
+ "port" : 8080,
+ "ttl" :
+ }
+ ],
+ }
+ "status" : ""
+ }
+
+ */
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ServiceInfo that = (ServiceInfo) o;
+ return Objects.equals(kind, that.kind) &&
+ Objects.equals(apiVersion, that.apiVersion) &&
+ Objects.equals(status, that.status) &&
+ Objects.equals(metadata, that.metadata) &&
+ Objects.equals(spec, that.spec);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(kind, apiVersion, status, metadata, spec);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Spec.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Spec.java
new file mode 100644
index 0000000..65e769b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Spec.java
@@ -0,0 +1,44 @@
+package org.onap.msb.apiroute.wrapper.dao.service.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter @Setter
+public class Spec {
+ private String visualRange = "";
+ private String url = "";
+ private String path = "";
+ private String publish_port;
+ private String host = "";
+ private String protocol = "";
+ private String lb_policy = "";
+ private boolean enable_ssl = false;
+ private Node[] nodes;
+
+ /*
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Spec spec = (Spec) o;
+ return Objects.equals(enable_ssl, spec.enable_ssl) &&
+ Objects.equals(visualRange, spec.visualRange) &&
+ Objects.equals(url, spec.url) &&
+ Objects.equals(path, spec.path) &&
+ Objects.equals(publish_port, spec.publish_port) &&
+ Objects.equals(host, spec.host) &&
+ Objects.equals(protocol, spec.protocol) &&
+ Objects.equals(lb_policy, spec.lb_policy) &&
+ Arrays.equals(nodes, spec.nodes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(visualRange, url, path, publish_port, host, protocol, lb_policy, enable_ssl, nodes);
+ }
+ */
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/BaseQueue.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/BaseQueue.java
new file mode 100644
index 0000000..dce3b12
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/BaseQueue.java
@@ -0,0 +1,36 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public abstract class BaseQueue<T> {
+
+ private final List<BlockingQueue<ServiceData<T>>> queueArray= new ArrayList<BlockingQueue<ServiceData<T>>>();
+
+ public BaseQueue(int queueNum,int queueCapacity)
+ {
+ for(int i=0;queueNum>0 && i<queueNum;i++)
+ {
+ queueArray.add(new LinkedBlockingQueue<ServiceData<T>>(queueCapacity));
+ }
+ }
+
+ public int getQueneNum(){
+ return queueArray.size();
+ }
+
+ protected BlockingQueue<ServiceData<T>> getQueue(int index)
+ {
+ return queueArray.get(index);
+ }
+
+ public abstract void put(final ServiceData<T> data) throws InterruptedException;
+
+ public abstract ServiceData<T> take(final int queueIndex) throws InterruptedException;
+
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/QueueManager.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/QueueManager.java
new file mode 100644
index 0000000..20525c8
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/QueueManager.java
@@ -0,0 +1,65 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.http.HttpEntity;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class QueueManager {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(QueueManager.class);
+
+ private final BaseQueue<HttpEntity> serviceListQueue;
+ private final BaseQueue<List<ServiceHealth>> serviceQueue;
+
+ private volatile static QueueManager instance = null;
+
+ public static QueueManager getInstance() {
+ if (instance == null) {
+ synchronized (QueueManager.class) {
+ if (instance == null) {
+ instance = new QueueManager();
+ }
+ }
+ }
+ return instance;
+ }
+
+ private QueueManager() {
+ serviceListQueue = new ServiceListQueue(
+ RouteUtil.SERVICE_LIST_QUEUE_CAPACITY);
+ serviceQueue = new ServiceQueue(RouteUtil.SERVICE_DATA_QUEUE_NUM,
+ RouteUtil.SERVICE_QUEUE_CAPACITY);
+ }
+
+ public ServiceData<HttpEntity> takeFromServiceListQueue(
+ int queueIndex) throws InterruptedException {
+ return serviceListQueue.take(queueIndex);
+ }
+
+ public ServiceData<List<ServiceHealth>> takeFromServiceQueue(int queueIndex)
+ throws InterruptedException {
+ return serviceQueue.take(queueIndex);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public <T> void putIn(ServiceData<T> data) throws InterruptedException {
+
+ if (data.getDataType() == ServiceData.DataType.service_list) {
+ LOGGER.debug("putIn service_list queue success");
+ serviceListQueue.put((ServiceData<HttpEntity>) data);
+ } else if (data.getDataType() == ServiceData.DataType.service) {
+ serviceQueue.put((ServiceData<List<ServiceHealth>>) data);
+ } else {
+ LOGGER.warn("DATA TYPE NOT SUPPORT:"+data.getDataType());
+ }
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceConsumer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceConsumer.java
new file mode 100644
index 0000000..29d705f
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceConsumer.java
@@ -0,0 +1,167 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.msb.apiroute.SyncDataManager;
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.health.RedisHealthCheck;
+import org.onap.msb.apiroute.wrapper.MicroServiceWrapper;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.onap.msb.apiroute.wrapper.util.CommonUtil;
+import org.onap.msb.apiroute.wrapper.util.ServiceFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ServiceConsumer implements Runnable {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceConsumer.class);
+
+ private boolean isRunning = true;
+
+ private int index;
+
+
+ private static final int retryCount=3;
+
+ //缓存服务信息:key:服务名 和对应的版本列表Set<String>
+ private final Map<String, Set<String>> lastVersionResponse = new HashMap<String, Set<String>>();
+
+ public ServiceConsumer(final int index) {
+ this.index = index;
+ }
+
+
+ public void run() {
+
+ LOGGER.info("run Service Consumer Thread [" + index + "]");
+
+ while (isRunning) {
+ try {
+ ServiceData<List<ServiceHealth>> serviceData;
+
+ serviceData = QueueManager.getInstance().takeFromServiceQueue(index);
+
+ // LOGGER.info("Service Consumer Thread [" + index +
+ // "] take out serviceData from Queue successfully");
+
+ if (serviceData.getOperate() == ServiceData.Operate.delete) {
+ // 删除服务
+ deleteMicroService(serviceData);
+ } else {
+ // 更新服务
+ updateMicroService(serviceData);
+ }
+ } catch (InterruptedException e) {
+ LOGGER.error("ServiceConsumer throw InterruptedException: ", e);
+ Thread.currentThread().interrupt();
+ }
+
+ }
+ }
+
+
+
+ private void deleteMicroService(ServiceData<List<ServiceHealth>> serviceData) {
+ String serviceName = null;
+ try {
+ if (serviceData.getData() == null || serviceData.getData().size() == 0) {
+ throw new Exception("sysn deleteMicroService is wrong:serviceData is empty");
+ }
+
+ serviceName = serviceData.getData().get(0).getService().getService();
+// LOGGER.info("Service Consumer [" + index + "] start to delete MicroService:[serviceName] "
+// + serviceName);
+
+ //ServiceListCache.removeService(serviceName);
+ MicroServiceWrapper.getInstance().deleteMicroService4AllVersion(serviceName);
+
+ } catch (Exception e) {
+ LOGGER.error("delete MicroServiceInfo 4AllVersion fail from consul:[serviceName]" + serviceName, e);
+ //删除失败,重试三次
+ for(int i=0;i<retryCount;i++){
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) {
+ LOGGER.error("delete MicroServiceInfo 4AllVersion Thread.sleep throw except:" + ex.getMessage());
+ }
+ if(reDeleteMicroService(serviceName)){
+ LOGGER.info((i+1) + "/"+retryCount+" : retry to delete MicroServiceInfo success [serviceName]" + serviceName);
+ break;
+ }
+ else{
+ LOGGER.error((i+1) + "/"+retryCount+" : retry to delete MicroServiceInfo still fail [serviceName]" + serviceName);
+ }
+ }
+ }
+ }
+
+ private boolean reDeleteMicroService(String serviceName){
+ try {
+ MicroServiceWrapper.getInstance().deleteMicroService4AllVersion(serviceName);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private void updateMicroService(ServiceData<List<ServiceHealth>> serviceData) {
+
+ if (serviceData.getData() == null || serviceData.getData().size() == 0) {
+ LOGGER.warn("sysn updateMicroService is wrong:serviceData is empty ");
+ return;
+ }
+
+ String serviceName = "";
+
+ try {
+
+ serviceName = serviceData.getData().get(0).getService().getService();
+ List<ServiceHealth> serviceNodeList = serviceData.getData();
+
+
+ Map<String, MicroServiceFullInfo> microServiceInfo4version =
+ ServiceFilter.getInstance().transMicroServiceInfoFromConsul(serviceNodeList);
+
+ // 删除数据库中已不存在的版本号服务信息
+ Set<String> newAllVersion = microServiceInfo4version.keySet();
+
+ if (lastVersionResponse.containsKey(serviceName)) {
+ Set<String> dbAllVersionSet = lastVersionResponse.get(serviceName);
+ // Set<String> dbAllVersionSet=MicroServiceWrapper.getInstance().getAllVersion(serviceName);
+ Set<String> delVersionList = CommonUtil.getDiffrent(newAllVersion, dbAllVersionSet);
+
+ if (delVersionList.size() > 0) {
+
+ LOGGER.info("MicroService version is change from consul:[serviceName]" + serviceName
+ + "[version]" + delVersionList);
+
+
+ for (String version : delVersionList) {
+ MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version);
+ }
+
+ }
+ }
+
+ lastVersionResponse.put(serviceName, newAllVersion);
+
+ for (Map.Entry<String, MicroServiceFullInfo> entry : microServiceInfo4version.entrySet()) {
+ MicroServiceFullInfo new_microServiceFullInfo = entry.getValue();
+ MicroServiceWrapper.getInstance().saveServiceAndnoticeRoute(new_microServiceFullInfo);
+
+ }
+
+
+ } catch (Exception e) {
+ LOGGER.error("update MicroServiceInfo fail from consul:[serviceName]" + serviceName);
+ //更新失败,重置任务服务的modifyIndex,等待重新更新
+ RedisHealthCheck.writeCheckFlag = true;
+ SyncDataManager.resetIndex(serviceName);
+ }
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceData.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceData.java
new file mode 100644
index 0000000..aaadbe9
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceData.java
@@ -0,0 +1,53 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+public class ServiceData<T> {
+ public static enum Type {
+ consul
+ };
+
+ public static enum Operate {
+ update, delete
+ };
+
+ public static enum DataType {
+ service_list, service
+ }
+
+ private Type type = Type.consul;
+ private DataType dataType;
+ private T data;
+ private Operate operate = Operate.update;
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public DataType getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(DataType dataType) {
+ this.dataType = dataType;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public Operate getOperate() {
+ return operate;
+ }
+
+ public void setOperate(Operate operate) {
+ this.operate = operate;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListCache.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListCache.java
new file mode 100644
index 0000000..59be2e4
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListCache.java
@@ -0,0 +1,35 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ServiceListCache {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceListCache.class);
+
+ private final static AtomicReference<Set<String>> serviceNameList4Cache = new AtomicReference<Set<String>>(new HashSet<String>());
+
+ public static Set<String> getLatestServiceNamelist() {
+ return serviceNameList4Cache.get();
+ }
+
+ public static void setLatestServiceNamelist(Set<String> newServicenamelist){
+ serviceNameList4Cache.set(newServicenamelist);
+ LOGGER.info("------current total Watch Service Num :"+ newServicenamelist.size());
+ }
+
+ public synchronized static void removeService(String serviceName){
+
+ Set<String> servicenamelist=serviceNameList4Cache.get();
+ servicenamelist.remove(serviceName);
+ serviceNameList4Cache.set(servicenamelist);
+ LOGGER.info("------current total Watch Service Num :"+ servicenamelist.size());
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListConsumer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListConsumer.java
new file mode 100644
index 0000000..e3a8aa7
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListConsumer.java
@@ -0,0 +1,209 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.http.HttpEntity;
+import org.onap.msb.apiroute.SyncDataManager;
+import org.onap.msb.apiroute.wrapper.MicroServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.CommonUtil;
+import org.onap.msb.apiroute.wrapper.util.ServiceFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+
+public class ServiceListConsumer implements Runnable {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(ServiceListConsumer.class);
+
+ private boolean isRunning = true;
+
+ private int index;
+
+
+ public ServiceListConsumer() {
+ this.index = 0;
+ }
+
+ public void run() {
+ LOGGER.info("run ServiceList Consumer Thread [" + index + "]");
+
+ while (isRunning) {
+ try {
+ // 取最新一条记录
+ ServiceData<HttpEntity> serviceData = QueueManager
+ .getInstance().takeFromServiceListQueue(index);
+ LOGGER.debug("ServiceList Consumer Thread [" + index +
+ "] take out serviceData from Queue successfully");
+
+ HttpEntity newValues = serviceData.getData();
+
+ Set<String> newServiceNameList = filterServiceList(newValues);
+
+ if (ServiceListCache.getLatestServiceNamelist().size() == 0) {
+ boolean initSuccess=initServiceList(newServiceNameList);
+ if(initSuccess){
+ ServiceListCache.setLatestServiceNamelist(newServiceNameList);
+ }
+ } else {
+ updateServiceList(newServiceNameList);
+ ServiceListCache.setLatestServiceNamelist(newServiceNameList);
+ }
+
+
+ } catch (Exception e) {
+ LOGGER.error(
+ "ServiceListConsumer throw Exception: ", e);
+ }
+ }
+ }
+
+ private void startWatchService(String serviceName) {
+ // start to Watch service nodes
+
+ SyncDataManager.startWatchService(serviceName);
+ }
+
+ private void updateServiceList(Set<String> newServiceNameList) {
+ Set<String> registerServiceNameList = CommonUtil.getDiffrent(
+ ServiceListCache.getLatestServiceNamelist(), newServiceNameList);
+
+ if (registerServiceNameList.size() > 0) {
+ LOGGER.info("***need to start Watch Service num from consul :"
+ + registerServiceNameList.size());
+
+ for (String serviceName : registerServiceNameList) {
+ startWatchService(serviceName);
+ }
+ }
+ }
+
+ private boolean initServiceList(Set<String> newServiceNameList) {
+ LOGGER.info("***start to initialize service List when System startup ***");
+
+ Set<String> dbServiceNameList = MicroServiceWrapper
+ .getInstance().getAllMicroServiceKey();
+
+ if(dbServiceNameList==null){
+ LOGGER.error("init ServiceList from redis fail ");
+ return false;
+ }
+
+
+ // 对比删除redis脏数据
+ Set<String> delServiceNameList = CommonUtil.getDiffrent(
+ newServiceNameList, dbServiceNameList);
+
+ LOGGER.info("***need to delete Service num from redis :"
+ + delServiceNameList.size());
+ for (String serviceName : delServiceNameList) {
+ try {
+ MicroServiceWrapper.getInstance()
+ .deleteMicroService4AllVersion(serviceName);
+ LOGGER.info("delete MicroService success from initialize:[serviceName]"
+ + serviceName);
+
+ } catch (Exception e) {
+ LOGGER.error(
+ "initialize serviceList :Delete MicroServiceInfo serviceName:"
+ + serviceName + " FAIL : ", e);
+ }
+ }
+
+ // 启动同步开启监听全部服务列表
+ LOGGER.info("***need to start Watch Service num from initialize :"
+ + newServiceNameList.size());
+
+ for (String serviceName : newServiceNameList) {
+ startWatchService(serviceName);
+ }
+
+ return true;
+
+ }
+
+ /*private ImmutableSet<String> filterServiceList(
+ final Map<String, List<String>> serviceList) {
+ if (serviceList == null || serviceList.isEmpty()) {
+ return ImmutableSet.of();
+ }
+
+ final ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+
+ for (Map.Entry<String, List<String>> entry : serviceList.entrySet()) {
+
+ String key = entry.getKey();
+ if (key != null && !"consul".equals(key)) {
+
+ List<String> value = entry.getValue();
+ if (ServiceFilter.getInstance().isFilterService(value)) {
+ builder.add(key);
+ }
+ }
+ }
+
+ LOGGER.info("consul all service num:" + serviceList.size());
+ LOGGER.info("consul filter service num:" + builder.build().size());
+
+ return builder.build();
+ }
+*/
+ private Set<String> filterServiceList(final HttpEntity serviceList) {
+
+ if (serviceList == null || serviceList.getContentLength() == 0) {
+ return new HashSet<String>();
+ }
+
+ final Set<String> builder = new HashSet<String>();
+
+ JsonFactory f = new JsonFactory();
+ JsonParser jp = null;
+ List<String> tagList = null;
+ int inputServiceNum = 0;
+ try {
+ jp = f.createParser(serviceList.getContent());
+ jp.nextToken();
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String serviceName = jp.getCurrentName();
+ inputServiceNum++;
+ jp.nextToken();
+ tagList = new ArrayList<>();
+ while (jp.nextToken() != JsonToken.END_ARRAY) {
+ tagList.add(jp.getText());
+ }
+
+ if (serviceName != null && !"consul".equals(serviceName)) {
+ if (ServiceFilter.getInstance().isFilterService(tagList)) {
+ builder.add(serviceName);
+ }
+ }
+ }
+ } catch (IOException e) {
+ LOGGER.warn("parse service list error",e);
+ return new HashSet<String>();
+ } finally {
+ try {
+ jp.close();
+ } catch (IOException e) {
+ LOGGER.warn("parse service list error",e);
+ return new HashSet<String>();
+ }
+ }
+
+ int latestServiceNum=ServiceListCache.getLatestServiceNamelist().size();
+// if(latestServiceNum!=builder.size()){
+ LOGGER.info("[consul] all service num:" + inputServiceNum+ ", filter service num: new——" + builder.size()+" old——"+latestServiceNum);
+// }
+
+ return builder;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListQueue.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListQueue.java
new file mode 100644
index 0000000..84ea286
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListQueue.java
@@ -0,0 +1,59 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.http.HttpEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ServiceListQueue extends BaseQueue<HttpEntity> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceListQueue.class);
+
+
+ private static final int SERVICE_LIST_DATA_QUEUE_NUM = 1;
+ private static final int SERVICE_LIST_QUEUE_INDEX = 0;
+
+ public ServiceListQueue(final int queueCapacity) {
+ super(SERVICE_LIST_DATA_QUEUE_NUM,queueCapacity);
+ }
+
+ @Override
+ public void put(ServiceData<HttpEntity> data) throws InterruptedException {
+ BlockingQueue<ServiceData<HttpEntity>> queue=getQueue(SERVICE_LIST_QUEUE_INDEX);
+
+ int size=queue.size();
+// LOGGER.info("before put ServiceListQueue[size:"+size+"] success :[service num]"+data.getData().size());
+ //先清空队列
+ if(size>0){
+ queue.clear();
+ }
+ //插入记录
+ queue.put(data);
+
+ }
+
+ @Override
+ public ServiceData<HttpEntity> take(int queueIndex) throws InterruptedException {
+ BlockingQueue<ServiceData<HttpEntity>> queue = getQueue(queueIndex);
+ ServiceData<HttpEntity> serviceData = queue.take();
+ return serviceData;
+
+ /*//取队列最新一条数据
+ if (queue.isEmpty()) {
+ LOGGER.info("take a single serviceData from ServiceListQueue ");
+ return serviceData;
+ } else {
+ List<ServiceData<Map<String, List<String>>>> serviceDataList =
+ new ArrayList<ServiceData<Map<String, List<String>>>>();
+ //一次性从BlockingQueue获取所有数据
+ queue.drainTo(serviceDataList);
+ LOGGER.info("take multiple serviceDatas from ServiceListQueue :[num]"+serviceDataList.size());
+ return serviceDataList.get(serviceDataList.size() - 1);
+ }*/
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceQueue.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceQueue.java
new file mode 100644
index 0000000..6c179fc
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceQueue.java
@@ -0,0 +1,45 @@
+package org.onap.msb.apiroute.wrapper.queue;
+
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ServiceQueue extends BaseQueue<List<ServiceHealth>> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceQueue.class);
+
+ private int queneNum;
+
+ public ServiceQueue(final int queneNum,final int queueCapacity) {
+ super(queneNum,queueCapacity);
+ this.queneNum=queneNum;
+ }
+
+
+ @Override
+ public void put(final ServiceData<List<ServiceHealth>> data) throws InterruptedException {
+ if(data.getData()==null || data.getData().size()==0) return;
+
+ String serviceName = data.getData().get(0).getService().getService();
+ long serviceNameHashCode=serviceName.hashCode() & 0x7FFFFFFF;
+ int queneIndex=(int) (serviceNameHashCode % queneNum);
+
+// LOGGER.info("put ServiceQueue [serviceName.hashCode():"+serviceNameHashCode+",queneIndex:"+queneIndex+",queneNum:"+queneNum+"] :[serviceName]"+serviceName);
+
+ BlockingQueue<ServiceData<List<ServiceHealth>>> queue=getQueue(queneIndex);
+ queue.put(data);
+
+ LOGGER.info("put ServiceQueue[index:"+queneIndex+",size:"+queue.size()+"] success :[serviceName]"+serviceName);
+ }
+
+ @Override
+ public ServiceData<List<ServiceHealth>> take(final int queueIndex) throws InterruptedException {
+ return getQueue(queueIndex).take();
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/ApiRouteService.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/ApiRouteService.java
new file mode 100644
index 0000000..c8265b3
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/ApiRouteService.java
@@ -0,0 +1,159 @@
+package org.onap.msb.apiroute.wrapper.service;
+
+import org.onap.msb.apiroute.api.ApiRouteInfo;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.wrapper.dao.DAOFactory;
+import org.onap.msb.apiroute.wrapper.dao.route.IRouteDAO;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Metadata;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Node;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.RouteInfo;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Spec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+
+public class ApiRouteService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteService.class);
+ private static final ApiRouteService instance = new ApiRouteService();
+ private IRouteDAO routeDAO = DAOFactory.getRouteDAO();
+
+ private ApiRouteService() {
+ }
+
+ public static ApiRouteService getInstance() {
+ return instance;
+ }
+
+ public void saveApiRouteService2Redis(ApiRouteInfo apiRouteInfo, String routeKey) throws Exception {
+ if(apiRouteInfo ==null){
+ throw new Exception("input apiRouteInfo to be saved is null!");
+ }
+ RouteInfo routeInfo = APIRouteAdapter.toRouteInfo(apiRouteInfo);
+ routeDAO.saveRoute(routeKey, routeInfo);
+ }
+
+ public long deleteApiRouteService2Redis(String routeKey) throws Exception {
+ return routeDAO.deleteRoute(routeKey);
+ }
+
+ public long deleteMultiApiRouteService2Redis(String routeKeyPattern) throws Exception {
+ return routeDAO.deleteMultiRoute(routeKeyPattern);
+ }
+
+ public ApiRouteInfo getApiRouteInstance(String routeKey) throws Exception {
+ ApiRouteInfo apiRouteInfo = null;
+ RouteInfo routeInfo = null;
+ routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo!=null) {
+ apiRouteInfo = APIRouteAdapter.fromRouteInfo(routeInfo);
+ }
+ return apiRouteInfo;
+ }
+
+ public List<ApiRouteInfo> getMultiApiRouteInstances(String apiRedisKeyPattern) throws Exception {
+ List<ApiRouteInfo> apiRouteList = new ArrayList<>();
+ List<RouteInfo> routeInfoList = routeDAO.queryMultiRoute(apiRedisKeyPattern);
+ for (RouteInfo routeInfo : routeInfoList) {
+ if (routeInfo != null) {
+ ApiRouteInfo apiRouteInfo = APIRouteAdapter.fromRouteInfo(routeInfo);;
+ apiRouteList.add(apiRouteInfo);
+ }
+ }
+ return apiRouteList;
+ }
+
+ public void updateApiRouteStatus2Redis(String routeKey,String status) throws Exception {
+ RouteInfo routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo != null){
+ routeInfo.setStatus(status);
+ routeDAO.saveRoute(routeKey,routeInfo);
+ }else{
+ throw new Exception("service to be updated is not exist! Update failed");
+ }
+ }
+}
+
+class APIRouteAdapter {
+ public static RouteInfo toRouteInfo(ApiRouteInfo apiRouteInfo) {
+ RouteInfo routeInfo = new RouteInfo();
+ routeInfo.setApiVersion(apiRouteInfo.getVersion());
+ routeInfo.setStatus(apiRouteInfo.getStatus());
+
+
+ Spec spec = new Spec();
+ spec.setVisualRange(apiRouteInfo.getVisualRange());
+ spec.setUrl(apiRouteInfo.getUrl().trim());
+ spec.setPublish_port(apiRouteInfo.getPublish_port());
+ spec.setHost(apiRouteInfo.getHost());
+ spec.setApijson(apiRouteInfo.getApiJson());
+ spec.setApijsontype(apiRouteInfo.getApiJsonType());
+ spec.setMetricsUrl(apiRouteInfo.getMetricsUrl());
+ spec.setConsulServiceName(apiRouteInfo.getConsulServiceName());
+ spec.setUseOwnUpstream(apiRouteInfo.getUseOwnUpstream());
+ spec.setPublish_protocol(apiRouteInfo.getPublishProtocol());
+ spec.setEnable_ssl(apiRouteInfo.isEnable_ssl());
+ spec.setControl(apiRouteInfo.getControl());
+ RouteServer[] routeServers = apiRouteInfo.getServers();
+ List<Node> nodeList = new ArrayList<>();
+ for (RouteServer server: routeServers){
+ Node node = new Node();
+ node.setIp(server.getIp());
+ node.setPort(Integer.parseInt(server.getPort()));
+ node.setWeight(server.getWeight());
+ nodeList.add(node);
+ }
+ spec.setNodes(nodeList.toArray(new Node[]{}));
+ routeInfo.setSpec(spec);
+
+ Metadata metadata = new Metadata();
+ metadata.setName(apiRouteInfo.getServiceName());
+ metadata.setNamespace(apiRouteInfo.getNamespace());
+ Calendar now = Calendar.getInstance();
+ now.set(Calendar.MILLISECOND, 0);
+ metadata.setUpdateTimestamp(now.getTime());
+ routeInfo.setMetadata(metadata);
+
+ return routeInfo;
+ }
+
+ public static ApiRouteInfo fromRouteInfo(RouteInfo routeInfo) {
+ ApiRouteInfo apiRouteInfo = new ApiRouteInfo();
+
+ apiRouteInfo.setVersion(routeInfo.getApiVersion());
+ apiRouteInfo.setStatus(routeInfo.getStatus());
+
+ Spec spec = routeInfo.getSpec();
+ apiRouteInfo.setVisualRange(spec.getVisualRange());
+ apiRouteInfo.setUrl(spec.getUrl());
+ apiRouteInfo.setPublish_port(spec.getPublish_port());
+ apiRouteInfo.setHost(spec.getHost());
+ apiRouteInfo.setApiJson(spec.getApijson());
+ apiRouteInfo.setApiJsonType(spec.getApijsontype());
+ apiRouteInfo.setMetricsUrl(spec.getMetricsUrl());
+ apiRouteInfo.setConsulServiceName(spec.getConsulServiceName());
+ apiRouteInfo.setUseOwnUpstream(spec.getUseOwnUpstream());
+ apiRouteInfo.setPublishProtocol(spec.getPublish_protocol());
+ apiRouteInfo.setEnable_ssl(spec.isEnable_ssl());
+ apiRouteInfo.setControl(spec.getControl());
+ Node[] nodes = spec.getNodes();
+ List<RouteServer> routeServerList = new ArrayList<>();
+ for (Node node: nodes){
+ RouteServer routeServer = new RouteServer();
+ routeServer.setIp(node.getIp());
+ routeServer.setPort(String.valueOf(node.getPort()));
+ routeServer.setWeight(node.getWeight());
+ routeServerList.add(routeServer);
+ }
+ apiRouteInfo.setServers(routeServerList.toArray(new RouteServer[]{}));
+
+ Metadata metadata = routeInfo.getMetadata();
+ apiRouteInfo.setServiceName(metadata.getName());
+ apiRouteInfo.setNamespace(metadata.getNamespace());
+
+ return apiRouteInfo;
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/CustomRouteService.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/CustomRouteService.java
new file mode 100644
index 0000000..6ea680e
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/CustomRouteService.java
@@ -0,0 +1,152 @@
+package org.onap.msb.apiroute.wrapper.service;
+
+import org.onap.msb.apiroute.api.CustomRouteInfo;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.wrapper.dao.DAOFactory;
+import org.onap.msb.apiroute.wrapper.dao.route.IRouteDAO;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Metadata;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Node;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.RouteInfo;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Spec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+
+public class CustomRouteService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CustomRouteService.class);
+
+ private static final CustomRouteService instance = new CustomRouteService();
+ private IRouteDAO routeDAO = DAOFactory.getRouteDAO();
+
+ private CustomRouteService() {
+ }
+
+ public static CustomRouteService getInstance() {
+ return instance;
+ }
+
+ public void saveCustomRouteService2Redis(CustomRouteInfo customRouteInfo, String routeKey) throws Exception {
+ if(customRouteInfo ==null){
+ throw new Exception("input customRouteInfo to be saved is null!");
+ }
+ RouteInfo routeInfo = CustomRouteAdapter.toRouteInfo(customRouteInfo);
+ routeDAO.saveRoute(routeKey, routeInfo);
+ }
+
+ public long deleteCustomRouteService2Redis(String routeKey) throws Exception {
+ return routeDAO.deleteRoute(routeKey);
+ }
+
+ public long deleteMultiCustomRouteService2Redis(String routeKeyPattern) throws Exception {
+ return routeDAO.deleteMultiRoute(routeKeyPattern);
+ }
+
+ public CustomRouteInfo getCustomRouteInstance(String routeKey) throws Exception {
+ CustomRouteInfo customRouteInfo = null;
+ RouteInfo routeInfo = null;
+ routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo!=null) {
+ customRouteInfo = CustomRouteAdapter.fromRouteInfo(routeInfo);
+ }
+ return customRouteInfo;
+ }
+
+ public List<CustomRouteInfo> getMultiCustomRouteInstances(String customRedisKeyPattern) throws Exception {
+ List<CustomRouteInfo> customRouteList = new ArrayList<>();
+ List<RouteInfo> routeInfoList = routeDAO.queryMultiRoute(customRedisKeyPattern);
+ for (RouteInfo routeInfo : routeInfoList) {
+ if (routeInfo != null) {
+ CustomRouteInfo customRouteInfo = CustomRouteAdapter.fromRouteInfo(routeInfo);;
+ customRouteList.add(customRouteInfo);
+ }
+ }
+ return customRouteList;
+ }
+
+ public void updateCustomRouteStatus2Redis(String routeKey,String status) throws Exception {
+ RouteInfo routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo != null){
+ routeInfo.setStatus(status);
+ routeDAO.saveRoute(routeKey,routeInfo);
+ }else{
+ throw new Exception("service to be updated is not exist! Update failed");
+ }
+ }
+
+}
+
+class CustomRouteAdapter {
+ public static RouteInfo toRouteInfo(CustomRouteInfo customRouteInfo) {
+ RouteInfo routeInfo = new RouteInfo();
+ routeInfo.setStatus(customRouteInfo.getStatus());
+
+
+ Spec spec = new Spec();
+ spec.setVisualRange(customRouteInfo.getVisualRange());
+ spec.setUrl(customRouteInfo.getUrl().trim());
+ spec.setPublish_port(customRouteInfo.getPublish_port());
+ spec.setHost(customRouteInfo.getHost());
+ spec.setConsulServiceName(customRouteInfo.getConsulServiceName());
+ spec.setUseOwnUpstream(customRouteInfo.getUseOwnUpstream());
+ spec.setPublish_protocol(customRouteInfo.getPublishProtocol());
+ spec.setEnable_ssl(customRouteInfo.isEnable_ssl());
+ spec.setControl(customRouteInfo.getControl());
+ RouteServer[] routeServers = customRouteInfo.getServers();
+ List<Node> nodeList = new ArrayList<>();
+ for (RouteServer server: routeServers){
+ Node node = new Node();
+ node.setIp(server.getIp());
+ node.setPort(Integer.parseInt(server.getPort()));
+ node.setWeight(server.getWeight());
+ nodeList.add(node);
+ }
+ spec.setNodes(nodeList.toArray(new Node[]{}));
+ routeInfo.setSpec(spec);
+
+ Metadata metadata = new Metadata();
+ metadata.setName(customRouteInfo.getServiceName());
+ metadata.setNamespace(customRouteInfo.getNamespace());
+ Calendar now = Calendar.getInstance();
+ now.set(Calendar.MILLISECOND, 0);
+ metadata.setUpdateTimestamp(now.getTime());
+ routeInfo.setMetadata(metadata);
+
+ return routeInfo;
+ }
+
+ public static CustomRouteInfo fromRouteInfo(RouteInfo routeInfo) {
+ CustomRouteInfo customRouteInfo = new CustomRouteInfo();
+ customRouteInfo.setStatus(routeInfo.getStatus());
+
+ Spec spec = routeInfo.getSpec();
+ customRouteInfo.setVisualRange(spec.getVisualRange());
+ customRouteInfo.setUrl(spec.getUrl());
+ customRouteInfo.setPublish_port(spec.getPublish_port());
+ customRouteInfo.setHost(spec.getHost());
+ customRouteInfo.setConsulServiceName(spec.getConsulServiceName());
+ customRouteInfo.setUseOwnUpstream(spec.getUseOwnUpstream());
+ customRouteInfo.setPublishProtocol(spec.getPublish_protocol());
+ customRouteInfo.setEnable_ssl(spec.isEnable_ssl());
+ customRouteInfo.setControl(spec.getControl());
+ Node[] nodes = spec.getNodes();
+ List<RouteServer> routeServerList = new ArrayList<>();
+ for (Node node: nodes){
+ RouteServer routeServer = new RouteServer();
+ routeServer.setIp(node.getIp());
+ routeServer.setPort(String.valueOf(node.getPort()));
+ routeServer.setWeight(node.getWeight());
+ routeServerList.add(routeServer);
+ }
+ customRouteInfo.setServers(routeServerList.toArray(new RouteServer[]{}));
+
+ Metadata metadata = routeInfo.getMetadata();
+ customRouteInfo.setServiceName(metadata.getName());
+ customRouteInfo.setNamespace(metadata.getNamespace());
+
+ return customRouteInfo;
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/IuiRouteService.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/IuiRouteService.java
new file mode 100644
index 0000000..c46cb75
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/IuiRouteService.java
@@ -0,0 +1,151 @@
+package org.onap.msb.apiroute.wrapper.service;
+
+import org.onap.msb.apiroute.api.IuiRouteInfo;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.wrapper.dao.DAOFactory;
+import org.onap.msb.apiroute.wrapper.dao.route.IRouteDAO;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Metadata;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Node;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.RouteInfo;
+import org.onap.msb.apiroute.wrapper.dao.route.bean.Spec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+
+public class IuiRouteService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CustomRouteService.class);
+
+ private static final IuiRouteService instance = new IuiRouteService();
+ private IRouteDAO routeDAO = DAOFactory.getRouteDAO();
+
+ private IuiRouteService() {
+ }
+
+ public static IuiRouteService getInstance() {
+ return instance;
+ }
+
+ public void saveIuiRouteService2Redis(IuiRouteInfo iuiRouteInfo, String routeKey) throws Exception {
+ if(iuiRouteInfo ==null){
+ throw new Exception("input apiRouteInfo to be saved is null!");
+ }
+ RouteInfo routeInfo = IuiRouteAdapter.toRouteInfo(iuiRouteInfo);
+ routeDAO.saveRoute(routeKey, routeInfo);
+ }
+
+ public long deleteIuiRouteService2Redis(String routeKey) throws Exception {
+ return routeDAO.deleteRoute(routeKey);
+ }
+
+ public long deleteMultiIuiRouteService2Redis(String routeKeyPattern) throws Exception {
+ return routeDAO.deleteMultiRoute(routeKeyPattern);
+ }
+
+ public IuiRouteInfo getIuiRouteInstance(String routeKey) throws Exception {
+ IuiRouteInfo iuiRouteInfo = null;
+ RouteInfo routeInfo = null;
+ routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo!=null) {
+ iuiRouteInfo = IuiRouteAdapter.fromRouteInfo(routeInfo);
+ }
+ return iuiRouteInfo;
+ }
+
+ public List<IuiRouteInfo> getMultiIuiRouteInstances(String apiRedisKeyPattern) throws Exception {
+ List<IuiRouteInfo> iuiRouteList = new ArrayList<>();
+ List<RouteInfo> routeInfoList = routeDAO.queryMultiRoute(apiRedisKeyPattern);
+ for (RouteInfo routeInfo : routeInfoList) {
+ if (routeInfo != null) {
+ IuiRouteInfo iuiRouteInfo = IuiRouteAdapter.fromRouteInfo(routeInfo);;
+ iuiRouteList.add(iuiRouteInfo);
+ }
+ }
+ return iuiRouteList;
+ }
+
+ public void updateIuiRouteStatus2Redis(String routeKey,String status) throws Exception {
+ RouteInfo routeInfo = routeDAO.queryRoute(routeKey);
+ if(routeInfo != null){
+ routeInfo.setStatus(status);
+ routeDAO.saveRoute(routeKey,routeInfo);
+ }else{
+ throw new Exception("service to be updated is not exist! Update failed");
+ }
+ }
+
+}
+
+class IuiRouteAdapter {
+ public static RouteInfo toRouteInfo(IuiRouteInfo iuiRouteInfo) {
+ RouteInfo routeInfo = new RouteInfo();
+ routeInfo.setStatus(iuiRouteInfo.getStatus());
+
+
+ Spec spec = new Spec();
+ spec.setVisualRange(iuiRouteInfo.getVisualRange());
+ spec.setUrl(iuiRouteInfo.getUrl().trim());
+ spec.setPublish_port(iuiRouteInfo.getPublish_port());
+ spec.setHost(iuiRouteInfo.getHost());
+ spec.setConsulServiceName(iuiRouteInfo.getConsulServiceName());
+ spec.setUseOwnUpstream(iuiRouteInfo.getUseOwnUpstream());
+ spec.setPublish_protocol(iuiRouteInfo.getPublishProtocol());
+ spec.setEnable_ssl(iuiRouteInfo.isEnable_ssl());
+ spec.setControl(iuiRouteInfo.getControl());
+ RouteServer[] routeServers = iuiRouteInfo.getServers();
+ List<Node> nodeList = new ArrayList<>();
+ for (RouteServer server: routeServers){
+ Node node = new Node();
+ node.setIp(server.getIp());
+ node.setPort(Integer.parseInt(server.getPort()));
+ node.setWeight(server.getWeight());
+ nodeList.add(node);
+ }
+ spec.setNodes(nodeList.toArray(new Node[]{}));
+ routeInfo.setSpec(spec);
+
+ Metadata metadata = new Metadata();
+ metadata.setName(iuiRouteInfo.getServiceName());
+ metadata.setNamespace(iuiRouteInfo.getNamespace());
+ Calendar now = Calendar.getInstance();
+ now.set(Calendar.MILLISECOND, 0);
+ metadata.setUpdateTimestamp(now.getTime());
+ routeInfo.setMetadata(metadata);
+ return routeInfo;
+ }
+
+ public static IuiRouteInfo fromRouteInfo(RouteInfo routeInfo) {
+ IuiRouteInfo iuiRouteInfo = new IuiRouteInfo();
+ iuiRouteInfo.setStatus(routeInfo.getStatus());
+
+ Spec spec = routeInfo.getSpec();
+ iuiRouteInfo.setVisualRange(spec.getVisualRange());
+ iuiRouteInfo.setUrl(spec.getUrl());
+ iuiRouteInfo.setPublish_port(spec.getPublish_port());
+ iuiRouteInfo.setHost(spec.getHost());
+ iuiRouteInfo.setConsulServiceName(spec.getConsulServiceName());
+ iuiRouteInfo.setUseOwnUpstream(spec.getUseOwnUpstream());
+ iuiRouteInfo.setPublishProtocol(spec.getPublish_protocol());
+ iuiRouteInfo.setEnable_ssl(spec.isEnable_ssl());
+ iuiRouteInfo.setControl(spec.getControl());
+ Node[] nodes = spec.getNodes();
+ List<RouteServer> routeServerList = new ArrayList<>();
+ for (Node node: nodes){
+ RouteServer routeServer = new RouteServer();
+ routeServer.setIp(node.getIp());
+ routeServer.setPort(String.valueOf(node.getPort()));
+ routeServer.setWeight(node.getWeight());
+ routeServerList.add(routeServer);
+ }
+ iuiRouteInfo.setServers(routeServerList.toArray(new RouteServer[]{}));
+
+ Metadata metadata = routeInfo.getMetadata();
+ iuiRouteInfo.setServiceName(metadata.getName());
+ iuiRouteInfo.setNamespace(metadata.getNamespace());
+
+ return iuiRouteInfo;
+ }
+} \ No newline at end of file
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullService.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullService.java
new file mode 100644
index 0000000..af005ae
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullService.java
@@ -0,0 +1,220 @@
+package org.onap.msb.apiroute.wrapper.service;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.wrapper.dao.DAOFactory;
+import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper;
+import org.onap.msb.apiroute.wrapper.dao.service.IServiceDAO;
+import org.onap.msb.apiroute.wrapper.dao.service.bean.Metadata;
+import org.onap.msb.apiroute.wrapper.dao.service.bean.ServiceInfo;
+import org.onap.msb.apiroute.wrapper.dao.service.bean.Spec;
+import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+public class MicroServiceFullService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceFullService.class);
+
+ private static MicroServiceFullService instance = new MicroServiceFullService();
+
+ private IServiceDAO serviceDAO = DAOFactory.getServiceDAO();
+
+ private MicroServiceFullService() {
+ }
+
+ public static MicroServiceFullService getInstance() {
+ return instance;
+ }
+
+ public List<MicroServiceFullInfo> getAllMicroServiceInstances() throws Exception {
+ String serviceKeyPattern = MicroServiceUtil.getPrefixedKey("*");
+
+ List<MicroServiceFullInfo> microServiceFullInfoList = new ArrayList<>();
+ List<ServiceInfo> serviceInfoList = serviceDAO.queryMultiService(serviceKeyPattern);
+ for (ServiceInfo serviceInfo : serviceInfoList) {
+ if (serviceInfo != null) {
+ MicroServiceFullInfo microServiceFullInfo = MicroServiceFullAdapter.fromServiceInfo(serviceInfo);
+ ;
+ microServiceFullInfoList.add(microServiceFullInfo);
+ }
+ }
+ return microServiceFullInfoList;
+ }
+
+ public Set<String> getAllMicroServiceKey() throws Exception {
+ final Set<String> builder = new HashSet<String>();
+
+ String serviceKeyPattern = MicroServiceUtil.getPrefixedKey("*");
+ Set<String> serviceKeySet = RedisAccessWrapper.filterKeys(serviceKeyPattern);
+
+ Pattern serviceKeyRegexPattern = MicroServiceUtil.getServiceKeyRegexPattern();
+ for (String serviceKey : serviceKeySet) {
+ Matcher matcher = serviceKeyRegexPattern.matcher(serviceKey);
+ if (matcher.matches()) {
+ builder.add(matcher.group("servicename"));
+ }
+ }
+ return builder;
+ }
+
+ public void saveMicroServiceInfo2Redis(MicroServiceFullInfo microServiceFullInfo) throws Exception {
+ if(microServiceFullInfo ==null){
+ throw new Exception("input microServiceInfo to be saved is null!");
+ }
+ ServiceInfo serviceInfo = MicroServiceFullAdapter.toServiceInfo(microServiceFullInfo);
+ String serviceKey = MicroServiceUtil.getServiceKey(microServiceFullInfo.getServiceName(),microServiceFullInfo.getVersion());
+ serviceDAO.saveService(serviceKey,serviceInfo);
+ }
+
+ public void updateMicroServiceStatus(String serviceName, String version, String status)
+ throws Exception {
+ if (null == version || "null".equals(version)) {
+ version = "";
+ }
+ String serviceKey = MicroServiceUtil.getServiceKey(serviceName, version);
+ ServiceInfo serviceInfo = serviceDAO.queryService(serviceKey);
+ if(serviceInfo != null){
+ serviceInfo.setStatus(status);
+ serviceDAO.saveService(serviceKey,serviceInfo);
+ }
+ }
+
+ public boolean existsMicroServiceInstance(String serviceName, String version)
+ throws Exception {
+ if (null == version || "null".equals(version)) {
+ version = "";
+ }
+ String serviceKey = MicroServiceUtil.getServiceKey(serviceName, version);
+ return RedisAccessWrapper.isExist(serviceKey);
+ }
+
+ public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version)
+ throws Exception {
+ if (null == version || "null".equals(version)) {
+ version = "";
+ }
+ String serviceKey = MicroServiceUtil.getServiceKey(serviceName, version);
+
+ MicroServiceFullInfo microServiceInfo = null;
+
+ ServiceInfo serviceInfo = null;
+ serviceInfo = serviceDAO.queryService(serviceKey);
+ if(serviceInfo!=null) {
+ microServiceInfo = MicroServiceFullAdapter.fromServiceInfo(serviceInfo);
+ }
+ return microServiceInfo;
+ }
+
+ /**
+ * query all the versions of the given ServiceName
+ * @param serviceName
+ * @return
+ * @throws Exception
+ */
+ public List<MicroServiceFullInfo> getAllVersionsOfTheService(String serviceName) throws Exception {
+ String serviceKeyPattern = MicroServiceUtil.getPrefixedKey(serviceName, "*");
+
+ List<MicroServiceFullInfo> microServiceFullInfoList = new ArrayList<>();
+ List<ServiceInfo> serviceInfoList = serviceDAO.queryMultiService(serviceKeyPattern);
+ for (ServiceInfo serviceInfo : serviceInfoList) {
+ if (serviceInfo != null) {
+ MicroServiceFullInfo microServiceFullInfo = MicroServiceFullAdapter.fromServiceInfo(serviceInfo);
+ microServiceFullInfoList.add(microServiceFullInfo);
+ }
+ }
+ return microServiceFullInfoList;
+ }
+
+ public void deleteMicroService(String serviceName, String version) throws Exception {
+ if (null == version || "null".equals(version)) {
+ version = "";
+ }
+ String serviceKey = MicroServiceUtil.getServiceKey(serviceName, version);
+ serviceDAO.deleteService(serviceKey);
+ }
+
+ public long deleteMultiMicroService(String keyPattern) throws Exception {
+ return serviceDAO.deleteMultiService(keyPattern);
+ }
+}
+
+class MicroServiceFullAdapter {
+ public static ServiceInfo toServiceInfo(MicroServiceFullInfo microServiceFullInfo) {
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.setApiVersion(microServiceFullInfo.getVersion());
+ serviceInfo.setStatus(microServiceFullInfo.getStatus());
+
+
+ Spec spec = new Spec();
+ spec.setVisualRange(microServiceFullInfo.getVisualRange());
+ spec.setUrl(microServiceFullInfo.getUrl());
+ spec.setPublish_port(microServiceFullInfo.getPublish_port());
+ spec.setHost(microServiceFullInfo.getHost());
+ spec.setProtocol(microServiceFullInfo.getProtocol());
+ spec.setLb_policy(microServiceFullInfo.getLb_policy());
+ spec.setEnable_ssl(microServiceFullInfo.isEnable_ssl());
+ Set<org.onap.msb.apiroute.api.Node> nodeSet = microServiceFullInfo.getNodes();
+ List<org.onap.msb.apiroute.wrapper.dao.service.bean.Node> serviceNodeList = new ArrayList<>();
+ for (org.onap.msb.apiroute.api.Node node : nodeSet) {
+ org.onap.msb.apiroute.wrapper.dao.service.bean.Node serviceNode = new org.onap.msb.apiroute.wrapper.dao.service.bean.Node();
+ serviceNode.setIp(node.getIp());
+ serviceNode.setPort(node.getPort());
+ serviceNode.setTtl(node.getTtl());
+ serviceNodeList.add(serviceNode);
+ }
+ spec.setNodes(serviceNodeList.toArray(new org.onap.msb.apiroute.wrapper.dao.service.bean.Node[]{}));
+ serviceInfo.setSpec(spec);
+
+ Metadata metadata = new Metadata();
+ metadata.setName(microServiceFullInfo.getServiceName());
+ metadata.setNamespace(microServiceFullInfo.getNamespace());
+ Calendar now = Calendar.getInstance();
+ now.set(Calendar.MILLISECOND, 0);
+ metadata.setUpdateTimestamp(now.getTime());
+ serviceInfo.setMetadata(metadata);
+
+ return serviceInfo;
+ }
+
+ public static MicroServiceFullInfo fromServiceInfo(ServiceInfo serviceInfo) {
+ MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo();
+
+ microServiceFullInfo.setVersion(serviceInfo.getApiVersion());
+ microServiceFullInfo.setStatus(serviceInfo.getStatus());
+
+ Spec spec = serviceInfo.getSpec();
+ microServiceFullInfo.setVisualRange(spec.getVisualRange());
+ microServiceFullInfo.setUrl(spec.getUrl());
+ microServiceFullInfo.setPath(spec.getPath());
+ microServiceFullInfo.setPublish_port(spec.getPublish_port());
+ microServiceFullInfo.setHost(spec.getHost());
+ microServiceFullInfo.setProtocol(spec.getProtocol());
+ microServiceFullInfo.setLb_policy(spec.getLb_policy());
+ microServiceFullInfo.setEnable_ssl(spec.isEnable_ssl());
+ org.onap.msb.apiroute.wrapper.dao.service.bean.Node[] serviceNodes = spec.getNodes();
+ List<org.onap.msb.apiroute.api.Node> nodeList = new ArrayList<>();
+ for (org.onap.msb.apiroute.wrapper.dao.service.bean.Node serviceNode : serviceNodes) {
+ org.onap.msb.apiroute.api.Node node = new org.onap.msb.apiroute.api.Node();
+ node.setIp(serviceNode.getIp());
+ node.setPort(String.valueOf(serviceNode.getPort()));
+ node.setTtl(serviceNode.getTtl());
+ nodeList.add(node);
+ }
+ microServiceFullInfo.setNodes(new HashSet<org.onap.msb.apiroute.api.Node>(nodeList));
+
+ Metadata metadata = serviceInfo.getMetadata();
+ microServiceFullInfo.setServiceName(metadata.getName());
+ microServiceFullInfo.setNamespace(metadata.getNamespace());
+
+ return microServiceFullInfo;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java
new file mode 100644
index 0000000..68e31f8
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.serviceListener;
+
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.Node;
+
+
+public interface IMicroServiceChangeListener {
+ public void onSave(MicroServiceFullInfo microServiceInfo) throws Exception;
+
+ public void onDelete(MicroServiceFullInfo microServiceInfo) throws Exception;
+
+ public void onChange(String serviceName,String version,MicroServiceFullInfo microServiceInfo) throws Exception;
+
+ public void onStatusChange(String serviceName,String version,String host, String protocol,String publish_port,
+ String status);
+
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListener.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListener.java
new file mode 100644
index 0000000..73b6a9c
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListener.java
@@ -0,0 +1,779 @@
+package org.onap.msb.apiroute.wrapper.serviceListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.api.ApiRouteInfo;
+import org.onap.msb.apiroute.api.CustomRouteInfo;
+import org.onap.msb.apiroute.api.DiscoverInfo;
+import org.onap.msb.apiroute.api.IuiRouteInfo;
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.Node;
+import org.onap.msb.apiroute.api.PublishFullAddress;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.wrapper.ApiRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.IuiRouteServiceWrapper;
+import org.onap.msb.apiroute.wrapper.util.CommonUtil;
+import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
+import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
+import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil;
+import org.onap.msb.apiroute.wrapper.util.RegExpTestUtil;
+import org.onap.msb.apiroute.wrapper.util.RouteUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+public class MicroServiceChangeListener implements IMicroServiceChangeListener {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceChangeListener.class);
+
+ @Override
+ public void onDelete(MicroServiceFullInfo microServiceInfo) throws Exception {
+
+ String path = microServiceInfo.getPath();
+
+ String[] routeWay = ConfigUtil.getInstance().getRouteWay();
+
+ for (int i = 0; i < routeWay.length; i++) {
+
+ if (StringUtils.isNotBlank(path) && !"/".equals(path)) {
+ // 1.按path优先判断类型
+ String host = getHost(microServiceInfo);
+ deleteServiceByUrl(path, host, microServiceInfo.getPublish_port(), routeWay[i]);
+ } else {
+ // 2.1 域名判断url
+ if (RouteUtil.ROUTEWAY_DOMAIN.equals(routeWay[i]) && ifRootByDomain(microServiceInfo)) {
+ deleteServiceByDomain4Root(microServiceInfo);
+ } else {
+ // 2.2 按协议优先判断类型
+ deleteServiceByProtocol(microServiceInfo, routeWay[i]);
+ }
+
+ }
+
+
+ }
+
+ }
+
+
+ @Override
+ public void onSave(MicroServiceFullInfo microServiceInfo) throws Exception {
+
+ String path = microServiceInfo.getPath();
+ String[] routeWay = ConfigUtil.getInstance().getRouteWay();
+
+ for (int i = 0; i < routeWay.length; i++) {
+ // 1.按path优先判断类型
+ if (StringUtils.isNotBlank(path) && !"/".equals(path)) {
+ saveServiceByPath(microServiceInfo, routeWay[i]);
+ } else {
+ // 2.1 域名判断url
+ if (RouteUtil.ROUTEWAY_DOMAIN.equals(routeWay[i]) && ifRootByDomain(microServiceInfo)) {
+ saveServiceByDomain4Root(microServiceInfo);
+ } else {
+ // 2.2 按协议优先判断类型
+ saveServiceByProtocol(microServiceInfo, routeWay[i]);
+ }
+ }
+ }
+
+ }
+
+
+ //判断按协议发布地址是否和注册的URL一致,如果一致发布地址保存为/,否则保存为协议类型的发布地址
+ private boolean ifRootByDomain(MicroServiceFullInfo microServiceInfo){
+
+
+ if("/".equals(microServiceInfo.getUrl())) return true;
+
+ String protocol = microServiceInfo.getProtocol();
+ String routeName =
+ RouteUtil.getRouteNameByns(microServiceInfo.getServiceName(),
+ microServiceInfo.getNamespace());
+ String publishUrl="";
+ String version = "";
+ if (StringUtils.isNotBlank(microServiceInfo.getVersion())) {
+ version = "/" + microServiceInfo.getVersion();
+ }
+
+ switch (protocol) {
+ case RouteUtil.PROTOCOL_UI:
+ publishUrl = "/iui/" + routeName;
+ break;
+ case RouteUtil.PROTOCOL_REST:
+ publishUrl = "/api/" + routeName + version;
+ break;
+ case RouteUtil.PROTOCOL_HTTP:
+ publishUrl = "/" + routeName + version;
+ break;
+ }
+ return publishUrl.equals(microServiceInfo.getUrl());
+
+ }
+
+
+ private void saveServiceByDomain4Root(MicroServiceFullInfo microServiceInfo) throws Exception {
+
+ CustomRouteInfo[] customRouteInfos =
+ this.buildCustomRouteInfo(microServiceInfo, "/", RouteUtil.ROUTEWAY_DOMAIN);
+ for (int i = 0; i < customRouteInfos.length; i++) {
+ customRouteInfos[i].setUrl("/");
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfos[i],
+ RouteUtil.ROUTEWAY_DOMAIN);
+ }
+ }
+
+ private void deleteServiceByDomain4Root(MicroServiceFullInfo microServiceInfo) throws Exception {
+
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute("/", getHost(microServiceInfo),
+ microServiceInfo.getPublish_port(), RouteUtil.ROUTEWAY_DOMAIN);
+ }
+
+ /**
+ * @Title saveServiceByProtocol
+ * @Description TODO(按用户注册协议保存服务)
+ * @param microServiceInfo
+ * @param routeWay
+ * @return void
+ * @throws Exception
+ */
+ private void saveServiceByProtocol(MicroServiceFullInfo microServiceInfo, String routeWay)
+ throws Exception {
+ String protocol = microServiceInfo.getProtocol();
+ String routeName =
+ RouteUtil.getRouteNameByns(microServiceInfo.getServiceName(),
+ microServiceInfo.getNamespace());
+
+ switch (protocol) {
+ case RouteUtil.PROTOCOL_UI:
+ IuiRouteInfo[] iuiRouteInfos =
+ this.buildIuiRouteInfo(microServiceInfo, routeName, routeWay);
+ for (int i = 0; i < iuiRouteInfos.length; i++) {
+ IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfos[i], routeWay);
+ }
+ break;
+
+ case RouteUtil.PROTOCOL_REST:
+
+ ApiRouteInfo[] apiRouteInfos =
+ this.buildApiRouteInfo(microServiceInfo, routeName, microServiceInfo.getVersion(),
+ routeWay);
+ for (int i = 0; i < apiRouteInfos.length; i++) {
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfos[i], routeWay);
+ }
+ break;
+ case RouteUtil.PROTOCOL_HTTP:
+ CustomRouteInfo[] customRouteInfos =
+ this.buildCustomRouteInfo(microServiceInfo,
+ getHttpName(routeName, microServiceInfo.getVersion()), routeWay);
+ for (int i = 0; i < customRouteInfos.length; i++) {
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfos[i],
+ routeWay);
+ }
+ break;
+ }
+ }
+
+ /**
+ * @Title deleteServiceByProtocol
+ * @Description TODO(按用户注册协议删除服务)
+ * @param microServiceInfo
+ * @param routeWay
+ * @return void
+ */
+ private void deleteServiceByProtocol(MicroServiceFullInfo microServiceInfo, String routeWay) {
+ String protocol = microServiceInfo.getProtocol();
+ String host = getHost(microServiceInfo);
+ String routeName =
+ RouteUtil.getRouteNameByns(microServiceInfo.getServiceName(),
+ microServiceInfo.getNamespace());
+
+ if (RouteUtil.PROTOCOL_UI.equals(protocol)) {
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(routeName, host, publishPorts[0],
+ routeWay);
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(routeName, host, publishPorts[1],
+ routeWay);
+ return;
+ }
+ }
+
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(routeName, host,
+ microServiceInfo.getPublish_port(), routeWay);
+ } else if (RouteUtil.PROTOCOL_REST.equals(protocol)) {
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(routeName,
+ microServiceInfo.getVersion(), host, publishPorts[0], routeWay);
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(routeName,
+ microServiceInfo.getVersion(), host, publishPorts[1], routeWay);
+ return;
+ }
+ }
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(routeName, microServiceInfo.getVersion(),
+ host, microServiceInfo.getPublish_port(), routeWay);
+ } else if (RouteUtil.PROTOCOL_HTTP.equals(protocol)) {
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(
+ getHttpName(routeName, microServiceInfo.getVersion()), host, publishPorts[0],
+ routeWay);
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(
+ getHttpName(routeName, microServiceInfo.getVersion()), host, publishPorts[1],
+ routeWay);
+ return;
+ }
+ }
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(
+ getHttpName(routeName, microServiceInfo.getVersion()), host,
+ microServiceInfo.getPublish_port(), routeWay);
+ }
+ }
+
+ /**
+ * @Title saveServiceByUrl
+ * @Description TODO(按URL地址判断服务协议并保存到路由表)
+ * @param url
+ * @param microServiceInfo
+ * @param routeWay
+ * @return void
+ * @throws Exception
+ */
+ private void saveServiceByPath(MicroServiceFullInfo microServiceInfo, String routeWay)
+ throws Exception {
+ String redis_serviceName;
+ String path=microServiceInfo.getPath();
+ if (RegExpTestUtil.apiRouteUrlRegExpTest(path)) {
+ // protocol:"REST"
+ String[] serviceKey = RegExpTestUtil.apiServiceNameMatch4URL(path);
+ if (serviceKey == null) {
+ LOGGER.error("save api Service ByUrl is error:[url]" + path);
+ return;
+ }
+ redis_serviceName = serviceKey[0];
+ String redis_serviceVersion = serviceKey[1];
+
+ ApiRouteInfo[] apiRouteInfos =
+ this.buildApiRouteInfo(microServiceInfo, redis_serviceName, redis_serviceVersion,
+ routeWay);
+ for (int i = 0; i < apiRouteInfos.length; i++) {
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfos[i], routeWay);
+ }
+ } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(path)) {
+ // protocol:"UI"
+ // 根据url获取服务名
+ redis_serviceName = RegExpTestUtil.iuiServiceNameMatch4URL(path);
+ if (redis_serviceName == null) {
+ LOGGER.error("save iui Service ByUrl is error:[url]" + path);
+ return;
+ }
+ IuiRouteInfo[] iuiRouteInfos =
+ this.buildIuiRouteInfo(microServiceInfo, redis_serviceName, routeWay);
+ for (int i = 0; i < iuiRouteInfos.length; i++) {
+ IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfos[i], routeWay);
+ }
+ } else {
+ // protocol:"HTTP";
+ redis_serviceName = path;
+ CustomRouteInfo[] customRouteInfos =
+ this.buildCustomRouteInfo(microServiceInfo, redis_serviceName, routeWay);
+ for (int i = 0; i < customRouteInfos.length; i++) {
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfos[i],
+ routeWay);
+ }
+ }
+ }
+
+ /**
+ * @Title deleteServiceByUrl
+ * @Description TODO(按URL地址判断服务协议并从路由表删除)
+ * @param url
+ * @param host
+ * @param publish_port
+ * @param routeWay
+ * @return void
+ */
+ private void deleteServiceByUrl(String url, String host, String publish_port, String routeWay) {
+ // 根据Url格式判断服务类型
+ String redis_serviceName;
+
+ if (RegExpTestUtil.apiRouteUrlRegExpTest(url)) {
+ // protocol:"REST"
+ String[] serviceKey = RegExpTestUtil.apiServiceNameMatch4URL(url);
+ if (serviceKey == null) {
+ LOGGER.error("delete api Service ByUrl is error:[url]" + url);
+ return;
+ }
+
+ redis_serviceName = serviceKey[0];
+ String redis_serviceVersion = serviceKey[1];
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(publish_port, "|");
+ if (publishPorts.length == 2) {
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(redis_serviceName,
+ redis_serviceVersion, host, publishPorts[0], routeWay);
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(redis_serviceName,
+ redis_serviceVersion, host, publishPorts[1], routeWay);
+ return;
+ }
+ }
+
+ ApiRouteServiceWrapper.getInstance().deleteApiRoute(redis_serviceName, redis_serviceVersion,
+ host, publish_port, routeWay);
+
+
+
+ } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url)) {
+ // protocol:"UI"
+ // 根据url获取服务名
+ redis_serviceName = RegExpTestUtil.iuiServiceNameMatch4URL(url);
+ if (redis_serviceName == null) {
+ LOGGER.error("delete iui Service ByUrl is error:[url]" + url);
+ return;
+ }
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(publish_port, "|");
+ if (publishPorts.length == 2) {
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(redis_serviceName, host,
+ publishPorts[0], routeWay);
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(redis_serviceName, host,
+ publishPorts[1], routeWay);
+ return;
+ }
+ }
+
+ IuiRouteServiceWrapper.getInstance().deleteIuiRoute(redis_serviceName, host, publish_port,
+ routeWay);
+
+
+ } else {
+ // protocol:"HTTP";
+ redis_serviceName = url;
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ // two ports
+ String[] publishPorts = StringUtils.split(publish_port, "|");
+ if (publishPorts.length == 2) {
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(redis_serviceName, host,
+ publishPorts[0], routeWay);
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(redis_serviceName, host,
+ publishPorts[1], routeWay);
+ return;
+ }
+ }
+
+ CustomRouteServiceWrapper.getInstance().deleteCustomRoute(redis_serviceName, host,
+ publish_port, routeWay);
+ }
+
+ }
+
+
+
+ /**
+ * @Title getCustomName
+ * @Description TODO(获取HTTP服务路由名)
+ * @param routeName
+ * @param version
+ * @return
+ * @return String
+ */
+ private String getHttpName(String routeName, String version) {
+ if (!routeName.startsWith("/")) {
+ routeName = "/" + routeName;
+ }
+
+ if (StringUtils.isNotBlank(version)) {
+ routeName += "/" + version;
+ }
+ return routeName;
+ }
+
+
+ private String getHost(MicroServiceFullInfo microServiceInfo) {
+ String host;
+ if (StringUtils.isNotBlank(microServiceInfo.getHost())) {
+ host = microServiceInfo.getHost().toLowerCase();
+ } else {
+ // host为空,取默认规则 服务名-ns
+ host = microServiceInfo.getServiceName().toLowerCase();
+ }
+
+ return host;
+ }
+
+
+
+ @Override
+ public void onChange(String serviceName, String version, MicroServiceFullInfo microServiceInfo)
+ throws Exception {
+ // TODO Auto-generated method stub
+
+ if (RouteUtil.PROTOCOL_UI.equals(microServiceInfo.getProtocol())) {
+ IuiRouteInfo[] iuiRouteInfos =
+ this.buildIuiRouteInfo(microServiceInfo, serviceName, RouteUtil.ROUTEWAY_IP);
+ for (int i = 0; i < iuiRouteInfos.length; i++) {
+ IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfos[i],
+ RouteUtil.ROUTEWAY_IP);
+ }
+ } else if (RouteUtil.PROTOCOL_REST.equals(microServiceInfo.getProtocol())) {
+ ApiRouteInfo[] apiRouteInfos =
+ this.buildApiRouteInfo(microServiceInfo, serviceName, version, RouteUtil.ROUTEWAY_IP);
+ for (int i = 0; i < apiRouteInfos.length; i++) {
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfos[i],
+ RouteUtil.ROUTEWAY_IP);
+ }
+ } else if (RouteUtil.PROTOCOL_HTTP.equals(microServiceInfo.getProtocol())) {
+ if (!serviceName.startsWith("/")) {
+ serviceName = "/" + serviceName;
+ }
+ CustomRouteInfo[] customRouteInfos =
+ this.buildCustomRouteInfo(microServiceInfo, serviceName, RouteUtil.ROUTEWAY_IP);
+ for (int i = 0; i < customRouteInfos.length; i++) {
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfos[i],
+ RouteUtil.ROUTEWAY_IP);
+ }
+ }
+ }
+
+
+ @Override
+ public void onStatusChange(String serviceName, String version, String host, String protocol,
+ String publish_port, String status) {
+
+ // 获取服务的host
+
+ if (StringUtils.isBlank(host)) {
+ host = serviceName.toLowerCase();
+ }
+
+ if (RouteUtil.PROTOCOL_UI.equals(protocol)) {
+
+ IuiRouteServiceWrapper.getInstance().updateIuiRouteStatus(serviceName, host, publish_port,
+ status, RouteUtil.ROUTEWAY_IP);
+
+ } else if (RouteUtil.PROTOCOL_REST.equals(protocol)) {
+ ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName, version, host,
+ publish_port, status, RouteUtil.ROUTEWAY_IP);
+
+ } else if (RouteUtil.PROTOCOL_HTTP.equals(protocol)) {
+ if (!serviceName.startsWith("/")) {
+ serviceName = "/" + serviceName;
+ }
+ CustomRouteServiceWrapper.getInstance().updateCustomRouteStatus(serviceName, host,
+ publish_port, status, RouteUtil.ROUTEWAY_IP);
+ }
+
+
+ }
+
+ private boolean buildRouteHttpProtocol(MicroServiceFullInfo microServiceInfo, String routeWay) {
+
+ // Portal协议处理
+ if (RouteUtil.CUSTOM_PORTAL.equals(microServiceInfo.getCustom())) {
+ if (RouteUtil.ROUTEWAY_DOMAIN.equals(routeWay)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // 自定义开启SSL处理
+ return microServiceInfo.isEnable_ssl();
+
+ }
+
+ private RouteServer[] buildRouteNodes(MicroServiceFullInfo microServiceInfo, String routeWay) {
+
+ // 针对custom=portal场景的域名路由使用apigateway发布地址作为node
+ if (RouteUtil.CUSTOM_PORTAL.equals(microServiceInfo.getCustom())) {
+ if (RouteUtil.ROUTEWAY_DOMAIN.equals(routeWay)) {
+
+ String discoverServiceName =
+ RouteUtil.getRouteNameByns(microServiceInfo.getServiceName(),
+ microServiceInfo.getNamespace());
+ List<Node> publishNodes =
+ getPublishNodes(discoverServiceName, microServiceInfo.getVersion(),
+ microServiceInfo.getNamespace());
+ if (publishNodes != null && publishNodes.size() > 0) {
+ RouteServer[] routeServers = new RouteServer[publishNodes.size()];
+ int i = 0;
+ for (Node node : publishNodes) {
+ RouteServer routeServer = new RouteServer(node.getIp(), node.getPort());
+ routeServers[i] = routeServer;
+ i++;
+ }
+ return routeServers;
+ }
+ }
+ }
+
+
+ Set<Node> nodes = microServiceInfo.getNodes();
+ RouteServer[] routeServers = new RouteServer[nodes.size()];
+ int n = 0;
+ for (Node node : nodes) {
+ RouteServer routeServer = new RouteServer(node.getIp(), node.getPort());
+ routeServers[n] = routeServer;
+ n++;
+ }
+
+ return routeServers;
+
+ }
+
+ /**
+ * From MicroServiceInfo to ApiRouteInfo
+ *
+ * @param microServiceInfo
+ * @return
+ */
+ private ApiRouteInfo[] buildApiRouteInfo(MicroServiceFullInfo microServiceInfo,
+ String redis_serviceName, String redis_version, String routeWay) {
+
+ ApiRouteInfo apiRouteInfo = new ApiRouteInfo();
+ apiRouteInfo.setUrl(microServiceInfo.getUrl());
+
+ apiRouteInfo.setServers(buildRouteNodes(microServiceInfo, routeWay));
+
+ apiRouteInfo.setVisualRange(RouteUtil.getVisualRangeByRouter(microServiceInfo.getVisualRange()));
+
+
+ if ("ip_hash".equals(microServiceInfo.getLb_policy())) {
+ apiRouteInfo.setUseOwnUpstream("1");
+ }
+
+ apiRouteInfo.setConsulServiceName(microServiceInfo.getServiceName());
+ apiRouteInfo.setServiceName(redis_serviceName);
+ apiRouteInfo.setVersion(redis_version);
+ apiRouteInfo.setApiJson(microServiceInfo.getUrl() + "/swagger.json");
+ apiRouteInfo.setMetricsUrl("/admin/metrics");
+ apiRouteInfo.setEnable_ssl(buildRouteHttpProtocol(microServiceInfo, routeWay));
+ // 默认 HttpProtocol和PublishProtocol=http
+ if (apiRouteInfo.isEnable_ssl()) {
+ apiRouteInfo.setPublishProtocol("https");
+ }
+
+ // 获取服务的host
+ String host = getHost(microServiceInfo);
+
+ apiRouteInfo.setHost(host.toLowerCase());
+ apiRouteInfo.setNamespace(microServiceInfo.getNamespace());
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+
+ if (StringUtils.isNotBlank(microServiceInfo.getPublish_port())) {
+ apiRouteInfo.setPublishProtocol("https");
+ }
+
+ // 获取服务的发布端口(支持多端口格式:https|http)
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ apiRouteInfo.setPublishProtocol("https");
+ apiRouteInfo.setPublish_port(publishPorts[0]);
+
+ try {
+ ApiRouteInfo apiRouteInfo_http = (ApiRouteInfo) apiRouteInfo.clone();
+ apiRouteInfo.setPublishProtocol("http");
+ apiRouteInfo.setPublish_port(publishPorts[1]);
+ return new ApiRouteInfo[] {apiRouteInfo, apiRouteInfo_http};
+ } catch (CloneNotSupportedException e) {
+ LOGGER.error("CLONE is wrong:" + apiRouteInfo);
+ return new ApiRouteInfo[] {apiRouteInfo};
+ }
+
+ }
+ }
+
+
+
+ apiRouteInfo.setPublish_port(microServiceInfo.getPublish_port());
+ return new ApiRouteInfo[] {apiRouteInfo};
+
+
+ }
+
+
+ /**
+ * From MicroServiceInfo to CustomRouteInfo
+ *
+ * @param microServiceInfo
+ * @return
+ */
+ private CustomRouteInfo[] buildCustomRouteInfo(MicroServiceFullInfo microServiceInfo,
+ String redis_serviceName, String routeWay) {
+
+ CustomRouteInfo customRouteInfo = new CustomRouteInfo();
+ customRouteInfo.setUrl(microServiceInfo.getUrl());
+
+
+ customRouteInfo.setServers(buildRouteNodes(microServiceInfo, routeWay));
+
+ customRouteInfo.setVisualRange(RouteUtil.getVisualRangeByRouter(microServiceInfo.getVisualRange()));
+
+ if ("ip_hash".equals(microServiceInfo.getLb_policy())) {
+ customRouteInfo.setUseOwnUpstream("1");
+ }
+
+ customRouteInfo.setConsulServiceName(microServiceInfo.getServiceName());
+ customRouteInfo.setServiceName(redis_serviceName);
+
+ // 获取服务的host
+ String host = getHost(microServiceInfo);
+
+ customRouteInfo.setHost(host.toLowerCase());
+ customRouteInfo.setNamespace(microServiceInfo.getNamespace());
+ customRouteInfo.setEnable_ssl(buildRouteHttpProtocol(microServiceInfo, routeWay));
+
+ if (customRouteInfo.isEnable_ssl()) {
+ customRouteInfo.setPublishProtocol("https");
+ }
+
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+ if (StringUtils.isNotBlank(microServiceInfo.getPublish_port())) {
+ customRouteInfo.setPublishProtocol("https");
+ }
+
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ // 获取服务的发布端口(支持多端口格式:https|http)
+ customRouteInfo.setPublishProtocol("https");
+ customRouteInfo.setPublish_port(publishPorts[0]);
+
+ try {
+ CustomRouteInfo customRouteInfo_http = (CustomRouteInfo) customRouteInfo.clone();
+ customRouteInfo.setPublishProtocol("http");
+ customRouteInfo.setPublish_port(publishPorts[1]);
+ return new CustomRouteInfo[] {customRouteInfo, customRouteInfo_http};
+ } catch (CloneNotSupportedException e) {
+ LOGGER.error("CLONE is wrong:" + customRouteInfo);
+ return new CustomRouteInfo[] {customRouteInfo};
+ }
+
+ }
+ }
+
+
+ customRouteInfo.setPublish_port(microServiceInfo.getPublish_port());
+ return new CustomRouteInfo[] {customRouteInfo};
+ }
+
+
+ /**
+ * From MicroServiceInfo to IuiRouteInfo
+ *
+ * @param microServiceInfo
+ * @return
+ */
+ private IuiRouteInfo[] buildIuiRouteInfo(MicroServiceFullInfo microServiceInfo,
+ String redis_serviceName, String routeWay) {
+
+ IuiRouteInfo iuiRouteInfo = new IuiRouteInfo();
+ iuiRouteInfo.setUrl(microServiceInfo.getUrl());
+
+ iuiRouteInfo.setServers(buildRouteNodes(microServiceInfo, routeWay));
+
+ iuiRouteInfo.setVisualRange(RouteUtil.getVisualRangeByRouter(microServiceInfo.getVisualRange()));
+
+ if ("ip_hash".equals(microServiceInfo.getLb_policy())) {
+ iuiRouteInfo.setUseOwnUpstream("1");
+ }
+
+
+ iuiRouteInfo.setConsulServiceName(microServiceInfo.getServiceName());
+ iuiRouteInfo.setServiceName(redis_serviceName);
+
+ // 获取服务的host
+ String host = getHost(microServiceInfo);
+
+ iuiRouteInfo.setHost(host.toLowerCase());
+ iuiRouteInfo.setNamespace(microServiceInfo.getNamespace());
+ iuiRouteInfo.setEnable_ssl(buildRouteHttpProtocol(microServiceInfo, routeWay));
+ if (iuiRouteInfo.isEnable_ssl()) {
+ iuiRouteInfo.setPublishProtocol("https");
+ }
+
+ if (RouteUtil.ROUTEWAY_IP.equals(routeWay)) {
+
+ if (StringUtils.isNotBlank(microServiceInfo.getPublish_port())) {
+ iuiRouteInfo.setPublishProtocol("https");
+ }
+
+ String[] publishPorts = StringUtils.split(microServiceInfo.getPublish_port(), "|");
+ if (publishPorts.length == 2) {
+ // 获取服务的发布端口(支持多端口格式:https|http)
+ iuiRouteInfo.setPublishProtocol("https");
+ iuiRouteInfo.setPublish_port(publishPorts[0]);
+
+ try {
+ IuiRouteInfo iuiRouteInfo_http = (IuiRouteInfo) iuiRouteInfo.clone();
+ iuiRouteInfo.setPublishProtocol("http");
+ iuiRouteInfo.setPublish_port(publishPorts[1]);
+ return new IuiRouteInfo[] {iuiRouteInfo, iuiRouteInfo_http};
+ } catch (CloneNotSupportedException e) {
+ LOGGER.error("CLONE is wrong:" + iuiRouteInfo);
+ return new IuiRouteInfo[] {iuiRouteInfo};
+ }
+
+ }
+ }
+ iuiRouteInfo.setPublish_port(microServiceInfo.getPublish_port());
+ return new IuiRouteInfo[] {iuiRouteInfo};
+ }
+
+
+
+ private List<Node> getPublishNodes(String discoverServiceName, String version, String namespace) {
+ List<Node> nodes = new ArrayList<Node>();
+
+ if (StringUtils.isBlank(version)) {
+ version = "null";
+ }
+
+ DiscoverInfo discoverInfo = ConfigUtil.getInstance().getDiscoverInfo();
+
+ String allpublishaddressUrl =
+ (new StringBuilder().append("http://").append(discoverInfo.toString())
+ .append(RouteUtil.MSB_ROUTE_URL).append("/").append(discoverServiceName)
+ .append("/version/").append(version).append("/allpublishaddress?namespace=")
+ .append(namespace).append("&visualRange=0")).toString();
+
+ String resultJson = HttpClientUtil.httpGet(allpublishaddressUrl);
+ List<PublishFullAddress> publishFullAddressList =
+ JacksonJsonUtil
+ .jsonToListBean(resultJson, new TypeReference<List<PublishFullAddress>>() {});
+ if (publishFullAddressList != null && publishFullAddressList.size() > 0) {
+ for (PublishFullAddress publishFullAddress : publishFullAddressList) {
+ if (StringUtils.isNotBlank(publishFullAddress.getIp())
+ && "https".equals(publishFullAddress.getPublish_protocol())) {
+ nodes.add(new Node(publishFullAddress.getIp(), publishFullAddress.getPort()));
+ }
+
+ }
+ }
+
+ return nodes;
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/RouteNotify.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/RouteNotify.java
new file mode 100644
index 0000000..3cd2d8a
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/RouteNotify.java
@@ -0,0 +1,77 @@
+package org.onap.msb.apiroute.wrapper.serviceListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.wrapper.util.ServiceFilter;
+
+public class RouteNotify {
+
+ private static RouteNotify instance = new RouteNotify();
+
+ private List<IMicroServiceChangeListener> serviceListenerlist =
+ new ArrayList<IMicroServiceChangeListener>();
+
+ private RouteNotify() {}
+
+ public static RouteNotify getInstance() {
+ return instance;
+ }
+
+
+ public void addServiceChangeListener(IMicroServiceChangeListener listener) {
+ synchronized (serviceListenerlist) {
+ serviceListenerlist.add(listener);
+ }
+ }
+
+
+ /* public void removeServiceChangeListener(IMicroServiceChangeListener listener) {
+ synchronized (serviceListenerlist) {
+ serviceListenerlist.remove(listener);
+ }
+ }*/
+
+
+ public void noticeRouteListener4Update(String serviceName, String version, MicroServiceFullInfo microServiceInfo) throws Exception {
+ if (ServiceFilter.getInstance().isNeedNotifyByProtocol(microServiceInfo.getProtocol())) {
+ for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
+ serviceListener.onChange(serviceName, version, microServiceInfo);
+ }
+ }
+
+ }
+
+ public void noticeUpdateStatusListener(MicroServiceFullInfo microServiceInfo, String status) {
+
+ for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
+ serviceListener.onStatusChange(microServiceInfo.getServiceName(),
+ microServiceInfo.getVersion(), microServiceInfo.getHost(),microServiceInfo.getProtocol(), microServiceInfo.getPublish_port(),status);
+ }
+ }
+
+
+
+
+ public void noticeRouteListener4Add(MicroServiceFullInfo microServiceInfo) throws Exception {
+ if (ServiceFilter.getInstance().isNeedNotifyByProtocol(microServiceInfo.getProtocol())) {
+ for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
+ serviceListener.onSave(microServiceInfo);
+ }
+ }
+ }
+
+ public void noticeRouteListener4Delete(MicroServiceFullInfo microServiceInfo) throws Exception {
+ if (ServiceFilter.getInstance().isNeedNotifyByProtocol(microServiceInfo.getProtocol())) {
+ for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
+ serviceListener.onDelete(microServiceInfo);
+ }
+ }
+ }
+
+
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/CommonUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/CommonUtil.java
new file mode 100644
index 0000000..2ad84a7
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/CommonUtil.java
@@ -0,0 +1,76 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class CommonUtil {
+
+ public static final int SC_OK = 200;
+
+ 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 strArray, String str) {
+ String[] array = StringUtils.split(strArray, ",");
+ return contain(array, str);
+ }
+
+ public static boolean contain(String[] array, String str) {
+ for (int i = 0; i < array.length; i++) {
+ if (array[i].trim().equals(str)) {
+ return true;
+ }
+ }
+ return false;
+
+ }
+
+ public static boolean contain(String[] array, String value[]) {
+ for (int i = 0; i < array.length; i++) {
+ for (int n = 0; n < value.length; n++) {
+ if (array[i].equals(value[n])) {
+ return true;
+ }
+ }
+ }
+ return false;
+
+ }
+
+ /**
+ * @param <T>
+ * @Title getDiffrent
+ * @Description TODO(Extract the list1 and list2 different data sets)
+ * @param list1
+ * @param list2
+ * @return TODO(a new List in list2 but not in list1)
+ * @return List<String>
+ */
+ public static <T> Set<T> getDiffrent(Set<T> list1, Set<T> list2) {
+
+ HashSet<T> set_all = new HashSet<T>();
+
+ for (T t1 : list1) {
+ set_all.add(t1);
+ }
+
+
+ Set<T> diff = new HashSet<T>();
+
+ for (T t2 : list2) {
+ if (set_all.add(t2)) { // in list2 but not in list1
+ diff.add(t2);
+ }
+ }
+
+
+ return diff;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ConfigUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ConfigUtil.java
new file mode 100644
index 0000000..80f99f4
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ConfigUtil.java
@@ -0,0 +1,446 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.ApiRouteAppConfig;
+import org.onap.msb.apiroute.api.DiscoverInfo;
+import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@SuppressWarnings("unchecked")
+public class ConfigUtil {
+ private final static ConfigUtil instance = new ConfigUtil();
+
+
+ private ConfigUtil() {}
+
+ public static ConfigUtil getInstance() {
+ return instance;
+ }
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class);
+
+ private String serverPort="80";
+
+ private String IUI_ROOT_PATH="iui";
+
+ private String API_ROOT_PATH="api";
+
+ private String namespaceMatches="all";
+
+ private String visualRangeMatches="0";
+
+ private String nodeMetaQueryParam="";
+
+ private String network_plane_typeMatches="";
+
+ private String[] routeWay={"ip"};
+
+ private Map<String,String> labelMapMatches;
+
+ private DiscoverInfo discoverInfo=new DiscoverInfo();
+
+ private String consul_ip="";
+
+ private String metricsUrl = "http://127.0.0.1:8066/admin/metrics";
+
+ public void initRootPath() {
+ String apiRootPathConfSource="Default";
+ String iuiRootPathConfSource="Default";
+
+ try {
+
+ URL urlRootPath =
+ ConfigUtil.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json");
+ if (urlRootPath != null) {
+ String path = urlRootPath.getPath();
+
+ LOGGER.warn("read initUrlRootPath:" + path);
+
+ String fileContent = FileUtil.readFile(path);
+ ObjectMapper mapper = new ObjectMapper();
+
+ Map<String, String> map = mapper.readValue(fileContent, HashMap.class);
+ if (map.get("iuiRootPath") != null) {
+ IUI_ROOT_PATH = map.get("iuiRootPath");
+ iuiRootPathConfSource="initUrlRootPath.json";
+ }
+ if (map.get("apiRootPath") != null) {
+ API_ROOT_PATH = map.get("apiRootPath");
+ apiRootPathConfSource="initUrlRootPath.json";
+ }
+
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ LOGGER.error("init UrlRootPath throw exception", e);
+ }
+
+ LOGGER.warn("init IUI_ROOT_PATH from ["+iuiRootPathConfSource+"]:"+IUI_ROOT_PATH);
+ LOGGER.warn("init API_ROOT_PATH from ["+apiRootPathConfSource+"]:"+API_ROOT_PATH);
+
+ }
+
+ public void initApiGatewayPort() {
+
+ String env_APIGATEWAY_EXPOSE_PORT=System.getenv("APIGATEWAY_EXPOSE_PORT");
+ String httpExposePortConfSource="Default";
+ try {
+ // read initApiGatewayConfig
+ if (StringUtils.isBlank(env_APIGATEWAY_EXPOSE_PORT)) {
+ URL apiGatewayConfigPath =
+ ConfigUtil.class
+ .getResource("/ext/initApiGatewayConfig/initApiGatewayConfig.json");
+ if (apiGatewayConfigPath != null) {
+ String path = apiGatewayConfigPath.getPath();
+
+ LOGGER.warn("read initApiGatewayConfig:" + path);
+
+ String fileContent = FileUtil.readFile(path);
+ ObjectMapper mapper = new ObjectMapper();
+
+ Map<String, Object> labelMap = mapper.readValue(fileContent, Map.class);
+ if (labelMap.get("port") != null) {
+ serverPort = (String) labelMap.get("port");
+ httpExposePortConfSource="initApiGatewayConfig.json";
+ }
+ }
+ } else {
+ serverPort = env_APIGATEWAY_EXPOSE_PORT;
+ httpExposePortConfSource="env:APIGATEWAY_EXPOSE_PORT";
+ }
+ LOGGER.warn("init APIGATEWAY http publish Port from ["+httpExposePortConfSource+"]:"+serverPort);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.error(
+ "read initApiGatewayConfig Files or env(APIGATEWAY_EXPOSE_PORT) throw exception", e);
+ }
+
+
+ }
+
+ public void initConsulIp() {
+ String sys_consulIp=System.getenv("CONSUL_IP");
+ if (StringUtils.isNotBlank(sys_consulIp)) {
+ consul_ip=sys_consulIp;
+ LOGGER.warn("init consul_Ip from [env:CONSUL_IP]:" + sys_consulIp);
+ }
+ else{
+ LOGGER.warn("init consul_Ip from [env:CONSUL_IP] is blank");
+ }
+
+
+ }
+
+ public void initRouteNameSpaceMatches() {
+ String env_NAMESPACE=System.getenv("NAMESPACE");
+ String namespaceConfSource="Default";
+ try {
+ // read NAMESPACE
+ if (StringUtils.isBlank(env_NAMESPACE)) {
+ URL routeLabelsPath =
+ InitRouteServiceWrapper.class
+ .getResource("/ext/initRouteLabels/initRouteLabelsMatches.json");
+ if (routeLabelsPath != null) {
+ String path = routeLabelsPath.getPath();
+
+ String fileContent = FileUtil.readFile(path);
+ ObjectMapper mapper = new ObjectMapper();
+
+ Map<String, Object> labelMap = mapper.readValue(fileContent, Map.class);
+ if (labelMap.get("namespace") != null) {
+ namespaceMatches = (String) labelMap.get("namespace");
+ namespaceConfSource="initRouteLabelsMatches.json";
+ }
+ }
+ } else {
+ namespaceMatches =env_NAMESPACE;
+ namespaceConfSource="env:NAMESPACE";
+ }
+ LOGGER.warn("init namespace Filter from ["+namespaceConfSource+"]:" + namespaceMatches);
+ }
+ catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.error("read initRouteNameSpaceMatches Files or env(NAMESPACE) throw exception",
+ e);
+ }
+
+
+
+ }
+ /**
+ * @Title: initRouteLabelsMatches
+ * @Description: TODO(According to the environment variable or a JSON file configuration
+ * initialization Route filter conditions)
+ * @return: void
+ */
+ public void initRouteLabelsMatches() {
+ String env_ROUTE_LABELS=System.getenv("ROUTE_LABELS");
+ String visualRangeConfSource="Default";
+ String networkPlaneConfSource="Default";
+ String labelConfSource="Default";
+ try {
+
+ // read ROUTE_LABELS
+ if (StringUtils.isBlank(env_ROUTE_LABELS)) {
+ URL routeLabelsPath =
+ InitRouteServiceWrapper.class
+ .getResource("/ext/initRouteLabels/initRouteLabelsMatches.json");
+ if (routeLabelsPath != null) {
+ String path = routeLabelsPath.getPath();
+
+ String fileContent = FileUtil.readFile(path);
+ ObjectMapper mapper = new ObjectMapper();
+
+ Map<?, ?> labelMap = mapper.readValue(fileContent, Map.class);
+ if (labelMap.get("predefineLabels") != null) {
+ Map<String, String> predefineLabelMapMatches =
+ (Map<String, String>) labelMap.get("predefineLabels");
+ if (predefineLabelMapMatches.get("visualRange") != null) {
+ visualRangeMatches = predefineLabelMapMatches.get("visualRange");
+ visualRangeConfSource="initRouteLabelsMatches.json";
+ }
+ if (predefineLabelMapMatches.get("network_plane_type") != null) {
+ network_plane_typeMatches =
+ predefineLabelMapMatches.get("network_plane_type");
+ networkPlaneConfSource="initRouteLabelsMatches.json";
+ }
+ }
+
+ if (labelMap.get("customLabels") != null) {
+ labelMapMatches = (Map<String, String>) labelMap.get("customLabels");
+ labelConfSource="initRouteLabelsMatches.json";
+ }
+
+ }
+ } else {
+ String[] env_routeLabels = StringUtils.split(env_ROUTE_LABELS, ",");
+ Map<String, String> labelMap = new HashMap<String, String>();
+
+ for (int i = 0; i < env_routeLabels.length; i++) {
+ String[] labels = StringUtils.split(env_routeLabels[i], ":");
+
+ if ("visualRange".equals(labels[0])) {
+ visualRangeMatches = labels[1];
+ visualRangeConfSource="env:ROUTE_LABELS";
+ } else if ("network_plane_type".equals(labels[0])) {
+ network_plane_typeMatches = labels[1];
+ networkPlaneConfSource="env:ROUTE_LABELS";
+ } else {
+ labelMap.put(labels[0], labels[1]);
+ }
+
+ }
+
+ labelConfSource="env:ROUTE_LABELS";
+ labelMapMatches = labelMap;
+
+ }
+ LOGGER.warn("init visualRange Filter from [ "+visualRangeConfSource+" ]:" + visualRangeMatches);
+ LOGGER.warn("init network_plane_type Filter from [ "+networkPlaneConfSource+" ]:" + network_plane_typeMatches);
+ LOGGER.warn("init customLabels Filter from [ "+labelConfSource+" ]:" + labelMapMatches);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ LOGGER.error(
+ "read initRouteLabelsPathMatches Files or env(ROUTE_LABELS) throw exception",
+ e);
+ }
+ }
+
+ public void initRouteWay() {
+ String env_ROUTE_WAY=System.getenv("ROUTE_WAY");
+ try {
+ // read NAMESPACE
+ if (StringUtils.isBlank(env_ROUTE_WAY)) {
+ URL routeLabelsPath =
+ InitRouteServiceWrapper.class.getResource("/ext/initRouteWay/initRouteWay.json");
+ if (routeLabelsPath != null) {
+ String path = routeLabelsPath.getPath();
+
+ String fileContent = FileUtil.readFile(path);
+ ObjectMapper mapper = new ObjectMapper();
+
+ Map<String, Object> routeWayMap = mapper.readValue(fileContent, Map.class);
+ String routeWayFromConfig=(String)routeWayMap.get("routeWay");
+ if (StringUtils.isNotBlank(routeWayFromConfig)) {
+ routeWay =
+ StringUtils.split(routeWayFromConfig, RouteUtil.SPLIT_LINE);
+ LOGGER.warn("init RouteWay from [initRouteWay.json]:" + routeWayFromConfig);
+ }
+ }
+ } else {
+ routeWay = StringUtils.split(env_ROUTE_WAY, RouteUtil.SPLIT_LINE);
+ LOGGER.warn("read initRouteWay from [env:ROUTE_WAY]:" + env_ROUTE_WAY);
+ }
+
+
+
+
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ LOGGER.error("read initRouteWay Files or env(ROUTE_WAY) throw exception", e);
+ }
+ }
+
+
+ public void initDiscoverInfo(ApiRouteAppConfig configuration){
+ DiscoverInfo config_discoverInfo = configuration.getDiscoverInfo();
+
+
+ discoverInfo.setEnabled(config_discoverInfo.isEnabled());
+
+ String discoverInfoConfSource="yaml config";
+
+ if (config_discoverInfo.isEnabled()) {
+
+ String discoverIP;
+ String env_SDCLIENT_IP=System.getenv("SDCLIENT_IP");
+
+ if (StringUtils.isBlank(env_SDCLIENT_IP)) {
+ // yml
+ discoverIP = config_discoverInfo.getIp();
+ } else {
+ discoverIP = env_SDCLIENT_IP;
+ discoverInfoConfSource="env:SDCLIENT_IP";
+ }
+
+ discoverInfo.setIp(discoverIP.trim());
+ discoverInfo.setPort(config_discoverInfo.getPort());
+ }
+
+ LOGGER.warn("init DiscoverInfo from ["+discoverInfoConfSource+"]--" + discoverInfo.toString()+" Enabled:"+discoverInfo.isEnabled());
+ }
+
+ public void initNodeMetaQueryParam() {
+ // judge consul register node:caltalog
+ String env_CONSUL_REGISTER_MODE = System.getenv("CONSUL_REGISTER_MODE");
+
+ if (env_CONSUL_REGISTER_MODE == null
+ || !env_CONSUL_REGISTER_MODE.trim().equals("catalog")) {
+ nodeMetaQueryParam = "";
+ return;
+ }
+
+ // visual range
+ String nodemeta_visualrange = nodemeta_visualrange(visualRangeMatches);
+
+ LOGGER.warn("calc nodemeta_visualrange from [" + visualRangeMatches
+ + "]:" + nodemeta_visualrange);
+
+ nodeMetaQueryParam = nodemeta_visualrange;
+
+ // name space
+ String nodemeta_namespace = nodemeta_namespace(namespaceMatches);
+ LOGGER.warn("calc nodemeta_namespace from [" + namespaceMatches + "]:"
+ + nodemeta_namespace);
+
+ if (!nodeMetaQueryParam.isEmpty() && !nodemeta_namespace.isEmpty()) {
+ nodeMetaQueryParam += "&";
+ }
+ nodeMetaQueryParam += nodemeta_namespace;
+
+ /*
+ * // nodemeta = (!nodemeta_visualrange.isEmpty() && !nodemeta_namespace
+ * .isEmpty()) ? nodemeta_visualrange + "&" + nodemeta_namespace :
+ * nodemeta_visualrange + nodemeta_namespace;
+ */
+
+ }
+
+ private String nodemeta_visualrange(final String visualRangeMatches) {
+
+ if (visualRangeMatches == null || visualRangeMatches.isEmpty()) {
+ return "";
+ }
+
+ // external:0
+ if (visualRangeMatches.trim().equals("0")) {
+ return "node-meta=external:true";
+ }
+
+ // internal:1
+ if (visualRangeMatches.trim().equals("1")) {
+ return "node-meta=internal:true";
+ }
+
+ return "";
+ }
+
+
+ private String nodemeta_namespace(final String namespaceMatches) {
+
+ // exclude null,"",all,&,|,!
+ if (namespaceMatches == null || namespaceMatches.isEmpty()
+ || namespaceMatches.contains("all")
+ || namespaceMatches.contains("&")
+ || namespaceMatches.contains("|")
+ || namespaceMatches.contains("!")) {
+ return "";
+ }
+
+ return "node-meta=ns:" + namespaceMatches;
+ }
+
+ public String getServerPort() {
+ return serverPort;
+ }
+
+ public String getIUI_ROOT_PATH() {
+ return IUI_ROOT_PATH;
+ }
+
+ public String getAPI_ROOT_PATH() {
+ return API_ROOT_PATH;
+ }
+
+ public String getNamespaceMatches() {
+ return namespaceMatches;
+ }
+
+ public String getVisualRangeMatches() {
+ return visualRangeMatches;
+ }
+
+ public String getNetwork_plane_typeMatches() {
+ return network_plane_typeMatches;
+ }
+
+ public String[] getRouteWay() {
+ return routeWay.clone();
+ }
+
+ public Map<String, String> getLabelMapMatches() {
+ return labelMapMatches;
+ }
+
+ public DiscoverInfo getDiscoverInfo() {
+ return discoverInfo;
+ }
+
+ public String getMetricsUrl() {
+ return metricsUrl;
+ }
+
+ public void setMetricsUrl(String metricsUrl) {
+ this.metricsUrl = metricsUrl;
+ }
+
+ public String getNodeMetaQueryParam() {
+ return nodeMetaQueryParam;
+ }
+
+ public String getConsul_ip() {
+ return consul_ip;
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java
new file mode 100644
index 0000000..1e89f82
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.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;
+ StringBuffer fileContent = new StringBuffer();
+ 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.append(tempString);
+ }
+ reader.close();
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ throw e;
+ }
+ }
+ }
+ return fileContent.toString();
+ }
+
+ /**
+ * Read all the files under a folder
+ */
+ public static String[] readfile(String filepath) throws FileNotFoundException, IOException {
+ File file = new File(filepath);
+ if (file.isDirectory()) {
+ String[] filelist = file.list();
+ return filelist;
+ }
+ return null;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtil.java
new file mode 100644
index 0000000..eb5ed1e
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtil.java
@@ -0,0 +1,117 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+import java.io.IOException;
+
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.config.RequestConfig;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HttpClientUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
+
+ private static int connectionTimeOut = 2*1000;
+
+
+ public static String httpGet(String url){
+ String result = null;
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.addHeader("Content-type", "application/json; charset=utf-8");
+ httpGet.setHeader("Accept", "application/json");
+ try {
+ CloseableHttpResponse res = httpClient.execute(httpGet);
+ result = EntityUtils.toString(res.getEntity());
+ if (res.getStatusLine().getStatusCode() != CommonUtil.SC_OK) {
+ logger.error(result);
+ }
+ res.close();
+ } catch (ClientProtocolException e) {
+ logger.error(url + ":httpGetWithJSON connect faild");
+ } catch (IOException e) {
+ logger.error( url + ":httpGetWithJSON connect faild");
+ } finally {
+ try {
+ httpClient.close();
+ } catch (IOException e) {
+ logger.error(url + ":close httpClient faild");
+ }
+ }
+
+ return result;
+
+ }
+
+ public static HttpGetResult httpGetStatusAndBody(String url){
+ HttpGetResult result= new HttpGetResult();
+ String body = null;
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.addHeader("Content-type", "application/json; charset=utf-8");
+ httpGet.setHeader("Accept", "application/json");
+
+ RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectionTimeOut).build();
+ httpGet.setConfig(requestConfig);
+
+ try {
+ CloseableHttpResponse res = httpClient.execute(httpGet);
+ body = EntityUtils.toString(res.getEntity());
+ if (res.getStatusLine().getStatusCode() != CommonUtil.SC_OK) {
+ logger.error(body);
+ }
+ result.setBody(body);
+ result.setStatusCode(res.getStatusLine().getStatusCode());
+ res.close();
+ } catch (ClientProtocolException e) {
+ logger.error(url + ":httpGetWithJSON connect faild",e);
+ } catch (IOException e) {
+ logger.error( url + ":httpGetWithJSON connect faild",e);
+ } finally {
+ try {
+ httpClient.close();
+ } catch (IOException e) {
+ logger.error(url + ":close httpClient faild");
+ }
+ }
+
+ return result;
+
+ }
+
+ public static int httpGetStatus(String url) throws Exception{
+ int iStatus=500;
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+
+ HttpGet httpGet = new HttpGet(url);
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();//设置请求和传输超时时间
+ httpGet.setConfig(requestConfig);
+ httpGet.addHeader("Content-type", "application/json; charset=utf-8");
+ httpGet.setHeader("Accept", "application/json");
+ try {
+ CloseableHttpResponse res = httpClient.execute(httpGet);
+
+ iStatus=res.getStatusLine().getStatusCode();
+ res.close();
+ } catch (ClientProtocolException e) {
+ logger.error(url + " httpGet connect faild:"+e.getMessage());
+ } catch (IOException e) {
+ logger.error(url + " httpGet connect faild:"+e.getMessage());
+ } finally {
+ try {
+ httpClient.close();
+ } catch (IOException e) {
+ logger.error(url + " httpGet close faild:"+e.getMessage());
+ }
+ }
+
+ return iStatus;
+
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpGetResult.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpGetResult.java
new file mode 100644
index 0000000..5b943e3
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpGetResult.java
@@ -0,0 +1,19 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+public class HttpGetResult {
+ private int statusCode;
+ private String body;
+ public int getStatusCode() {
+ return statusCode;
+ }
+ public void setStatusCode(int statusCode) {
+ this.statusCode = statusCode;
+ }
+ public String getBody() {
+ return body;
+ }
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/Jackson.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/Jackson.java
new file mode 100644
index 0000000..20b60d4
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/Jackson.java
@@ -0,0 +1,28 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+import com.fasterxml.jackson.datatype.jdk7.Jdk7Module;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
+
+public class Jackson {
+ //use static singleton, make sure to reuse!
+ public static final ObjectMapper MAPPER = newObjectMapper();
+
+ private Jackson() {
+ /* singleton */
+ }
+
+ private static ObjectMapper newObjectMapper() {
+ final ObjectMapper mapper = new ObjectMapper();
+ return configure(mapper);
+ }
+
+ private static ObjectMapper configure(ObjectMapper mapper) {
+ mapper.registerModule(new GuavaModule());
+ mapper.registerModule(new JodaModule());
+ mapper.registerModule(new Jdk7Module());
+
+ return mapper;
+ }
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtil.java
new file mode 100644
index 0000000..4a7f50e
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtil.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.util;
+
+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 volatile static ObjectMapper mapper = null;
+
+ private static ObjectMapper getMapperInstance() {
+ if (mapper == null) {
+ synchronized (JacksonJsonUtil.class) {
+ 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;
+
+ ObjectMapper objectMapper = getMapperInstance();
+ objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ json = objectMapper.writeValueAsString(obj);
+
+ 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 <T> T jsonToListBean(String json, TypeReference<T> valueTypeRef) {
+ try {
+
+ ObjectMapper objectMapper = getMapperInstance();
+
+
+ return objectMapper.readValue(json, valueTypeRef);
+
+ } catch (Exception e) {
+ String errorMsg = " JsonTobean faild:" + e.getMessage();
+ logger.error(errorMsg);
+ }
+ return null;
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JedisUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JedisUtil.java
new file mode 100644
index 0000000..ac9421b
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JedisUtil.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+
+
+public 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 volatile static JedisPool jedisPool = null;
+
+
+ public static String propertiesName = "redis.properties";
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+
+ private JedisUtil() {
+ // private constructor
+
+ }
+
+ private synchronized static JedisPool initialPool() throws IOException {
+
+ JedisPoolConfig config = new JedisPoolConfig();
+ config.setMaxTotal(50);
+ config.setMaxIdle(30);
+ config.setMaxWaitMillis(5000);
+ config.setTestOnBorrow(false);
+ config.setTestOnReturn(true);
+
+ URL urlPath = JedisUtil.class.getResource("/ext/redisConf/redis.properties");
+ if (urlPath != null) {
+ String propertiesPath = urlPath.getPath();
+
+
+ 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!");
+ }
+
+
+ // Set up the connection pool basic information
+ String strHost = bundle.getString("redis.host");
+ if (StringUtils.isNotEmpty(strHost)) {
+ host = strHost;
+ }
+
+ // redis port: first read from env
+ if (StringUtils.isNotBlank(System.getenv("APIGATEWAY_REDIS_PORT"))) {
+ port = Integer.parseInt(System.getenv("APIGATEWAY_REDIS_PORT"));
+ } else {
+ String strPort = bundle.getString("redis.port");
+ if (StringUtils.isNotEmpty(strPort)) {
+ port = Integer.parseInt(strPort);
+ }
+ }
+
+
+ String strTimeout = bundle.getString("redis.connectionTimeout");
+ if (StringUtils.isNotEmpty(strTimeout)) {
+ connectionTimeout = Integer.parseInt(strTimeout);
+ }
+
+
+ String strDbIndex = bundle.getString("redis.db_index");
+ if (StringUtils.isNotEmpty(strDbIndex)) {
+ DEFAULT_DB_INDEX = Integer.parseInt(strDbIndex);
+ }
+
+ String strMaxTotal = bundle.getString("redis.pool.maxTotal");
+ if (StringUtils.isNotEmpty(strMaxTotal)) {
+ config.setMaxTotal(Integer.parseInt(strMaxTotal));
+ }
+
+ String strMaxIdle = bundle.getString("redis.pool.maxIdle");
+ if (StringUtils.isNotEmpty(strMaxIdle)) {
+ config.setMaxIdle(Integer.parseInt(strMaxIdle));
+ }
+
+ String strMaxWaitMillis = bundle.getString("redis.pool.maxWaitMillis");
+ if (StringUtils.isNotEmpty(strMaxWaitMillis)) {
+ config.setMaxWaitMillis(Long.parseLong(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));
+ }
+
+ }
+ }
+
+ StringBuffer redisinfo = new StringBuffer();
+ redisinfo.append("------redis.properties------").append(LINE_SEPARATOR);
+ redisinfo.append("redis.host: ").append(host).append(":").append(port).append(LINE_SEPARATOR);
+ redisinfo.append("redis.connectionTimeout: ").append(connectionTimeout).append(LINE_SEPARATOR);
+ redisinfo.append("redis.pool.maxTotal: ").append(config.getMaxTotal()).append(LINE_SEPARATOR);
+ redisinfo.append("redis.pool.maxIdle: ").append(config.getMaxIdle()).append(LINE_SEPARATOR);
+ redisinfo.append("redis.pool.maxWaitMillis: ").append(config.getMaxWaitMillis())
+ .append(LINE_SEPARATOR);
+ redisinfo.append("redis.pool.testOnBorrow: ").append(config.getTestOnBorrow())
+ .append(LINE_SEPARATOR);
+ redisinfo.append("redis.pool.testOnReturn: ").append(config.getTestOnReturn())
+ .append(LINE_SEPARATOR);
+
+
+ LOGGER.info(redisinfo.toString());
+ return new JedisPool(config, host, port, connectionTimeout);
+
+ }
+
+ /**
+ * From the connection pool to obtain jedis instance, use the default database index number 0
+ *
+ * @return
+ * @throws Exception
+ */
+ public static Jedis borrowJedisInstance() throws Exception {
+ return borrowJedisInstance(DEFAULT_DB_INDEX);
+ }
+
+ /**
+ * From the connection pool to obtain jedis instance, using the specified database index number
+ *
+ * @return
+ * @throws Exception
+ */
+
+ public static Jedis borrowJedisInstance(final int dbIndex) throws Exception {
+ if (jedisPool == null) {
+ synchronized (JedisUtil.class) {
+ if (jedisPool == null) {
+ jedisPool = initialPool();
+ }
+ }
+ }
+ Jedis resource = jedisPool.getResource();
+
+ if (resource == null) {
+ throw new Exception("fetch from jedis pool failed,null object!");
+ }
+
+ resource.select(dbIndex);
+ return resource;
+
+ }
+
+ /**
+ * returned to the pool jedis instance
+ *
+ * @param jedis
+ */
+ public static void returnJedisInstance(final Jedis jedis) {
+ if (jedis != null) {
+ jedis.close();
+ }
+ }
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java
new file mode 100644
index 0000000..1081579
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.regex.Pattern;
+
+
+public class MicroServiceUtil {
+ public static final String PREFIX_PATH = "discover:microservices";
+
+ private static final Pattern SERVICE_KEY_REGEX_PATTERN =
+ Pattern.compile("discover:microservices:(?<servicename>[^:]+)(:(?<version>[^:]*))");
+
+
+ public static String getPrefixedKey(String... paths) {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(PREFIX_PATH);
+
+ for (int i = 0; i < paths.length; i++) {
+ sb.append(":");
+ sb.append(paths[i]);
+ }
+ return sb.toString();
+ }
+
+
+ public static String getServiceKey(String serviceName, String version) {
+ return getPrefixedKey(serviceName, version);
+ }
+
+ public static Pattern getServiceKeyRegexPattern(){
+ return SERVICE_KEY_REGEX_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/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java
new file mode 100644
index 0000000..0edcfda
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RegExpTestUtil {
+
+
+ private final static String API_KEY_PATTERN ="/api/(?<servicename>[^/]+)(/(?<version>[^/]*)).*";
+
+ private final static String IUI_KEY_PATTERN ="/iui/(?<servicename>[^/]+)/.*";
+
+ 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 = "^\\/"+ConfigUtil.getInstance().getAPI_ROOT_PATH()+"\\/.*$";
+ return Pattern.matches(urlReg, url);
+
+}
+
+public static boolean iuiRouteUrlRegExpTest(String url){
+
+ String urlReg = "^\\/"+ConfigUtil.getInstance().getIUI_ROOT_PATH()+"\\/.*$";
+ return Pattern.matches(urlReg, url);
+
+}
+
+public static String[] apiServiceNameMatch4URL(String url){
+ Pattern redisKeyPattern =Pattern.compile(API_KEY_PATTERN);
+ Matcher matcher = redisKeyPattern.matcher(url+"/");
+ if (matcher.matches()) {
+ String version;
+ if(versionRegExpTest(matcher.group("version"))){
+ version=matcher.group("version");
+ }
+ else{
+ version="";
+ }
+ return new String[]{matcher.group("servicename"),version};
+ }
+ else{
+ return null;
+ }
+}
+
+
+public static String iuiServiceNameMatch4URL(String url){
+ Pattern redisKeyPattern =Pattern.compile(IUI_KEY_PATTERN);
+ Matcher matcher = redisKeyPattern.matcher(url+"/");
+ if (matcher.matches()) {
+ return matcher.group("servicename");
+ }
+ else{
+ return null;
+ }
+}
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RouteUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RouteUtil.java
new file mode 100644
index 0000000..331671f
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RouteUtil.java
@@ -0,0 +1,345 @@
+/**
+ * Copyright 2016 ZTE, Inc. and others.
+ *
+ * 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.onap.msb.apiroute.wrapper.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.Node;
+import org.onap.msb.apiroute.api.RouteInfo;
+import org.onap.msb.apiroute.api.RouteServer;
+import org.onap.msb.apiroute.api.exception.UnprocessableEntityException;
+
+
+public class RouteUtil {
+
+
+ public static final int consulDeafultPort=8500;
+
+ public static final String ROUTE_PATH="msb:routing";
+
+ public static final String ROUTE_PORT_PATH="msb:";
+
+ public static final String ROUTE_PATH_HOST="msb:host";
+
+ public static final String APIROUTE="api";
+
+ public static final String IUIROUTE="iui";
+
+ public static final String CUSTOMROUTE="custom";
+
+ public static final String HTTPS_PROTOCOL="https";
+
+ public static final String CUSTOM_PORTAL="portal";
+
+
+ public static final String PROTOCOL_LIST="REST,HTTP,UI,MQ,FTP,SNMP,TCP,UDP";
+
+ public static final String MSB_ROUTE_URL = "/api/microservices/v1/services";
+
+ public static final String MSB_CHECK_URL = "/api/catalog/v1/service/router-all";
+
+ public static final String visualRangeRange="0,1";
+
+ public static final String controlRangeMatches="0,1,2";
+
+ public static final String statusRangeMatches="0,1";
+
+ public static final String useOwnUpstreamRangeMatches="0,1";
+
+ public static final String ROUTEWAY_IP="ip";
+
+ public static final String ROUTEWAY_DOMAIN="domain";
+
+ public static final String SPLIT_LINE="|";
+
+ public static final String PROTOCOL_REST="REST";
+
+ public static final String PROTOCOL_UI="UI";
+
+ public static final String PROTOCOL_HTTP="HTTP";
+
+ public static final String FILTER_PROTOCOLS="REST,UI,HTTP";
+
+ public static final int SERVICE_DATA_QUEUE_NUM=5;
+
+ public static final int SERVICE_QUEUE_CAPACITY=100;
+
+ public static final int SERVICE_LIST_QUEUE_CAPACITY=5;
+
+ public static final int WATCH_SECOND=120;
+
+ public static final String HEALTH_CHECK_PASSING="passing";
+
+
+
+
+ /**
+ * @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(ConfigUtil.getInstance().getServerPort())){
+ sb.append(ROUTE_PATH);
+ }
+ else{
+ sb.append(ROUTE_PORT_PATH).append(paths[0]);
+ }
+
+ for (int i = 1; i < paths.length; i++) {
+ sb.append(":");
+ sb.append(paths[i]);
+ }
+ return sb.toString();
+ }
+
+ public static String getPrefixedKey4Host(String...paths){
+ StringBuffer sb= new StringBuffer();
+
+ sb.append(ROUTE_PATH_HOST);
+
+
+ for (int i = 0; i < paths.length; i++) {
+ sb.append(":");
+ sb.append(paths[i]);
+ }
+ return sb.toString();
+ }
+
+
+
+
+ public static void checkRouteWay(String routeWay){
+ if(!CommonUtil.contain(ConfigUtil.getInstance().getRouteWay(),routeWay)){
+ String errInfo = "routeWay does not support,must be ip or domain";
+ throw new UnprocessableEntityException(errInfo);
+ }
+ }
+
+ public static void checkServiceNameAndVersion(String serviceName,String version){
+ if (StringUtils.isBlank(serviceName)) {
+ throw new UnprocessableEntityException("serviceName can't be empty");
+ }
+
+ if (StringUtils.isNotBlank(version)) {
+ if (!RegExpTestUtil.versionRegExpTest(version)) {
+ throw new UnprocessableEntityException("version is not a valid format");
+ }
+ }
+ }
+
+ public static void checkServiceStatus(String status){
+ if (!CommonUtil.contain(statusRangeMatches, status)) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo Status FAIL:status is wrong,value range:("
+ + RouteUtil.statusRangeMatches + ")");
+ }
+ }
+
+
+
+ public static void checkRouterInfoFormat(RouteInfo routeInfo) {
+
+ if (StringUtils.isBlank(routeInfo.getServiceName()) || routeInfo.getServers().length == 0) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL: Some required fields are empty");
+ }
+
+ if (StringUtils.isNotBlank(routeInfo.getUrl())) {
+ if (!RegExpTestUtil.urlRegExpTest(routeInfo.getUrl())) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL:url is not a valid format(url must be begin with /)");
+
+ }
+ }
+
+ if (!CommonUtil.contain(RouteUtil.visualRangeRange, routeInfo.getVisualRange())) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL:VisualRange is wrong,value range:("
+ + RouteUtil.visualRangeRange + ")");
+ }
+
+ if (!CommonUtil.contain(RouteUtil.controlRangeMatches, routeInfo.getControl())) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL:control is wrong,value range:("
+ + RouteUtil.controlRangeMatches + ")");
+ }
+
+ if (!CommonUtil.contain(RouteUtil.statusRangeMatches, routeInfo.getStatus())) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL:status is wrong,value range:("
+ + RouteUtil.statusRangeMatches + ")");
+ }
+
+ if (!CommonUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, routeInfo.getUseOwnUpstream())) {
+ throw new UnprocessableEntityException(
+ "save RouteInfo FAIL:useOwnUpstream is wrong,value range:("
+ + RouteUtil.useOwnUpstreamRangeMatches + ")");
+ }
+
+ // Check the service instance format
+ RouteServer[] serverList = routeInfo.getServers();
+ for (int i = 0; i < serverList.length; i++) {
+ RouteServer server = serverList[i];
+ if (!RegExpTestUtil.ipRegExpTest(server.getIp())) {
+ throw new UnprocessableEntityException("save RouteInfo FAIL:IP(" + server.getIp()
+ + ")is not a valid ip address");
+ }
+
+ if (!RegExpTestUtil.portRegExpTest(server.getPort())) {
+ throw new UnprocessableEntityException("save RouteInfo FAIL:Port(" + server.getPort()
+ + ")is not a valid Port address");
+ }
+ }
+ }
+
+ public static void checkMicroServiceInfoFormat(MicroServiceFullInfo microServiceInfo,String requestIP){
+ // Check the service instance format
+ if (StringUtils.isBlank(microServiceInfo.getServiceName())
+ || StringUtils.isBlank(microServiceInfo.getProtocol())
+ || microServiceInfo.getNodes().size() == 0) {
+ throw new UnprocessableEntityException(
+ "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 UnprocessableEntityException("register MicroServiceInfo FAIL:IP(" + node.getIp()
+ + ")is not a valid ip address");
+ }
+
+ if (!RegExpTestUtil.portRegExpTest(node.getPort())) {
+ throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Port("
+ + node.getPort() + ")is not a valid Port address");
+ }
+ }
+
+ if (StringUtils.isNotBlank(microServiceInfo.getVersion())) {
+ if (!RegExpTestUtil.versionRegExpTest(microServiceInfo.getVersion())) {
+ throw new UnprocessableEntityException(
+ "register MicroServiceInfo FAIL:version is not a valid format");
+
+ }
+ }
+
+ if (StringUtils.isNotBlank(microServiceInfo.getUrl().trim())) {
+ if (!RegExpTestUtil.urlRegExpTest(microServiceInfo.getUrl())) {
+ throw new UnprocessableEntityException(
+ "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 UnprocessableEntityException(
+ "register MicroServiceInfo FAIL:Protocol is wrong,value range:("
+ + RouteUtil.PROTOCOL_LIST + ")");
+ }
+
+ }
+
+
+ public static String getAPIRedisPrefixedKey(String routeName, String version, String host,String publish_port,String routeWay){
+ String redisPrefixedKey;
+ if(ROUTEWAY_DOMAIN.equals(routeWay)){
+ redisPrefixedKey= RouteUtil.getPrefixedKey4Host(host, APIROUTE, routeName, version);
+ }
+ else{
+ redisPrefixedKey=RouteUtil.getPrefixedKey(publish_port, APIROUTE, routeName, version);
+ }
+
+ return redisPrefixedKey;
+ }
+
+ public static String getRedisPrefixedKey(String routeType,String routeName, String host,String publish_port,String routeWay){
+ String redisPrefixedKey;
+ if(ROUTEWAY_DOMAIN.equals(routeWay)){
+ redisPrefixedKey= RouteUtil.getPrefixedKey4Host(host, routeType, routeName);
+ }
+ else{
+ redisPrefixedKey=RouteUtil.getPrefixedKey(publish_port, routeType, routeName);
+ }
+
+ return redisPrefixedKey;
+ }
+
+ public static String getMutiRedisKey(String routeType,String routeWay){
+ String redisKey;
+ if(RouteUtil.ROUTEWAY_DOMAIN.equals(routeWay)){
+ redisKey =
+ RouteUtil.getPrefixedKey4Host("*", routeType, "*");
+
+ }
+ else{
+ redisKey =
+ RouteUtil.getPrefixedKey("[^h]*", routeType, "*");
+
+ }
+
+ return redisKey;
+ }
+
+ /**
+ * @Title getRouteNameByns
+ * @Description TODO(根据服务名和命名空间拆分服务路由名)
+ * @param serviceName
+ * @param namespace
+ * @return
+ * @return String
+ */
+ public static String getRouteNameByns(String consul_serviceName,String namespace){
+ String serviceName=consul_serviceName;
+ if(StringUtils.isNotBlank(namespace)){
+ if(consul_serviceName.endsWith("-"+namespace)){
+ serviceName=consul_serviceName.substring(0,consul_serviceName.length()-namespace.length()-1);
+ }
+ }
+
+ return serviceName;
+ }
+
+ public static String getVisualRangeByRouter(String visualRange){
+ String[] rangs = StringUtils.split(visualRange, "|");
+ if(rangs.length>1){
+ String visualRangeMatches=ConfigUtil.getInstance().getVisualRangeMatches();
+ if(StringUtils.split(visualRangeMatches, "|").length>1){
+ return "0";
+ }
+ else{
+ return visualRangeMatches;
+ }
+ }
+ else{
+ return visualRange;
+ }
+
+ }
+
+
+
+}
diff --git a/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ServiceFilter.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ServiceFilter.java
new file mode 100644
index 0000000..49b7b49
--- /dev/null
+++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ServiceFilter.java
@@ -0,0 +1,515 @@
+package org.onap.msb.apiroute.wrapper.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.msb.apiroute.api.MicroServiceFullInfo;
+import org.onap.msb.apiroute.api.Node;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.Service;
+import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.orbitz.consul.model.health.HealthCheck;
+
+
+
+public class ServiceFilter {
+ private static ServiceFilter instance = new ServiceFilter();
+
+ private ServiceFilter() {}
+
+ public static ServiceFilter getInstance() {
+ return instance;
+ }
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceFilter.class);
+
+
+ /**
+ * Determine whether the service needs to send a notification TODO: filter according to the
+ * agreement, the only notice of agreement for REST \HTTP\ UI interface MSB - REST
+ *
+ * @param protocol
+ * @return
+ */
+ public boolean isNeedNotifyByProtocol(String protocol) {
+ return CommonUtil.contain(RouteUtil.FILTER_PROTOCOLS, protocol.trim());
+ }
+
+ /**
+ * Determine whether the service needs to send a notification TODO: according to the visual range
+ * filter conditions Regular language: all 、 default 、 !default 、 A、 |A 、 A|B、 !A&!B
+ *
+ * @param visualRange
+ * @return
+ */
+ public boolean isNeedNotifyByNameSpace(String nameSpace) {
+
+ String namespaceMatches = ConfigUtil.getInstance().getNamespaceMatches();
+ String[] namespaceArray = StringUtils.split(namespaceMatches, "|");
+
+ if (CommonUtil.contain(namespaceArray, "all")) {
+ return true;
+ }
+
+ if (CommonUtil.contain(namespaceArray, "default")) {
+ if (StringUtils.isEmpty(nameSpace) || "default".equals(nameSpace) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ if (CommonUtil.contain(namespaceArray, "!default")) {
+ if (StringUtils.isNotEmpty(nameSpace) && !"default".equals(nameSpace)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ try {
+ String namespaceReg;
+ if (namespaceMatches.contains("!")) {
+ namespaceReg = "^" + namespaceMatches.replaceAll("!", "").replaceAll("&", "|") + "$";
+ return !Pattern.matches(namespaceReg, nameSpace);
+ } else {
+ namespaceReg = "^" + namespaceMatches + "$";
+ return Pattern.matches(namespaceReg, nameSpace);
+ }
+
+ } catch (Exception e) {
+ LOGGER.error(" Regular " + namespaceMatches + " throw exception:" + e.getMessage());
+ return false;
+ }
+ }
+
+ public boolean isNeedNotifyByVisualRange(String visualRange) {
+
+ String[] routeVisualRangeArray =
+ StringUtils.split(ConfigUtil.getInstance().getVisualRangeMatches(), "|");
+
+ String[] serviceVisualRangeArray = StringUtils.split(visualRange, "|");
+
+ if (CommonUtil.contain(serviceVisualRangeArray, routeVisualRangeArray)) {
+ return true;
+ }
+
+ return false;
+
+ }
+
+ public boolean isNeedNotifyByNetwork_plane_typeMatches(String network_plane_type) {
+
+ String network_plane_typeMatches = ConfigUtil.getInstance().getNetwork_plane_typeMatches();
+ if (StringUtils.isBlank(network_plane_typeMatches))
+ return true;
+
+ String[] routeNetwork_plane_typeArray = StringUtils.split(network_plane_typeMatches, "|");
+
+ String[] serviceVisualRangeArray = StringUtils.split(network_plane_type, "|");
+
+ if (CommonUtil.contain(serviceVisualRangeArray, routeNetwork_plane_typeArray)) {
+ return true;
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Determine whether the service needs to send a notification TODO: according to the visual range
+ * filter conditions
+ *
+ * @param visualRange
+ * @return
+ */
+ public boolean isNeedNotifyByRouteLabels(Map<String, String> labelMap) {
+
+ Map<String, String> labelMapMatches = ConfigUtil.getInstance().getLabelMapMatches();
+
+ if (labelMapMatches == null || labelMapMatches.isEmpty()) {
+ return true;
+ }
+
+ for (Map.Entry<String, String> entry : labelMapMatches.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+
+ // Multiple values match
+
+ if (StringUtils.isBlank(labelMap.get(key))) {
+ continue;
+ }
+
+ String[] routeLalelsArray = StringUtils.split(value, "|");
+
+ String[] serviceLabelsArray = StringUtils.split(labelMap.get(key), "|");
+
+ if (CommonUtil.contain(routeLalelsArray, serviceLabelsArray)) {
+ return true;
+ }
+
+ }
+
+ return false;
+ }
+
+
+
+ /*
+ * public boolean isNeedNotifyByRoute(String protocol, String namespace, String visualRange,
+ * String network_plane_type, Map<String, String> labelMap) {
+ *
+ * return isNeedNotifyByProtocol(protocol) && isNeedNotifyByNameSpace(namespace) &&
+ * isNeedNotifyByVisualRange(visualRange) && isNeedNotifyByRouteLabels(labelMap) &&
+ * isNeedNotifyByNetwork_plane_typeMatches(network_plane_type);
+ *
+ * }
+ */
+
+ public boolean isFilterCheck(ServiceHealth health){
+ return isFilterHealthCheck(health.getChecks()) && isFilterService(health.getService().getTags());
+ }
+
+ /**
+ * @Title isFilterHealthCheck
+ * @Description TODO(判断服务实例的健康检查信息,全部为passing表示健康检查有效)
+ * @param List<HealthCheck>
+ * @return boolean checkList示例——"Checks" : [{
+ "Node" : "server",
+ "CheckID" : "serfHealth",
+ "Name" : "Serf Health Status",
+ "Status" : "passing",
+ "Notes" : "",
+ "Output" : "Agent alive and reachable",
+ "ServiceID" : "",
+ "ServiceName" : "",
+ "CreateIndex" : 65536,
+ "ModifyIndex" : 65536
+ }, {
+ "Node" : "server",
+ "CheckID" : "service:_tcp_roundrobin_1_10.74.151.26_22",
+ "Name" : "Service 'tcp_roundrobin_1' check",
+ "Status" : "critical",
+ "Notes" : "",
+ "Output" : "dial tcp: missing port in address ok",
+ "ServiceID" : "_tcp_roundrobin_1_10.74.151.26_22",
+ "ServiceName" : "tcp_roundrobin_1",
+ "CreateIndex" : 75988,
+ "ModifyIndex" : 76173
+ }
+ ]
+ */
+ public boolean isFilterHealthCheck(List<HealthCheck> checkList){
+ if(checkList.isEmpty()){
+ return true;
+ }
+
+ for (HealthCheck check : checkList) {
+ if (!RouteUtil.HEALTH_CHECK_PASSING.equals(check.getStatus())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * @Title isFilterService
+ * @Description TODO(判断来自consul的服务信息是否需要过滤)
+ * @param List<String>
+ * @return boolean tagList示例—— [
+ * "\"base\":{\"protocol\":\"REST\",\"is_manual\":\"true\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"
+ * , "\"ns\":{\"namespace\":\"nsName\"}",
+ * "\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"
+ * ]
+ */
+ @SuppressWarnings("unchecked")
+ public boolean isFilterService(List<String> tagList) {
+
+ if (tagList == null || tagList.size() == 0)
+ return false;
+
+ String visualRange = "", network_plane_type = "", protocol = "", namespace = "";
+
+ //针对多版本不同属性的tag会有多个,只要其中一个匹配即通过过滤,默认不通过
+ boolean visualRangeFilter=false,protocolFilter = false, namespaceFilter = false;
+ boolean hasnamespace=false;
+
+ try {
+
+ for (String tag : tagList) {
+
+ // 提取基础属性tag
+ if (!protocolFilter && tag.startsWith("\"base\"")) {
+ String ms_base_json = tag.split("\"base\":")[1];
+
+ Map<String, String> baseMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
+
+ if (baseMap.get("protocol") != null) {
+ protocol = baseMap.get("protocol");
+ if ("PORTAL".equalsIgnoreCase(protocol)) {
+ protocol = "HTTP";
+ }
+
+ if (isNeedNotifyByProtocol(protocol)) {
+ protocolFilter=true;
+ }
+
+ }
+
+
+
+ continue;
+ }
+
+ // 提取命名空间属性tag
+ if (!namespaceFilter && tag.startsWith("\"ns\"")) {
+ String ms_ns_json = tag.split("\"ns\":")[1];
+ Map<String, String> nsMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
+
+ if (nsMap.get("namespace") != null) {
+ namespace = nsMap.get("namespace");
+ hasnamespace=true;
+
+ if (isNeedNotifyByNameSpace(namespace)) {
+ namespaceFilter=true;
+ }
+ }
+
+
+ continue;
+ }
+
+ // 提取Label属性tag
+ if (tag.startsWith("\"labels\"")) {
+ String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
+ // 自定义label标签属性
+ Map<String, String> labelMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
+
+
+
+ if (!visualRangeFilter && labelMap.get("visualRange") != null) {
+ visualRange = labelMap.get("visualRange");
+ labelMap.remove("visualRange"); // 自定义标签排除可见范围和网络平面
+
+ if(isNeedNotifyByVisualRange(visualRange)){
+ visualRangeFilter=true;
+ }
+ }
+
+
+ if (labelMap.get("network_plane_type") != null) {
+ network_plane_type = labelMap.get("network_plane_type");
+ labelMap.remove("network_plane_type");
+ }
+ if (!isNeedNotifyByNetwork_plane_typeMatches(network_plane_type)) {
+ return false;
+ }
+
+ if (!isNeedNotifyByRouteLabels(labelMap)) {
+ return false;
+ }
+
+ continue;
+ }
+
+ }
+
+ //针对无命名空间的服务判断是否过滤
+ if (!hasnamespace && isNeedNotifyByNameSpace(namespace)) {
+ namespaceFilter=true;
+ }
+
+ return visualRangeFilter && protocolFilter && namespaceFilter;
+
+
+ } catch (Exception e) {
+ LOGGER.error(" read tag throw exception", e);
+ return false;
+ }
+
+
+ }
+
+
+
+ @SuppressWarnings("unchecked")
+ public Map<String, MicroServiceFullInfo> transMicroServiceInfoFromConsul(
+ List<ServiceHealth> serviceNodeList) {
+ // 同名多版本服务MAP
+ Map<String, MicroServiceFullInfo> microServiceInfo4version =
+ new HashMap<String, MicroServiceFullInfo>();
+
+
+ for (ServiceHealth serviceNode : serviceNodeList) {
+
+ MicroServiceFullInfo microServiceInfo = new MicroServiceFullInfo();
+ String url = "";
+ String version = "", visualRange = "", protocol = "", lb_policy = "", namespace =
+ "", host = "", path = "", publish_port = "";
+ boolean enable_ssl = false;
+
+ HashSet<Node> nodes = new HashSet<Node>();
+
+ Service service = serviceNode.getService();
+ String serviceName = service.getService();
+
+ try {
+ List<String> tagList = service.getTags();
+
+ for (String tag : tagList) {
+
+ if (tag.startsWith("\"base\"")) {
+ String ms_base_json = tag.split("\"base\":")[1];
+
+
+ Map<String, String> baseMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
+ if (baseMap.get("url") != null) {
+ url = baseMap.get("url");
+ }
+
+ if (baseMap.get("version") != null) {
+ version = baseMap.get("version");
+ }
+
+ if (baseMap.get("protocol") != null) {
+ protocol = baseMap.get("protocol");
+ }
+
+ if (baseMap.get("host") != null) {
+ host = baseMap.get("host");
+ }
+
+ if (baseMap.get("path") != null) {
+ path = baseMap.get("path");
+ }
+
+ if (baseMap.get("publish_port") != null) {
+ publish_port = baseMap.get("publish_port");
+ }
+
+
+ if (baseMap.get("enable_ssl") != null) {
+ enable_ssl = Boolean.valueOf(baseMap.get("enable_ssl"));
+ }
+
+ continue;
+ }
+
+
+
+ if (tag.startsWith("\"ns\"")) {
+ String ms_ns_json = tag.split("\"ns\":")[1];
+ Map<String, String> nsMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
+
+ if (nsMap.get("namespace") != null) {
+ namespace = nsMap.get("namespace");
+ }
+
+ continue;
+ }
+
+ if (tag.startsWith("\"labels\"")) {
+ String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
+ Map<String, String> labelMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
+
+
+ if (labelMap.get("visualRange") != null) {
+ visualRange = labelMap.get("visualRange");
+ }
+
+ /*if (labelMap.get("network_plane_type") != null) {
+ network_plane_type = labelMap.get("network_plane_type");
+ }*/
+
+ continue;
+ }
+
+ if (tag.startsWith("\"lb\"")) {
+ String ms_lb_json = tag.split("\"lb\":")[1];
+ Map<String, String> lbMap =
+ (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_lb_json, Map.class);
+
+ if (lbMap.get("lb_policy") != null) {
+ lb_policy = lbMap.get("lb_policy");
+ }
+ continue;
+ }
+
+ }
+
+
+
+ } catch (Exception e) {
+ LOGGER.error(serviceName + " read tag throw exception", e);
+ }
+
+ if (!microServiceInfo4version.containsKey(version)) {
+
+ if ("PORTAL".equalsIgnoreCase(protocol)) {
+ protocol = "HTTP";
+ microServiceInfo.setCustom(RouteUtil.CUSTOM_PORTAL);
+ }
+
+ microServiceInfo.setProtocol(protocol);
+ microServiceInfo.setUrl(url);
+ microServiceInfo.setServiceName(serviceName);
+ microServiceInfo.setLb_policy(lb_policy);
+ microServiceInfo.setVisualRange(visualRange);
+
+ microServiceInfo.setEnable_ssl(enable_ssl);
+ microServiceInfo.setVersion(version);
+ microServiceInfo.setNamespace(namespace);
+ microServiceInfo.setHost(host);
+ microServiceInfo.setPath(path);
+ //系统间apigateway 保存publish_port
+ if ("0".equals(ConfigUtil.getInstance().getVisualRangeMatches())) {
+ microServiceInfo.setPublish_port(publish_port);
+ }
+
+ nodes.add(new Node(service.getAddress(), String.valueOf(service.getPort())));
+ microServiceInfo.setNodes(nodes);
+
+ microServiceInfo4version.put(version, microServiceInfo);
+ } else {
+
+ Set<Node> newNodes = microServiceInfo4version.get(version).getNodes();
+ // 默认node是注册信息的IP和port
+ newNodes.add(new Node(service.getAddress(), String.valueOf(service.getPort())));
+
+ // 同名多版本同步
+ microServiceInfo4version.get(version).setNodes(newNodes);
+
+ }
+
+
+ /*
+ * // 健康检查信息 List<Check> checks = value.getChecks(); node.setStatus("passing"); for (Check
+ * check : checks) { if (!"passing".equals(check.getStatus())) {
+ * node.setStatus(check.getStatus()); break; } }
+ */
+
+
+
+ }
+
+ return microServiceInfo4version;
+
+ }
+
+}