2 * Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package org.openo.msb;
\r
19 import io.dropwizard.Application;
\r
20 import io.dropwizard.assets.AssetsBundle;
\r
21 import io.dropwizard.jetty.HttpConnectorFactory;
\r
22 import io.dropwizard.server.SimpleServerFactory;
\r
23 import io.dropwizard.setup.Bootstrap;
\r
24 import io.dropwizard.setup.Environment;
\r
25 import io.swagger.jaxrs.config.BeanConfig;
\r
26 import io.swagger.jaxrs.listing.ApiListingResource;
\r
28 import java.io.BufferedWriter;
\r
29 import java.io.File;
\r
30 import java.io.FileNotFoundException;
\r
31 import java.io.FileWriter;
\r
32 import java.io.IOException;
\r
33 import java.net.URL;
\r
34 import java.util.List;
\r
36 import net.sf.json.JSONObject;
\r
38 import org.apache.commons.lang3.StringUtils;
\r
39 import org.openo.msb.api.ApiRouteInfo;
\r
40 import org.openo.msb.api.ConsulInfo;
\r
41 import org.openo.msb.api.CustomRouteInfo;
\r
42 import org.openo.msb.api.DiscoverInfo;
\r
43 import org.openo.msb.api.IuiRouteInfo;
\r
44 import org.openo.msb.api.RouteServer;
\r
45 import org.openo.msb.api.exception.ExtendedNotFoundException;
\r
46 import org.openo.msb.health.ApiRouteHealthCheck;
\r
47 import org.openo.msb.resources.ApiRouteResource;
\r
48 import org.openo.msb.resources.CustomRouteResource;
\r
49 import org.openo.msb.resources.IuiRouteResource;
\r
50 import org.openo.msb.resources.MetricsResource;
\r
51 import org.openo.msb.resources.MicroServiceResource;
\r
52 import org.openo.msb.resources.ServiceAccessResource;
\r
53 import org.openo.msb.wrapper.ApiRouteServiceWrapper;
\r
54 import org.openo.msb.wrapper.CustomRouteServiceWrapper;
\r
55 import org.openo.msb.wrapper.IuiRouteServiceWrapper;
\r
56 import org.openo.msb.wrapper.serviceListener.MicroServiceChangeListener;
\r
57 import org.openo.msb.wrapper.util.FileUtil;
\r
58 import org.openo.msb.wrapper.util.JacksonJsonUtil;
\r
59 import org.openo.msb.wrapper.util.JedisUtil;
\r
60 import org.openo.msb.wrapper.util.MetricsUtil;
\r
61 import org.openo.msb.wrapper.util.MicroServiceDB;
\r
62 import org.openo.msb.wrapper.util.RegExpTestUtil;
\r
63 import org.openo.msb.wrapper.util.RouteUtil;
\r
64 import org.slf4j.Logger;
\r
65 import org.slf4j.LoggerFactory;
\r
67 import com.fasterxml.jackson.annotation.JsonInclude;
\r
69 public class ApiRouteApp extends Application<ApiRouteAppConfig> {
\r
71 private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class);
\r
73 public static void main(String[] args) throws Exception {
\r
74 new ApiRouteApp().run(args);
\r
78 private ApiRouteAppConfig config;
\r
81 public String getName() {
\r
82 return " MicroService Bus ";
\r
86 public void initialize(Bootstrap<ApiRouteAppConfig> bootstrap) {
\r
92 public void run(ApiRouteAppConfig configuration, Environment environment) {
\r
97 new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics",
\r
98 "index.html", "iui-metrics").run(environment);
\r
100 new AssetsBundle("/iui-route", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html",
\r
101 "iui-microservices").run(environment);
\r
103 new AssetsBundle("/api-doc", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc",
\r
104 "index.html", "api-doc").run(environment);
\r
106 new AssetsBundle("/ext", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext",
\r
107 "index.html", "ext").run(environment);
\r
112 final ApiRouteHealthCheck healthCheck =
\r
113 new ApiRouteHealthCheck(configuration.getDefaultWorkspace());
\r
114 environment.healthChecks().register("template", healthCheck);
\r
115 environment.jersey().register(new ApiRouteResource());
\r
116 environment.jersey().register(new IuiRouteResource());
\r
117 environment.jersey().register(new MetricsResource());
\r
118 environment.jersey().register(new CustomRouteResource());
\r
119 environment.jersey().register(new ServiceAccessResource());
\r
120 environment.jersey().register(new MicroServiceResource());
\r
122 config = configuration;
\r
124 initSwaggerConfig(environment, configuration);
\r
125 initRedisConfig(configuration);
\r
126 checkRedisConnect();
\r
127 initMetricsConfig(configuration);
\r
128 initVisualRangeMatches();
\r
130 registerServiceChangeListener();
\r
135 private void initMetricsConfig(ApiRouteAppConfig configuration) {
\r
137 SimpleServerFactory simpleServerFactory =
\r
138 (SimpleServerFactory) configuration.getServerFactory();
\r
139 HttpConnectorFactory httpConnectorFactory =
\r
140 (HttpConnectorFactory) simpleServerFactory.getConnector();
\r
141 MetricsUtil.adminContextPath =
\r
142 "http://127.0.0.1:" + httpConnectorFactory.getPort()
\r
143 + simpleServerFactory.getAdminContextPath() + "/metrics";
\r
146 private void initSwaggerConfig(Environment environment, ApiRouteAppConfig configuration) {
\r
148 environment.jersey().register(new ApiListingResource());
\r
149 environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
\r
151 BeanConfig config = new BeanConfig();
\r
152 config.setTitle("MicroService Bus rest API");
\r
153 config.setVersion("1.0.0");
\r
154 config.setResourcePackage("org.openo.msb.resources");
\r
155 SimpleServerFactory simpleServerFactory =
\r
156 (SimpleServerFactory) configuration.getServerFactory();
\r
157 String basePath = simpleServerFactory.getApplicationContextPath();
\r
158 String rootPath = simpleServerFactory.getJerseyRootPath();
\r
160 rootPath = rootPath.substring(0, rootPath.indexOf("/*"));
\r
163 basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath)
\r
164 .append(rootPath).toString();
\r
166 LOGGER.info("getApplicationContextPath: " + basePath);
\r
167 config.setBasePath(basePath);
\r
168 config.setScan(true);
\r
172 private void initRootPath(){
\r
175 URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json");
\r
176 if (urlRootPath != null) {
\r
177 String path = urlRootPath.getPath();
\r
179 LOGGER.info("read initUrlRootPath:" + path);
\r
181 String fileContent = FileUtil.readFile(path);
\r
182 JSONObject jsonObj = JSONObject.fromObject(fileContent);
\r
183 RouteUtil.IUI_ROOT_PATH=jsonObj.get("iuiRootPath").toString();
\r
184 RouteUtil.API_ROOT_PATH=jsonObj.get("apiRootPath").toString();
\r
186 } catch (Exception e) {
\r
187 // TODO Auto-generated catch block
\r
188 LOGGER.error("read initUrlRootPath Files throw exception", e);
\r
192 private void initRedisConfig(ApiRouteAppConfig configuration) {
\r
194 String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
\r
195 String jarPath = path.substring(0, path.lastIndexOf("/"));
\r
197 LOGGER.info("jarpath: " + jarPath);
\r
198 LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace());
\r
201 jarPath + "/" + configuration.getDefaultWorkspace() + "/"
\r
202 + configuration.getPropertiesDir();
\r
203 String propertiesPath = confDir + "/" + configuration.getPropertiesName();
\r
205 JedisUtil.propertiesPath = propertiesPath;
\r
207 LOGGER.info("propertiesPath: " + propertiesPath);
\r
208 LOGGER.info("confDir: " + confDir);
\r
211 File dirFile = new File(confDir);
\r
213 if (!dirFile.exists()) {
\r
216 } catch (Exception e) {
\r
217 // TODO Auto-generated catch block
\r
218 LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage());
\r
223 File propertiesFile = new File(propertiesPath);
\r
224 if (!propertiesFile.exists()) {
\r
227 propertiesFile.createNewFile();
\r
229 BufferedWriter output = new BufferedWriter(new FileWriter(propertiesFile));
\r
230 StringBuilder contentBuilder = new StringBuilder();
\r
231 contentBuilder.append("redis.host=127.0.0.1\n").append("redis.port=6379\n")
\r
232 .append("#connectionTimeout\n").append("redis.connectionTimeout=2000\n")
\r
233 .append("#redis dbIndex,defaule:0\n")
\r
234 .append("redis.db_index=0\n\n")
\r
235 .append("#--------------redis pool config--------------\n")
\r
236 .append("#maxTotal\n").append("redis.pool.maxTotal=100\n")
\r
237 .append("#maxIdle\n").append("redis.pool.maxIdle=20\n")
\r
238 .append("#maxWaitMillis:ms\n")
\r
239 .append("redis.pool.maxWaitMillis=1000\n")
\r
240 .append("#testOnBorrow\n")
\r
241 .append("redis.pool.testOnBorrow=false\n")
\r
242 .append("#testOnReturn\n")
\r
243 .append("redis.pool.testOnReturn=true\n")
\r
244 .append("#nginx Port\n").append("server.port=10080\n");
\r
246 output.write(contentBuilder.toString());
\r
250 } catch (IOException e) {
\r
251 // TODO Auto-generated catch block
\r
252 LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage());
\r
257 private void checkRedisConnect() {
\r
259 new Thread(new Runnable() {
\r
260 public void run() {
\r
263 if (ApiRouteServiceWrapper.checkRedisConnect() == false) {
\r
265 System.out.println(n
\r
266 + "/10 : Initial Route Configuration——redis connection fail...");
\r
269 Thread.sleep(10000);
\r
270 } catch (InterruptedException e) {
\r
271 LOGGER.error("Thread.sleep throw except:"+e.getMessage());
\r
276 System.out.println("Initial Route Configuration fail,timeout exit");
\r
277 LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit...");
\r
281 System.out.println("starting to initial Route Configuration");
\r
282 // initRouteInfoFromConfig();
\r
283 initRouteInfoFromJson();
\r
284 System.out.println("starting to initial consul Configuration");
\r
285 runConsulClientApp();
\r
299 * @Title: initVisualRangeMatches
\r
300 * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions)
\r
303 private void initVisualRangeMatches(){
\r
305 if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null)
\r
308 URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json");
\r
309 if (visualRangePath != null) {
\r
310 String path = visualRangePath.getPath();
\r
312 LOGGER.info("read initVisualRangeMatches:" + path);
\r
314 String fileContent = FileUtil.readFile(path);
\r
315 JSONObject jsonObj = JSONObject.fromObject(fileContent);
\r
316 String visualRangeArray=jsonObj.get("visualRange").toString();
\r
319 RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ",");
\r
326 RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ",");
\r
328 } catch (Exception e) {
\r
329 // TODO Auto-generated catch block
\r
330 LOGGER.error("read initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e);
\r
335 * @Title: initRouteInfoFromJson
\r
336 * @Description: TODO(按照JSON文件配置初始化route数据)
\r
339 private void initRouteInfoFromJson() {
\r
341 URL apiDocsPath = ApiRouteApp.class.getResource("/ext/initServices");
\r
342 if (apiDocsPath != null) {
\r
343 String path = apiDocsPath.getPath();
\r
345 LOGGER.info("read JsonFilefolder:" + path);
\r
348 File[] files = FileUtil.readFileFolder(path);
\r
349 for (int i = 0; i < files.length; i++) {
\r
350 File file = files[i];
\r
351 if (file.isFile() && file.getName().endsWith(".json")) {
\r
352 LOGGER.info("read JsonFile:" + file.getPath());
\r
353 String fileContent = FileUtil.readFile(file.getPath());
\r
354 saveInitService2redis(fileContent);
\r
356 LOGGER.warn(file.getName() + " is not a right file");
\r
362 } catch (FileNotFoundException e) {
\r
363 // TODO Auto-generated catch block
\r
364 LOGGER.error("read initServices Files throw FileNotFoundException", e);
\r
365 } catch (IOException e) {
\r
366 // TODO Auto-generated catch block
\r
367 LOGGER.error("read initServices Files throw IOexception", e);
\r
378 private void saveInitService2redis(String fileContent) {
\r
380 List<ApiRouteInfo> routeList =
\r
381 (List<ApiRouteInfo>) JacksonJsonUtil.jsonToListBean(fileContent);
\r
382 for (ApiRouteInfo route : routeList) {
\r
383 String url = route.getUrl();
\r
385 if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) {
\r
388 CustomRouteInfo dbCustomRoute =
\r
389 CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(
\r
390 route.getServiceName());
\r
392 catch(ExtendedNotFoundException e){
\r
394 LOGGER.info("initCustomRoute: ServiceName--" + route.getServiceName());
\r
396 CustomRouteInfo customRouteInfo = new CustomRouteInfo();
\r
397 customRouteInfo.setControl(route.getControl());
\r
398 customRouteInfo.setServers(route.getServers());
\r
399 customRouteInfo.setServiceName(route.getServiceName());
\r
400 customRouteInfo.setStatus(route.getStatus());
\r
401 customRouteInfo.setUrl(route.getUrl());
\r
404 CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(
\r
405 customRouteInfo, "");
\r
411 if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) {
\r
415 ApiRouteInfo dbApiRoute =
\r
416 ApiRouteServiceWrapper.getInstance().getApiRouteInstance(
\r
417 route.getServiceName(), route.getVersion());
\r
419 catch(ExtendedNotFoundException e){
\r
420 LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName());
\r
421 ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, "");
\r
425 } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) {
\r
428 IuiRouteInfo dbIuiRoute =
\r
429 IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(
\r
430 route.getServiceName());
\r
432 catch(ExtendedNotFoundException e){
\r
434 LOGGER.info(" initiuiRoute: ServiceName--" + route.getServiceName());
\r
435 IuiRouteInfo iuiRouteInfo = new IuiRouteInfo();
\r
436 iuiRouteInfo.setControl(route.getControl());
\r
437 iuiRouteInfo.setServers(route.getServers());
\r
438 iuiRouteInfo.setServiceName(route.getServiceName());
\r
439 iuiRouteInfo.setStatus(route.getStatus());
\r
441 if(url.equals("/iui/microservices")){
\r
442 iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices");
\r
445 iuiRouteInfo.setUrl(route.getUrl());
\r
448 IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo);
\r
453 LOGGER.error("init Service throw exception——serviceName: " + route.getServiceName()+",url:"+url);
\r
461 } catch (Exception e) {
\r
462 // TODO Auto-generated catch block
\r
463 LOGGER.error("read initServices Files throw exception", e);
\r
471 * The listener registration service changes
\r
473 private void registerServiceChangeListener() {
\r
474 MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener());
\r
477 // Open the consul to monitor subscription service
\r
478 private void runConsulClientApp() {
\r
479 DiscoverInfo config_discoverInfo = config.getDiscoverInfo();
\r
481 ConsulInfo config_consulInfo=config.getConsulInfo();
\r
483 RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled());
\r
485 if (config_discoverInfo.isEnabled()) {
\r
487 if(System.getenv("SDCLIENT_SVC_PORT")==null)
\r
490 RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp());
\r
491 RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort());
\r
496 String discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1];
\r
497 String sdIP=discoverAddress.split(":")[0];
\r
499 .parseInt(discoverAddress.split(":")[1]);
\r
501 RouteUtil.discoverInfo.setIp(sdIP);
\r
502 RouteUtil.discoverInfo.setPort(sdPort);
\r
504 config_consulInfo.setIp(sdIP);
\r
505 config_consulInfo.setPort(sdPort);
\r
512 //Registration service discovery routing
\r
514 ApiRouteInfo discoverApiService=new ApiRouteInfo();
\r
515 discoverApiService.setServiceName("msdiscover");
\r
516 discoverApiService.setUrl("/api/microservices/v1");
\r
517 discoverApiService.setVersion("v1");
\r
518 discoverApiService.setMetricsUrl("/admin/metrics");
\r
519 discoverApiService.setApiJson("/api/microservices/v1/swagger.json");
\r
521 RouteServer[] servers=new RouteServer[1];
\r
522 servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort()));
\r
523 discoverApiService.setServers(servers);
\r
525 ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, "");
\r
528 IuiRouteInfo discoverIUIService=new IuiRouteInfo();
\r
529 discoverIUIService.setServiceName("msdiscover");
\r
530 discoverIUIService.setUrl("/iui/microservices");
\r
531 discoverIUIService.setServers(servers);
\r
532 IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService);
\r
536 ConsulClientApp consulClientApp = new ConsulClientApp(config_consulInfo.getIp(), config_consulInfo.getPort());
\r
537 // Monitor service change
\r
538 consulClientApp.startServiceListen();
\r
539 LOGGER.info("start monitor consul service--" +config_consulInfo.getIp() + ":"
\r
540 + config_consulInfo.getPort());
\r
542 catch(Exception e){
\r
543 LOGGER.error("start monitor consul service fail:"+e.getMessage());
\r