94b29ac0670b464d8ce0aab211a4914f1892b12d
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / ApiRouteApp.java
1 /**
2  * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.openo.msb;
17
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;
26
27 import java.io.BufferedWriter;
28 import java.io.File;
29 import java.io.FileNotFoundException;
30 import java.io.FileWriter;
31 import java.io.IOException;
32 import java.net.URL;
33 import java.util.List;
34
35 import net.sf.json.JSONObject;
36
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;
65
66 import com.fasterxml.jackson.annotation.JsonInclude;
67
68 public class ApiRouteApp extends Application<ApiRouteAppConfig> {
69
70     private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class);
71
72     public static void main(String[] args) throws Exception {
73         new ApiRouteApp().run(args);
74
75     }
76
77     private ApiRouteAppConfig config;
78
79     @Override
80     public String getName() {
81         return " MicroService Bus ";
82     }
83
84     @Override
85     public void initialize(Bootstrap<ApiRouteAppConfig> bootstrap) {
86         
87         
88     }
89
90     @Override
91     public void run(ApiRouteAppConfig configuration, Environment environment) {
92         
93         initRootPath();
94         
95       
96         new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics",
97             "index.html", "iui-metrics").run(environment); 
98         
99         new AssetsBundle("/iui-route",  "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html",
100                 "iui-microservices").run(environment); 
101         
102         new AssetsBundle("/api-doc",  "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc",
103             "index.html", "api-doc").run(environment);
104         
105         new AssetsBundle("/ext",  "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext",
106             "index.html", "ext").run(environment);
107         
108         
109         
110
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());
120
121         config = configuration;
122
123         initSwaggerConfig(environment, configuration);
124         initRedisConfig(configuration);
125         checkRedisConnect();
126         initMetricsConfig(configuration);
127         initVisualRangeMatches();
128
129         registerServiceChangeListener();
130
131
132     }
133
134     private void initMetricsConfig(ApiRouteAppConfig configuration) {
135
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";
143     }
144
145     private void initSwaggerConfig(Environment environment, ApiRouteAppConfig configuration) {
146
147         environment.jersey().register(new ApiListingResource());
148         environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
149
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();
158
159         rootPath = rootPath.substring(0, rootPath.indexOf("/*"));
160
161         basePath =
162                 basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath)
163                         .append(rootPath).toString();
164
165         LOGGER.info("getApplicationContextPath: " + basePath);
166         config.setBasePath(basePath);
167         config.setScan(true);
168     }
169     
170     
171     private void initRootPath(){
172         try {
173             
174             URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json");
175             if (urlRootPath != null) {
176                 String path = urlRootPath.getPath();
177     
178                 LOGGER.info("read initUrlRootPath:" + path);
179               
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();
184                 }
185         } catch (Exception e) {
186             // TODO Auto-generated catch block
187             LOGGER.error("read  initUrlRootPath Files throw exception", e);
188         }
189         
190     }
191     private void initRedisConfig(ApiRouteAppConfig configuration) {
192
193         String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
194         String jarPath = path.substring(0, path.lastIndexOf("/"));
195
196         LOGGER.info("jarpath: " + jarPath);
197         LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace());
198
199         String confDir =
200                 jarPath + "/" + configuration.getDefaultWorkspace() + "/"
201                         + configuration.getPropertiesDir();
202         String propertiesPath = confDir + "/" + configuration.getPropertiesName();
203
204         JedisUtil.propertiesPath = propertiesPath;
205
206         LOGGER.info("propertiesPath: " + propertiesPath);
207         LOGGER.info("confDir: " + confDir);
208
209         try {
210             File dirFile = new File(confDir);
211
212             if (!dirFile.exists()) {
213                 dirFile.mkdirs();
214             }
215         } catch (Exception e) {
216             // TODO Auto-generated catch block
217             LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage());
218         }
219
220
221         try {
222             File propertiesFile = new File(propertiesPath);
223             if (!propertiesFile.exists()) {
224
225
226                 propertiesFile.createNewFile();
227
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");
244
245                 output.write(contentBuilder.toString());
246                 output.close();
247
248             }
249         } catch (IOException e) {
250             // TODO Auto-generated catch block
251             LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage());
252         }
253     }
254
255
256     private void checkRedisConnect() {
257
258         new Thread(new Runnable() {
259             public void run() {
260                 int n = 0;
261                 while (true) {
262                     if (ApiRouteServiceWrapper.checkRedisConnect() == false) {
263                         n++;
264                         System.out.println(n
265                                 + "/10 : Initial Route Configuration——redis connection fail...");
266
267                         try {
268                             Thread.sleep(10000);
269                         } catch (InterruptedException e) {
270                             LOGGER.error("Thread.sleep throw except:"+e.getMessage());
271                         }
272
273
274                         if (n >= 10) {
275                             System.out.println("Initial Route Configuration fail,timeout exit");
276                             LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit...");
277                             break;
278                         }
279                     } else {
280                         System.out.println("starting to initial Route Configuration");
281                         // initRouteInfoFromConfig();
282                         initRouteInfoFromJson();
283                         System.out.println("starting to initial consul Configuration");
284                         runConsulClientApp();
285
286                         break;
287                     }
288                 }
289
290             }
291         }).start();
292     }
293
294
295     
296
297     /**
298      * @Title: initVisualRangeMatches
299      * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions)
300      * @return: void
301      */
302     private void initVisualRangeMatches(){
303         try {
304             if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null)
305             {
306             
307             URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json");
308             if (visualRangePath != null) {
309                 String path = visualRangePath.getPath();
310     
311                 LOGGER.info("read initVisualRangeMatches:" + path);
312               
313                 String fileContent = FileUtil.readFile(path);
314                 JSONObject jsonObj = JSONObject.fromObject(fileContent);
315                 String visualRangeArray=jsonObj.get("visualRange").toString();
316                 
317             
318                 RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ",");  
319              
320                 
321                
322                 }
323             }
324             else{
325                 RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ",");
326             }
327         } catch (Exception e) {
328             // TODO Auto-generated catch block
329             LOGGER.error("read  initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e);
330         }
331     }
332
333     /**
334      * @Title: initRouteInfoFromJson
335      * @Description: TODO(按照JSON文件配置初始化route数据)
336      * @return: void
337      */
338     private void initRouteInfoFromJson() {
339
340         URL apiDocsPath = ApiRouteApp.class.getResource("/ext/initServices");
341         if (apiDocsPath != null) {
342             String path = apiDocsPath.getPath();
343
344             LOGGER.info("read JsonFilefolder:" + path);
345
346             try {
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);
354                     } else {
355                         LOGGER.warn(file.getName() + " is not a right file");
356                     }
357                 }
358
359
360
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);
367             }
368
369         }
370
371
372
373     }
374
375
376
377     private void saveInitService2redis(String fileContent) {
378         try {
379             List<ApiRouteInfo> routeList =
380                     (List<ApiRouteInfo>) JacksonJsonUtil.jsonToListBean(fileContent);
381             for (ApiRouteInfo route : routeList) {
382                 String url = route.getUrl();
383
384                 if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) {
385                     
386                     try{
387                     CustomRouteInfo dbCustomRoute =
388                             CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(
389                                     route.getServiceName());
390                     }
391                     catch(ExtendedNotFoundException e){
392
393                         LOGGER.info("initCustomRoute: ServiceName--" + route.getServiceName());
394
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());
401
402
403                         CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(
404                                 customRouteInfo, "");
405
406
407                     }
408                 } else {
409
410                     if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) {
411
412
413                         try{
414                         ApiRouteInfo dbApiRoute =
415                                 ApiRouteServiceWrapper.getInstance().getApiRouteInstance(
416                                         route.getServiceName(), route.getVersion());
417                         }
418                         catch(ExtendedNotFoundException e){
419                             LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName());
420                             ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, "");
421                         }
422
423                        
424                     } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url)  || url.equals("/iui/microservices")) {
425                         
426                         try{
427                         IuiRouteInfo dbIuiRoute =
428                                 IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(
429                                         route.getServiceName());
430                         }
431                         catch(ExtendedNotFoundException e){
432                     
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());
439                             
440                             if(url.equals("/iui/microservices")){
441                                 iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices");
442                             }
443                             else{
444                             iuiRouteInfo.setUrl(route.getUrl());
445                             }
446
447                             IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo);
448
449                         }
450
451                     } else {
452                         LOGGER.error("init Service throw exception——serviceName: " + route.getServiceName()+",url:"+url);
453                     }
454                 }
455
456
457
458             }
459
460         } catch (Exception e) {
461             // TODO Auto-generated catch block
462             LOGGER.error("read  initServices Files throw exception", e);
463         }
464
465     }
466
467
468
469     /**
470      * The listener registration service changes
471      */
472     private void registerServiceChangeListener() {
473         MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener());
474     }
475
476     // Open the consul to monitor subscription service
477     private void runConsulClientApp() {
478         DiscoverInfo config_discoverInfo = config.getDiscoverInfo();
479         
480         ConsulInfo config_consulInfo=config.getConsulInfo();
481         
482         RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled());        
483         
484         if (config_discoverInfo.isEnabled()) {
485             try{
486             if(System.getenv("SDCLIENT_SVC_PORT")==null)
487             {
488                 //yml          
489                 RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp()); 
490                 RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort());
491                 
492             }
493             else{
494                
495                  String  discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1];
496                  String sdIP=discoverAddress.split(":")[0];
497                  int sdPort=Integer
498                          .parseInt(discoverAddress.split(":")[1]);
499                  
500                  RouteUtil.discoverInfo.setIp(sdIP);
501                  RouteUtil.discoverInfo.setPort(sdPort);
502                  
503                  config_consulInfo.setIp(sdIP);
504                  config_consulInfo.setPort(sdPort);
505              
506                 
507             }
508             
509            
510                
511                 //Registration service discovery routing
512                 //api
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");
519                 
520                 RouteServer[] servers=new RouteServer[1];
521                 servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort()));
522                 discoverApiService.setServers(servers);
523              
524                 ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, "");
525                
526                 //iui
527                 IuiRouteInfo discoverIUIService=new IuiRouteInfo();
528                 discoverIUIService.setServiceName("msdiscover");
529                 discoverIUIService.setUrl("/iui/microservices");
530                 discoverIUIService.setServers(servers);
531                 IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService);
532                 
533                
534
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());
540             }
541             catch(Exception e){
542                 LOGGER.error("start monitor consul service fail:"+e.getMessage()); 
543             }
544         }
545         
546        
547     }
548
549 }