2 * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.openo.msb;
18 import io.dropwizard.Application;
19 import io.dropwizard.assets.AssetsBundle;
20 import io.dropwizard.jetty.HttpConnectorFactory;
21 import io.dropwizard.server.SimpleServerFactory;
22 import io.dropwizard.setup.Bootstrap;
23 import io.dropwizard.setup.Environment;
24 import io.swagger.jaxrs.config.BeanConfig;
25 import io.swagger.jaxrs.listing.ApiListingResource;
27 import java.io.BufferedWriter;
29 import java.io.FileNotFoundException;
30 import java.io.FileWriter;
31 import java.io.IOException;
33 import java.util.List;
35 import net.sf.json.JSONObject;
37 import org.apache.commons.lang3.StringUtils;
38 import org.openo.msb.api.ApiRouteInfo;
39 import org.openo.msb.api.ConsulInfo;
40 import org.openo.msb.api.CustomRouteInfo;
41 import org.openo.msb.api.DiscoverInfo;
42 import org.openo.msb.api.IuiRouteInfo;
43 import org.openo.msb.api.RouteServer;
44 import org.openo.msb.api.exception.ExtendedNotFoundException;
45 import org.openo.msb.health.ApiRouteHealthCheck;
46 import org.openo.msb.resources.ApiRouteResource;
47 import org.openo.msb.resources.CustomRouteResource;
48 import org.openo.msb.resources.IuiRouteResource;
49 import org.openo.msb.resources.MetricsResource;
50 import org.openo.msb.resources.MicroServiceResource;
51 import org.openo.msb.resources.ServiceAccessResource;
52 import org.openo.msb.wrapper.ApiRouteServiceWrapper;
53 import org.openo.msb.wrapper.CustomRouteServiceWrapper;
54 import org.openo.msb.wrapper.IuiRouteServiceWrapper;
55 import org.openo.msb.wrapper.serviceListener.MicroServiceChangeListener;
56 import org.openo.msb.wrapper.util.FileUtil;
57 import org.openo.msb.wrapper.util.JacksonJsonUtil;
58 import org.openo.msb.wrapper.util.JedisUtil;
59 import org.openo.msb.wrapper.util.MetricsUtil;
60 import org.openo.msb.wrapper.util.MicroServiceDB;
61 import org.openo.msb.wrapper.util.RegExpTestUtil;
62 import org.openo.msb.wrapper.util.RouteUtil;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 import com.fasterxml.jackson.annotation.JsonInclude;
68 public class ApiRouteApp extends Application<ApiRouteAppConfig> {
70 private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class);
72 public static void main(String[] args) throws Exception {
73 new ApiRouteApp().run(args);
77 private ApiRouteAppConfig config;
80 public String getName() {
81 return " MicroService Bus ";
85 public void initialize(Bootstrap<ApiRouteAppConfig> bootstrap) {
91 public void run(ApiRouteAppConfig configuration, Environment environment) {
96 new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics",
97 "index.html", "iui-metrics").run(environment);
99 new AssetsBundle("/iui-route", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html",
100 "iui-microservices").run(environment);
102 new AssetsBundle("/api-doc", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc",
103 "index.html", "api-doc").run(environment);
105 new AssetsBundle("/ext", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext",
106 "index.html", "ext").run(environment);
111 final ApiRouteHealthCheck healthCheck =
112 new ApiRouteHealthCheck(configuration.getDefaultWorkspace());
113 environment.healthChecks().register("template", healthCheck);
114 environment.jersey().register(new ApiRouteResource());
115 environment.jersey().register(new IuiRouteResource());
116 environment.jersey().register(new MetricsResource());
117 environment.jersey().register(new CustomRouteResource());
118 environment.jersey().register(new ServiceAccessResource());
119 environment.jersey().register(new MicroServiceResource());
121 config = configuration;
123 initSwaggerConfig(environment, configuration);
124 initRedisConfig(configuration);
126 initMetricsConfig(configuration);
127 initVisualRangeMatches();
129 registerServiceChangeListener();
134 private void initMetricsConfig(ApiRouteAppConfig configuration) {
136 SimpleServerFactory simpleServerFactory =
137 (SimpleServerFactory) configuration.getServerFactory();
138 HttpConnectorFactory httpConnectorFactory =
139 (HttpConnectorFactory) simpleServerFactory.getConnector();
140 MetricsUtil.adminContextPath =
141 "http://127.0.0.1:" + httpConnectorFactory.getPort()
142 + simpleServerFactory.getAdminContextPath() + "/metrics";
145 private void initSwaggerConfig(Environment environment, ApiRouteAppConfig configuration) {
147 environment.jersey().register(new ApiListingResource());
148 environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
150 BeanConfig config = new BeanConfig();
151 config.setTitle("MicroService Bus rest API");
152 config.setVersion("1.0.0");
153 config.setResourcePackage("org.openo.msb.resources");
154 SimpleServerFactory simpleServerFactory =
155 (SimpleServerFactory) configuration.getServerFactory();
156 String basePath = simpleServerFactory.getApplicationContextPath();
157 String rootPath = simpleServerFactory.getJerseyRootPath();
159 rootPath = rootPath.substring(0, rootPath.indexOf("/*"));
162 basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath)
163 .append(rootPath).toString();
165 LOGGER.info("getApplicationContextPath: " + basePath);
166 config.setBasePath(basePath);
167 config.setScan(true);
171 private void initRootPath(){
174 URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json");
175 if (urlRootPath != null) {
176 String path = urlRootPath.getPath();
178 LOGGER.info("read initUrlRootPath:" + path);
180 String fileContent = FileUtil.readFile(path);
181 JSONObject jsonObj = JSONObject.fromObject(fileContent);
182 RouteUtil.IUI_ROOT_PATH=jsonObj.get("iuiRootPath").toString();
183 RouteUtil.API_ROOT_PATH=jsonObj.get("apiRootPath").toString();
185 } catch (Exception e) {
186 // TODO Auto-generated catch block
187 LOGGER.error("read initUrlRootPath Files throw exception", e);
191 private void initRedisConfig(ApiRouteAppConfig configuration) {
193 String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
194 String jarPath = path.substring(0, path.lastIndexOf("/"));
196 LOGGER.info("jarpath: " + jarPath);
197 LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace());
200 jarPath + "/" + configuration.getDefaultWorkspace() + "/"
201 + configuration.getPropertiesDir();
202 String propertiesPath = confDir + "/" + configuration.getPropertiesName();
204 JedisUtil.propertiesPath = propertiesPath;
206 LOGGER.info("propertiesPath: " + propertiesPath);
207 LOGGER.info("confDir: " + confDir);
210 File dirFile = new File(confDir);
212 if (!dirFile.exists()) {
215 } catch (Exception e) {
216 // TODO Auto-generated catch block
217 LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage());
222 File propertiesFile = new File(propertiesPath);
223 if (!propertiesFile.exists()) {
226 propertiesFile.createNewFile();
228 BufferedWriter output = new BufferedWriter(new FileWriter(propertiesFile));
229 StringBuilder contentBuilder = new StringBuilder();
230 contentBuilder.append("redis.host=127.0.0.1\n").append("redis.port=6379\n")
231 .append("#connectionTimeout\n").append("redis.connectionTimeout=2000\n")
232 .append("#redis dbIndex,defaule:0\n")
233 .append("redis.db_index=0\n\n")
234 .append("#--------------redis pool config--------------\n")
235 .append("#maxTotal\n").append("redis.pool.maxTotal=100\n")
236 .append("#maxIdle\n").append("redis.pool.maxIdle=20\n")
237 .append("#maxWaitMillis:ms\n")
238 .append("redis.pool.maxWaitMillis=1000\n")
239 .append("#testOnBorrow\n")
240 .append("redis.pool.testOnBorrow=false\n")
241 .append("#testOnReturn\n")
242 .append("redis.pool.testOnReturn=true\n")
243 .append("#nginx Port\n").append("server.port=10080\n");
245 output.write(contentBuilder.toString());
249 } catch (IOException e) {
250 // TODO Auto-generated catch block
251 LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage());
256 private void checkRedisConnect() {
258 new Thread(new Runnable() {
262 if (ApiRouteServiceWrapper.checkRedisConnect() == false) {
265 + "/10 : Initial Route Configuration——redis connection fail...");
269 } catch (InterruptedException e) {
270 LOGGER.error("Thread.sleep throw except:"+e.getMessage());
275 System.out.println("Initial Route Configuration fail,timeout exit");
276 LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit...");
280 System.out.println("starting to initial Route Configuration");
281 // initRouteInfoFromConfig();
282 initRouteInfoFromJson();
283 System.out.println("starting to initial consul Configuration");
284 runConsulClientApp();
298 * @Title: initVisualRangeMatches
299 * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions)
302 private void initVisualRangeMatches(){
304 if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null)
307 URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json");
308 if (visualRangePath != null) {
309 String path = visualRangePath.getPath();
311 LOGGER.info("read initVisualRangeMatches:" + path);
313 String fileContent = FileUtil.readFile(path);
314 JSONObject jsonObj = JSONObject.fromObject(fileContent);
315 String visualRangeArray=jsonObj.get("visualRange").toString();
318 RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ",");
325 RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ",");
327 } catch (Exception e) {
328 // TODO Auto-generated catch block
329 LOGGER.error("read initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e);
334 * @Title: initRouteInfoFromJson
335 * @Description: TODO(按照JSON文件配置初始化route数据)
338 private void initRouteInfoFromJson() {
340 URL apiDocsPath = ApiRouteApp.class.getResource("/ext/initServices");
341 if (apiDocsPath != null) {
342 String path = apiDocsPath.getPath();
344 LOGGER.info("read JsonFilefolder:" + path);
347 File[] files = FileUtil.readFileFolder(path);
348 for (int i = 0; i < files.length; i++) {
349 File file = files[i];
350 if (file.isFile() && file.getName().endsWith(".json")) {
351 LOGGER.info("read JsonFile:" + file.getPath());
352 String fileContent = FileUtil.readFile(file.getPath());
353 saveInitService2redis(fileContent);
355 LOGGER.warn(file.getName() + " is not a right file");
361 } catch (FileNotFoundException e) {
362 // TODO Auto-generated catch block
363 LOGGER.error("read initServices Files throw FileNotFoundException", e);
364 } catch (IOException e) {
365 // TODO Auto-generated catch block
366 LOGGER.error("read initServices Files throw IOexception", e);
377 private void saveInitService2redis(String fileContent) {
379 List<ApiRouteInfo> routeList =
380 (List<ApiRouteInfo>) JacksonJsonUtil.jsonToListBean(fileContent);
381 for (ApiRouteInfo route : routeList) {
382 String url = route.getUrl();
384 if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) {
387 CustomRouteInfo dbCustomRoute =
388 CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(
389 route.getServiceName());
391 catch(ExtendedNotFoundException e){
393 LOGGER.info("initCustomRoute: ServiceName--" + route.getServiceName());
395 CustomRouteInfo customRouteInfo = new CustomRouteInfo();
396 customRouteInfo.setControl(route.getControl());
397 customRouteInfo.setServers(route.getServers());
398 customRouteInfo.setServiceName(route.getServiceName());
399 customRouteInfo.setStatus(route.getStatus());
400 customRouteInfo.setUrl(route.getUrl());
403 CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(
404 customRouteInfo, "");
410 if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) {
414 ApiRouteInfo dbApiRoute =
415 ApiRouteServiceWrapper.getInstance().getApiRouteInstance(
416 route.getServiceName(), route.getVersion());
418 catch(ExtendedNotFoundException e){
419 LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName());
420 ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, "");
424 } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) {
427 IuiRouteInfo dbIuiRoute =
428 IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(
429 route.getServiceName());
431 catch(ExtendedNotFoundException e){
433 LOGGER.info(" initiuiRoute: ServiceName--" + route.getServiceName());
434 IuiRouteInfo iuiRouteInfo = new IuiRouteInfo();
435 iuiRouteInfo.setControl(route.getControl());
436 iuiRouteInfo.setServers(route.getServers());
437 iuiRouteInfo.setServiceName(route.getServiceName());
438 iuiRouteInfo.setStatus(route.getStatus());
440 if(url.equals("/iui/microservices")){
441 iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices");
444 iuiRouteInfo.setUrl(route.getUrl());
447 IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo);
452 LOGGER.error("init Service throw exception——serviceName: " + route.getServiceName()+",url:"+url);
460 } catch (Exception e) {
461 // TODO Auto-generated catch block
462 LOGGER.error("read initServices Files throw exception", e);
470 * The listener registration service changes
472 private void registerServiceChangeListener() {
473 MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener());
476 // Open the consul to monitor subscription service
477 private void runConsulClientApp() {
478 DiscoverInfo config_discoverInfo = config.getDiscoverInfo();
480 ConsulInfo config_consulInfo=config.getConsulInfo();
482 RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled());
484 if (config_discoverInfo.isEnabled()) {
486 if(System.getenv("SDCLIENT_SVC_PORT")==null)
489 RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp());
490 RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort());
495 String discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1];
496 String sdIP=discoverAddress.split(":")[0];
498 .parseInt(discoverAddress.split(":")[1]);
500 RouteUtil.discoverInfo.setIp(sdIP);
501 RouteUtil.discoverInfo.setPort(sdPort);
503 config_consulInfo.setIp(sdIP);
504 config_consulInfo.setPort(sdPort);
511 //Registration service discovery routing
513 ApiRouteInfo discoverApiService=new ApiRouteInfo();
514 discoverApiService.setServiceName("msdiscover");
515 discoverApiService.setUrl("/api/microservices/v1");
516 discoverApiService.setVersion("v1");
517 discoverApiService.setMetricsUrl("/admin/metrics");
518 discoverApiService.setApiJson("/api/microservices/v1/swagger.json");
520 RouteServer[] servers=new RouteServer[1];
521 servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort()));
522 discoverApiService.setServers(servers);
524 ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, "");
527 IuiRouteInfo discoverIUIService=new IuiRouteInfo();
528 discoverIUIService.setServiceName("msdiscover");
529 discoverIUIService.setUrl("/iui/microservices");
530 discoverIUIService.setServers(servers);
531 IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService);
535 ConsulClientApp consulClientApp = new ConsulClientApp(config_consulInfo.getIp(), config_consulInfo.getPort());
536 // Monitor service change
537 consulClientApp.startServiceListen();
538 LOGGER.info("start monitor consul service--" +config_consulInfo.getIp() + ":"
539 + config_consulInfo.getPort());
542 LOGGER.error("start monitor consul service fail:"+e.getMessage());