--- /dev/null
+/**\r
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+package org.openo.msb;\r
+\r
+import io.dropwizard.Application;\r
+import io.dropwizard.assets.AssetsBundle;\r
+import io.dropwizard.jetty.HttpConnectorFactory;\r
+import io.dropwizard.server.SimpleServerFactory;\r
+import io.dropwizard.setup.Bootstrap;\r
+import io.dropwizard.setup.Environment;\r
+import io.swagger.jaxrs.config.BeanConfig;\r
+import io.swagger.jaxrs.listing.ApiListingResource;\r
+\r
+import java.io.BufferedWriter;\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.net.URL;\r
+import java.util.List;\r
+\r
+import net.sf.json.JSONObject;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.openo.msb.api.ApiRouteInfo;\r
+import org.openo.msb.api.ConsulInfo;\r
+import org.openo.msb.api.CustomRouteInfo;\r
+import org.openo.msb.api.DiscoverInfo;\r
+import org.openo.msb.api.IuiRouteInfo;\r
+import org.openo.msb.api.RouteServer;\r
+import org.openo.msb.api.exception.ExtendedNotFoundException;\r
+import org.openo.msb.health.ApiRouteHealthCheck;\r
+import org.openo.msb.resources.ApiRouteResource;\r
+import org.openo.msb.resources.CustomRouteResource;\r
+import org.openo.msb.resources.IuiRouteResource;\r
+import org.openo.msb.resources.MetricsResource;\r
+import org.openo.msb.resources.MicroServiceResource;\r
+import org.openo.msb.resources.ServiceAccessResource;\r
+import org.openo.msb.wrapper.ApiRouteServiceWrapper;\r
+import org.openo.msb.wrapper.CustomRouteServiceWrapper;\r
+import org.openo.msb.wrapper.IuiRouteServiceWrapper;\r
+import org.openo.msb.wrapper.serviceListener.MicroServiceChangeListener;\r
+import org.openo.msb.wrapper.util.FileUtil;\r
+import org.openo.msb.wrapper.util.JacksonJsonUtil;\r
+import org.openo.msb.wrapper.util.JedisUtil;\r
+import org.openo.msb.wrapper.util.MetricsUtil;\r
+import org.openo.msb.wrapper.util.MicroServiceDB;\r
+import org.openo.msb.wrapper.util.RegExpTestUtil;\r
+import org.openo.msb.wrapper.util.RouteUtil;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.fasterxml.jackson.annotation.JsonInclude;\r
+\r
+public class ApiRouteApp extends Application<ApiRouteAppConfig> {\r
+\r
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class);\r
+\r
+ public static void main(String[] args) throws Exception {\r
+ new ApiRouteApp().run(args);\r
+\r
+ }\r
+\r
+ private ApiRouteAppConfig config;\r
+\r
+ @Override\r
+ public String getName() {\r
+ return " MicroService Bus ";\r
+ }\r
+\r
+ @Override\r
+ public void initialize(Bootstrap<ApiRouteAppConfig> bootstrap) {\r
+ \r
+ \r
+ }\r
+\r
+ @Override\r
+ public void run(ApiRouteAppConfig configuration, Environment environment) {\r
+ \r
+ initRootPath();\r
+ \r
+ \r
+ new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics",\r
+ "index.html", "iui-metrics").run(environment); \r
+ \r
+ new AssetsBundle("/iui-route", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html",\r
+ "iui-microservices").run(environment); \r
+ \r
+ new AssetsBundle("/api-doc", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc",\r
+ "index.html", "api-doc").run(environment);\r
+ \r
+ new AssetsBundle("/ext", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext",\r
+ "index.html", "ext").run(environment);\r
+ \r
+ \r
+ \r
+\r
+ final ApiRouteHealthCheck healthCheck =\r
+ new ApiRouteHealthCheck(configuration.getDefaultWorkspace());\r
+ environment.healthChecks().register("template", healthCheck);\r
+ environment.jersey().register(new ApiRouteResource());\r
+ environment.jersey().register(new IuiRouteResource());\r
+ environment.jersey().register(new MetricsResource());\r
+ environment.jersey().register(new CustomRouteResource());\r
+ environment.jersey().register(new ServiceAccessResource());\r
+ environment.jersey().register(new MicroServiceResource());\r
+\r
+ config = configuration;\r
+\r
+ initSwaggerConfig(environment, configuration);\r
+ initRedisConfig(configuration);\r
+ checkRedisConnect();\r
+ initMetricsConfig(configuration);\r
+ initVisualRangeMatches();\r
+\r
+ registerServiceChangeListener();\r
+\r
+\r
+ }\r
+\r
+ private void initMetricsConfig(ApiRouteAppConfig configuration) {\r
+\r
+ SimpleServerFactory simpleServerFactory =\r
+ (SimpleServerFactory) configuration.getServerFactory();\r
+ HttpConnectorFactory httpConnectorFactory =\r
+ (HttpConnectorFactory) simpleServerFactory.getConnector();\r
+ MetricsUtil.adminContextPath =\r
+ "http://127.0.0.1:" + httpConnectorFactory.getPort()\r
+ + simpleServerFactory.getAdminContextPath() + "/metrics";\r
+ }\r
+\r
+ private void initSwaggerConfig(Environment environment, ApiRouteAppConfig configuration) {\r
+\r
+ environment.jersey().register(new ApiListingResource());\r
+ environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);\r
+\r
+ BeanConfig config = new BeanConfig();\r
+ config.setTitle("MicroService Bus rest API");\r
+ config.setVersion("1.0.0");\r
+ config.setResourcePackage("org.openo.msb.resources");\r
+ SimpleServerFactory simpleServerFactory =\r
+ (SimpleServerFactory) configuration.getServerFactory();\r
+ String basePath = simpleServerFactory.getApplicationContextPath();\r
+ String rootPath = simpleServerFactory.getJerseyRootPath();\r
+\r
+ rootPath = rootPath.substring(0, rootPath.indexOf("/*"));\r
+\r
+ basePath =\r
+ basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath)\r
+ .append(rootPath).toString();\r
+\r
+ LOGGER.info("getApplicationContextPath: " + basePath);\r
+ config.setBasePath(basePath);\r
+ config.setScan(true);\r
+ }\r
+ \r
+ \r
+ private void initRootPath(){\r
+ try {\r
+ \r
+ URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json");\r
+ if (urlRootPath != null) {\r
+ String path = urlRootPath.getPath();\r
+ \r
+ LOGGER.info("read initUrlRootPath:" + path);\r
+ \r
+ String fileContent = FileUtil.readFile(path);\r
+ JSONObject jsonObj = JSONObject.fromObject(fileContent);\r
+ RouteUtil.IUI_ROOT_PATH=jsonObj.get("iuiRootPath").toString();\r
+ RouteUtil.API_ROOT_PATH=jsonObj.get("apiRootPath").toString();\r
+ }\r
+ } catch (Exception e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.error("read initUrlRootPath Files throw exception", e);\r
+ }\r
+ \r
+ }\r
+ private void initRedisConfig(ApiRouteAppConfig configuration) {\r
+\r
+ String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();\r
+ String jarPath = path.substring(0, path.lastIndexOf("/"));\r
+\r
+ LOGGER.info("jarpath: " + jarPath);\r
+ LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace());\r
+\r
+ String confDir =\r
+ jarPath + "/" + configuration.getDefaultWorkspace() + "/"\r
+ + configuration.getPropertiesDir();\r
+ String propertiesPath = confDir + "/" + configuration.getPropertiesName();\r
+\r
+ JedisUtil.propertiesPath = propertiesPath;\r
+\r
+ LOGGER.info("propertiesPath: " + propertiesPath);\r
+ LOGGER.info("confDir: " + confDir);\r
+\r
+ try {\r
+ File dirFile = new File(confDir);\r
+\r
+ if (!dirFile.exists()) {\r
+ dirFile.mkdirs();\r
+ }\r
+ } catch (Exception e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage());\r
+ }\r
+\r
+\r
+ try {\r
+ File propertiesFile = new File(propertiesPath);\r
+ if (!propertiesFile.exists()) {\r
+\r
+\r
+ propertiesFile.createNewFile();\r
+\r
+ BufferedWriter output = new BufferedWriter(new FileWriter(propertiesFile));\r
+ StringBuilder contentBuilder = new StringBuilder();\r
+ contentBuilder.append("redis.host=127.0.0.1\n").append("redis.port=6379\n")\r
+ .append("#connectionTimeout\n").append("redis.connectionTimeout=2000\n")\r
+ .append("#redis dbIndex,defaule:0\n")\r
+ .append("redis.db_index=0\n\n")\r
+ .append("#--------------redis pool config--------------\n")\r
+ .append("#maxTotal\n").append("redis.pool.maxTotal=100\n")\r
+ .append("#maxIdle\n").append("redis.pool.maxIdle=20\n")\r
+ .append("#maxWaitMillis:ms\n")\r
+ .append("redis.pool.maxWaitMillis=1000\n")\r
+ .append("#testOnBorrow\n")\r
+ .append("redis.pool.testOnBorrow=false\n")\r
+ .append("#testOnReturn\n")\r
+ .append("redis.pool.testOnReturn=true\n")\r
+ .append("#nginx Port\n").append("server.port=10080\n");\r
+\r
+ output.write(contentBuilder.toString());\r
+ output.close();\r
+\r
+ }\r
+ } catch (IOException e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage());\r
+ }\r
+ }\r
+\r
+\r
+ private void checkRedisConnect() {\r
+\r
+ new Thread(new Runnable() {\r
+ public void run() {\r
+ int n = 0;\r
+ while (true) {\r
+ if (ApiRouteServiceWrapper.checkRedisConnect() == false) {\r
+ n++;\r
+ System.out.println(n\r
+ + "/10 : Initial Route Configuration——redis connection fail...");\r
+\r
+ try {\r
+ Thread.sleep(10000);\r
+ } catch (InterruptedException e) {\r
+ LOGGER.error("Thread.sleep throw except:"+e.getMessage());\r
+ }\r
+\r
+\r
+ if (n >= 10) {\r
+ System.out.println("Initial Route Configuration fail,timeout exit");\r
+ LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit...");\r
+ break;\r
+ }\r
+ } else {\r
+ System.out.println("starting to initial Route Configuration");\r
+ // initRouteInfoFromConfig();\r
+ initRouteInfoFromJson();\r
+ System.out.println("starting to initial consul Configuration");\r
+ runConsulClientApp();\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ }\r
+ }).start();\r
+ }\r
+\r
+\r
+ \r
+\r
+ /**\r
+ * @Title: initVisualRangeMatches\r
+ * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions)\r
+ * @return: void\r
+ */\r
+ private void initVisualRangeMatches(){\r
+ try {\r
+ if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null)\r
+ {\r
+ \r
+ URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json");\r
+ if (visualRangePath != null) {\r
+ String path = visualRangePath.getPath();\r
+ \r
+ LOGGER.info("read initVisualRangeMatches:" + path);\r
+ \r
+ String fileContent = FileUtil.readFile(path);\r
+ JSONObject jsonObj = JSONObject.fromObject(fileContent);\r
+ String visualRangeArray=jsonObj.get("visualRange").toString();\r
+ \r
+ \r
+ RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ","); \r
+ \r
+ \r
+ \r
+ }\r
+ }\r
+ else{\r
+ RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ",");\r
+ }\r
+ } catch (Exception e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.error("read initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @Title: initRouteInfoFromJson\r
+ * @Description: TODO(按照JSON文件配置初始化route数据)\r
+ * @return: void\r
+ */\r
+ private void initRouteInfoFromJson() {\r
+\r
+ URL apiDocsPath = ApiRouteApp.class.getResource("/ext/initServices");\r
+ if (apiDocsPath != null) {\r
+ String path = apiDocsPath.getPath();\r
+\r
+ LOGGER.info("read JsonFilefolder:" + path);\r
+\r
+ try {\r
+ File[] files = FileUtil.readFileFolder(path);\r
+ for (int i = 0; i < files.length; i++) {\r
+ File file = files[i];\r
+ if (file.isFile() && file.getName().endsWith(".json")) {\r
+ LOGGER.info("read JsonFile:" + file.getPath());\r
+ String fileContent = FileUtil.readFile(file.getPath());\r
+ saveInitService2redis(fileContent);\r
+ } else {\r
+ LOGGER.warn(file.getName() + " is not a right file");\r
+ }\r
+ }\r
+\r
+\r
+\r
+ } catch (FileNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.error("read initServices Files throw FileNotFoundException", e);\r
+ } catch (IOException e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.error("read initServices Files throw IOexception", e);\r
+ }\r
+\r
+ }\r
+\r
+\r
+\r
+ }\r
+\r
+\r
+\r
+ private void saveInitService2redis(String fileContent) {\r
+ try {\r
+ List<ApiRouteInfo> routeList =\r
+ (List<ApiRouteInfo>) JacksonJsonUtil.jsonToListBean(fileContent);\r
+ for (ApiRouteInfo route : routeList) {\r
+ String url = route.getUrl();\r
+\r
+ if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) {\r
+ \r
+ try{\r
+ CustomRouteInfo dbCustomRoute =\r
+ CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(\r
+ route.getServiceName());\r
+ }\r
+ catch(ExtendedNotFoundException e){\r
+\r
+ LOGGER.info("initCustomRoute: ServiceName--" + route.getServiceName());\r
+\r
+ CustomRouteInfo customRouteInfo = new CustomRouteInfo();\r
+ customRouteInfo.setControl(route.getControl());\r
+ customRouteInfo.setServers(route.getServers());\r
+ customRouteInfo.setServiceName(route.getServiceName());\r
+ customRouteInfo.setStatus(route.getStatus());\r
+ customRouteInfo.setUrl(route.getUrl());\r
+\r
+\r
+ CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(\r
+ customRouteInfo, "");\r
+\r
+\r
+ }\r
+ } else {\r
+\r
+ if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) {\r
+\r
+\r
+ try{\r
+ ApiRouteInfo dbApiRoute =\r
+ ApiRouteServiceWrapper.getInstance().getApiRouteInstance(\r
+ route.getServiceName(), route.getVersion());\r
+ }\r
+ catch(ExtendedNotFoundException e){\r
+ LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName());\r
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, "");\r
+ }\r
+\r
+ \r
+ } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) {\r
+ \r
+ try{\r
+ IuiRouteInfo dbIuiRoute =\r
+ IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(\r
+ route.getServiceName());\r
+ }\r
+ catch(ExtendedNotFoundException e){\r
+ \r
+ LOGGER.info(" initiuiRoute: ServiceName--" + route.getServiceName());\r
+ IuiRouteInfo iuiRouteInfo = new IuiRouteInfo();\r
+ iuiRouteInfo.setControl(route.getControl());\r
+ iuiRouteInfo.setServers(route.getServers());\r
+ iuiRouteInfo.setServiceName(route.getServiceName());\r
+ iuiRouteInfo.setStatus(route.getStatus());\r
+ \r
+ if(url.equals("/iui/microservices")){\r
+ iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices");\r
+ }\r
+ else{\r
+ iuiRouteInfo.setUrl(route.getUrl());\r
+ }\r
+\r
+ IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo);\r
+\r
+ }\r
+\r
+ } else {\r
+ LOGGER.error("init Service throw exception——serviceName: " + route.getServiceName()+",url:"+url);\r
+ }\r
+ }\r
+\r
+\r
+\r
+ }\r
+\r
+ } catch (Exception e) {\r
+ // TODO Auto-generated catch block\r
+ LOGGER.error("read initServices Files throw exception", e);\r
+ }\r
+\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ * The listener registration service changes\r
+ */\r
+ private void registerServiceChangeListener() {\r
+ MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener());\r
+ }\r
+\r
+ // Open the consul to monitor subscription service\r
+ private void runConsulClientApp() {\r
+ DiscoverInfo config_discoverInfo = config.getDiscoverInfo();\r
+ \r
+ ConsulInfo config_consulInfo=config.getConsulInfo();\r
+ \r
+ RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled()); \r
+ \r
+ if (config_discoverInfo.isEnabled()) {\r
+ try{\r
+ if(System.getenv("SDCLIENT_SVC_PORT")==null)\r
+ {\r
+ //yml \r
+ RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp()); \r
+ RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort());\r
+ \r
+ }\r
+ else{\r
+ \r
+ String discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1];\r
+ String sdIP=discoverAddress.split(":")[0];\r
+ int sdPort=Integer\r
+ .parseInt(discoverAddress.split(":")[1]);\r
+ \r
+ RouteUtil.discoverInfo.setIp(sdIP);\r
+ RouteUtil.discoverInfo.setPort(sdPort);\r
+ \r
+ config_consulInfo.setIp(sdIP);\r
+ config_consulInfo.setPort(sdPort);\r
+ \r
+ \r
+ }\r
+ \r
+ \r
+ \r
+ //Registration service discovery routing\r
+ //api\r
+ ApiRouteInfo discoverApiService=new ApiRouteInfo();\r
+ discoverApiService.setServiceName("msdiscover");\r
+ discoverApiService.setUrl("/api/microservices/v1");\r
+ discoverApiService.setVersion("v1");\r
+ discoverApiService.setMetricsUrl("/admin/metrics");\r
+ discoverApiService.setApiJson("/api/microservices/v1/swagger.json");\r
+ \r
+ RouteServer[] servers=new RouteServer[1];\r
+ servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort()));\r
+ discoverApiService.setServers(servers);\r
+ \r
+ ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, "");\r
+ \r
+ //iui\r
+ IuiRouteInfo discoverIUIService=new IuiRouteInfo();\r
+ discoverIUIService.setServiceName("msdiscover");\r
+ discoverIUIService.setUrl("/iui/microservices");\r
+ discoverIUIService.setServers(servers);\r
+ IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService);\r
+ \r
+ \r
+\r
+ ConsulClientApp consulClientApp = new ConsulClientApp(config_consulInfo.getIp(), config_consulInfo.getPort());\r
+ // Monitor service change\r
+ consulClientApp.startServiceListen();\r
+ LOGGER.info("start monitor consul service--" +config_consulInfo.getIp() + ":"\r
+ + config_consulInfo.getPort());\r
+ }\r
+ catch(Exception e){\r
+ LOGGER.error("start monitor consul service fail:"+e.getMessage()); \r
+ }\r
+ }\r
+ \r
+ \r
+ }\r
+\r
+}\r