From 672f3d40be83d9e380fd7be4b674d5e8d5fa36de Mon Sep 17 00:00:00 2001 From: HuabingZhao Date: Tue, 25 Jul 2017 15:18:33 +0800 Subject: [PATCH] Divide the MSB source codes into two repos Change-Id: Ie76d545b214a8ce5191f215350a623e1529983d9 Issue-id: MSB-5 Signed-off-by: HuabingZhao --- .gitattributes | 1 + .gitignore | 10 + .gitreview | 4 - License.txt | 473 -- README.md | 19 +- .../apiroute-service/dependency-reduced-pom.xml | 121 + apiroute/apiroute-service/pom.xml | 174 + .../java/org/onap/msb/apiroute/ApiRouteApp.java | 131 + .../org/onap/msb/apiroute}/ApiRouteAppConfig.java | 46 +- .../org/onap/msb/apiroute/SyncDataManager.java | 135 + .../org/onap/msb/apiroute/api/ApiRouteInfo.java | 107 + .../msb/apiroute}/api/CustomDateSerializer.java | 4 +- .../org/onap/msb/apiroute/api/CustomRouteInfo.java | 11 +- .../org/onap/msb/apiroute}/api/DiscoverInfo.java | 10 +- .../org/onap/msb/apiroute/api/IuiRouteInfo.java | 16 +- .../msb/apiroute/api/MicroServiceFullInfo.java | 195 + .../main/java/org/onap/msb/apiroute}/api/Node.java | 39 +- .../onap/msb/apiroute/api/PublishFullAddress.java | 48 + .../java/org/onap/msb/apiroute/api/RouteInfo.java | 179 + .../org/onap/msb/apiroute}/api/RouteServer.java | 19 +- .../ExtendedInternalServerErrorException.java | 4 +- .../api/exception/ExtendedNotFoundException.java | 4 +- .../exception/UnprocessableEntityException.java | 18 + .../msb/apiroute}/health/ApiRouteHealthCheck.java | 33 +- .../msb/apiroute/health/ConsulLinkHealthCheck.java | 132 + .../msb/apiroute/health/OpenRestyHealthCheck.java | 39 + .../onap/msb/apiroute/health/RedisHealthCheck.java | 160 + .../msb/apiroute}/resources/ApiRouteResource.java | 113 +- .../apiroute}/resources/CustomRouteResource.java | 58 +- .../msb/apiroute}/resources/IuiRouteResource.java | 67 +- .../apiroute}/resources/MicroServiceResource.java | 135 +- .../apiroute/wrapper/ApiRouteServiceWrapper.java | 273 + .../wrapper/CustomRouteServiceWrapper.java | 217 + .../apiroute/wrapper/InitRouteServiceWrapper.java | 416 ++ .../apiroute/wrapper/IuiRouteServiceWrapper.java | 221 + .../msb/apiroute/wrapper/MicroServiceWrapper.java | 398 ++ .../wrapper/consulextend/CatalogClient.java | 87 + .../msb/apiroute/wrapper/consulextend/Consul.java | 97 + .../wrapper/consulextend/HealthClient.java | 112 + .../consulextend/async/ConsulResponseCallback.java | 33 + .../consulextend/async/ConsulResponseHeader.java | 27 + .../consulextend/async/OriginalConsulResponse.java | 27 + .../wrapper/consulextend/cache/ConsulCache.java | 301 + .../consulextend/cache/ServiceHealthCache.java | 65 + .../consulextend/cache/ServicesCatalogCache.java | 39 + ...heckServiceDataEmptyAndAutoStopWatchFilter.java | 98 + .../expose/CheckTagAndAutoStopWatchFilter.java | 96 + .../consulextend/expose/ConsulIndexFilter.java | 48 + .../expose/ServiceModifyIndexFilter.java | 121 + .../expose/WatchCatalogServicesTask.java | 90 + .../expose/WatchServiceHealthTask.java | 128 + .../wrapper/consulextend/expose/WatchTask.java | 87 + .../consulextend/expose/WriteBufferHandler.java | 36 + .../wrapper/consulextend/model/health/Service.java | 39 + .../consulextend/model/health/ServiceHealth.java | 30 + .../apiroute/wrapper/consulextend/util/Http.java | 281 + .../msb/apiroute/wrapper/dao/DAOConstants.java | 6 + .../onap/msb/apiroute/wrapper/dao/DAOFactory.java | 18 + .../apiroute/wrapper/dao/RedisAccessWrapper.java | 133 + .../msb/apiroute/wrapper/dao/route/IRouteDAO.java | 18 + .../apiroute/wrapper/dao/route/RouteDAOImpl.java | 63 + .../apiroute/wrapper/dao/route/bean/Metadata.java | 48 + .../msb/apiroute/wrapper/dao/route/bean/Node.java | 32 + .../apiroute/wrapper/dao/route/bean/RouteInfo.java | 79 + .../msb/apiroute/wrapper/dao/route/bean/Spec.java | 52 + .../apiroute/wrapper/dao/service/IServiceDAO.java | 17 + .../wrapper/dao/service/ServiceDAOImpl.java | 59 + .../wrapper/dao/service/bean/Metadata.java | 50 + .../apiroute/wrapper/dao/service/bean/Node.java | 32 + .../wrapper/dao/service/bean/ServiceInfo.java | 76 + .../apiroute/wrapper/dao/service/bean/Spec.java | 44 + .../onap/msb/apiroute/wrapper/queue/BaseQueue.java | 36 + .../msb/apiroute/wrapper/queue/QueueManager.java | 65 + .../apiroute/wrapper/queue/ServiceConsumer.java | 167 + .../msb/apiroute/wrapper/queue/ServiceData.java | 53 + .../apiroute/wrapper/queue/ServiceListCache.java | 35 + .../wrapper/queue/ServiceListConsumer.java | 209 + .../apiroute/wrapper/queue/ServiceListQueue.java | 59 + .../msb/apiroute/wrapper/queue/ServiceQueue.java | 45 + .../apiroute/wrapper/service/ApiRouteService.java | 159 + .../wrapper/service/CustomRouteService.java | 152 + .../apiroute/wrapper/service/IuiRouteService.java | 151 + .../wrapper/service/MicroServiceFullService.java | 220 + .../IMicroServiceChangeListener.java | 22 +- .../MicroServiceChangeListener.java | 779 +++ .../wrapper/serviceListener/RouteNotify.java | 77 + .../onap/msb/apiroute/wrapper/util/CommonUtil.java | 76 + .../onap/msb/apiroute/wrapper/util/ConfigUtil.java | 446 ++ .../onap/msb/apiroute}/wrapper/util/FileUtil.java | 23 +- .../msb/apiroute/wrapper/util/HttpClientUtil.java | 117 + .../msb/apiroute/wrapper/util/HttpGetResult.java | 19 + .../onap/msb/apiroute/wrapper/util/Jackson.java | 28 + .../msb/apiroute/wrapper/util/JacksonJsonUtil.java | 110 + .../onap/msb/apiroute/wrapper/util/JedisUtil.java | 208 + .../apiroute}/wrapper/util/MicroServiceUtil.java | 51 +- .../msb/apiroute}/wrapper/util/RegExpTestUtil.java | 47 +- .../onap/msb/apiroute/wrapper/util/RouteUtil.java | 345 ++ .../msb/apiroute/wrapper/util/ServiceFilter.java | 515 ++ .../main/resources/api-doc/META-INF/MANIFEST.MF | 0 .../src/main/resources/api-doc/WEB-INF/web.xml | 40 + .../src/main/resources/api-doc/css/reset.css | 18 - .../src/main/resources/api-doc/css/screen.css | 18 - .../src/main/resources/api-doc/css/typography.css | 18 - .../api-doc/fonts/droid-sans-v6-latin-700.eot | Bin .../api-doc/fonts/droid-sans-v6-latin-700.svg | 0 .../api-doc/fonts/droid-sans-v6-latin-700.ttf | Bin .../api-doc/fonts/droid-sans-v6-latin-700.woff | Bin .../api-doc/fonts/droid-sans-v6-latin-700.woff2 | Bin .../api-doc/fonts/droid-sans-v6-latin-regular.eot | Bin .../api-doc/fonts/droid-sans-v6-latin-regular.svg | 0 .../api-doc/fonts/droid-sans-v6-latin-regular.ttf | Bin .../api-doc/fonts/droid-sans-v6-latin-regular.woff | Bin .../fonts/droid-sans-v6-latin-regular.woff2 | Bin .../resources/api-doc/images/explorer_icons.png | Bin .../main/resources/api-doc/images/logo_small.png | Bin .../resources/api-doc/images/pet_store_api.png | Bin .../src/main/resources/api-doc/images/throbber.gif | Bin .../main/resources/api-doc/images/wordnik_api.png | Bin .../src/main/resources/api-doc/index.html | 241 +- .../iframeResizer.contentWindow.min.js | 0 .../api-doc}/js/iframeResizer/iframeResizer.min.js | 0 .../src/main/resources/api-doc/js/tools.js | 1054 ++++ .../src/main/resources/api-doc/lib/backbone-min.js | 18 - .../main/resources/api-doc/lib/handlebars-2.0.0.js | 1 - .../resources/api-doc/lib/highlight.7.3.pack.js | 1 - .../main/resources/api-doc/lib/jquery-1.8.0.min.js | 0 .../resources/api-doc/lib/jquery.ba-bbq.min.js | 8 + .../resources/api-doc/lib/jquery.slideto.min.js | 0 .../resources/api-doc/lib/jquery.wiggle.min.js | 0 .../src/main/resources/api-doc/lib/marked.js | 22 +- .../src/main/resources/api-doc/lib/shred.bundle.js | 1 - .../main/resources/api-doc/lib/shred/content.js | 19 +- .../main/resources/api-doc/lib/swagger-client.js | 1 - .../main/resources/api-doc/lib/swagger-oauth.js | 1 - .../main/resources/api-doc/lib/underscore-min.js | 1 - .../src/main/resources/api-doc/o2c.html | 20 + .../src/main/resources/api-doc/swagger-ui.js | 0 .../src/main/resources/api-doc/swagger-ui.min.js | 0 .../apiroute-service/src/main/resources/banner.txt | 5 + .../main/resources/iui-route}/css/animate.min.css | 0 .../src/main/resources/iui-route/css/base.css | 54 + .../src/main/resources/iui-route/css/chart.css | 16 + .../src/main/resources/iui-route/css/newRoute.css | 613 ++- .../src/main/resources/iui-route/css/route.css | 1285 +++-- .../src/main/resources/iui-route/default.html | 177 + .../iui-route/i18n/loadi18nApp_iui-route_view.js | 9 +- .../i18n/msb-iui-route-i18n-en-US.properties | 166 + .../i18n/msb-iui-route-i18n-zh-CN.properties | 160 + .../resources/iui-route/img/checkbox-checked.png | Bin .../main/resources/iui-route/img/checkbox-init.png | Bin .../main/resources/iui-route/img/details_close.png | Bin .../main/resources/iui-route/img/details_open.png | Bin .../src/main/resources/iui-route/img/down.png | Bin .../iui-route}/img/loading-spinner-grey.gif | Bin .../src/main/resources/iui-route/img/logo.png | Bin 0 -> 4762 bytes .../iui-route/img/sidebar-toggler-grey.jpg | Bin .../src/main/resources/iui-route}/img/throbber.gif | Bin .../src/main/resources/iui-route/img/up.png | Bin .../main/resources/iui-route/img/zte_logo_16.gif | Bin .../src/main/resources/iui-route/index.html | 2066 ++++--- .../src/main/resources/iui-route}/js/avalon.js | 1 - .../resources/iui-route/js/bootbox/bootbox.min.js | 0 .../resources/iui-route/js/bootstrap-growl.min.js | 0 .../iui-route/js/bootstrap/css/bootstrap-dt.css | 6 + .../iui-route/js/bootstrap/css/bootstrap.min.css | 6 + .../iui-route/js/bootstrap/js/bootstrap.js | 6 + .../iui-route}/js/bootstrap/js/bootstrap.min.js | 10 +- .../js/bootstrap/js/bootstrap2-typeahead.min.js | 1 + .../js/dataTables/dataTables.bootstrap.css | 1 - .../js/dataTables/dataTables.bootstrap.min.js | 0 .../js/dataTables/jquery.dataTables.min.js | 0 .../iui-route/js/echarts/echarts.common.min.js | 29 + .../resources/iui-route/js/echarts/macarons.js | 540 ++ .../iui-route}/js/fontAwesome/css/font-awesome.css | 0 .../js/fontAwesome/css/font-awesome.css.map | 0 .../js/fontAwesome/css/font-awesome.min.css | 3 + .../js/fontAwesome/fonts/FontAwesome.otf | Bin .../js/fontAwesome/fonts/fontawesome-webfont.eot | Bin .../js/fontAwesome/fonts/fontawesome-webfont.svg | 0 .../js/fontAwesome/fonts/fontawesome-webfont.ttf | Bin .../js/fontAwesome/fonts/fontawesome-webfont.woff | Bin .../js/fontAwesome/fonts/fontawesome-webfont.woff2 | Bin .../iui-route}/js/fontAwesome/less/animated.less | 0 .../js/fontAwesome/less/bordered-pulled.less | 0 .../iui-route}/js/fontAwesome/less/core.less | 0 .../js/fontAwesome/less/fixed-width.less | 0 .../js/fontAwesome/less/font-awesome.less | 0 .../iui-route}/js/fontAwesome/less/icons.less | 0 .../iui-route}/js/fontAwesome/less/larger.less | 0 .../iui-route}/js/fontAwesome/less/list.less | 0 .../iui-route}/js/fontAwesome/less/mixins.less | 0 .../iui-route}/js/fontAwesome/less/path.less | 0 .../js/fontAwesome/less/rotated-flipped.less | 0 .../iui-route}/js/fontAwesome/less/stacked.less | 0 .../iui-route}/js/fontAwesome/less/variables.less | 0 .../iui-route}/js/fontAwesome/scss/_animated.scss | 0 .../js/fontAwesome/scss/_bordered-pulled.scss | 0 .../iui-route}/js/fontAwesome/scss/_core.scss | 0 .../js/fontAwesome/scss/_fixed-width.scss | 0 .../iui-route}/js/fontAwesome/scss/_icons.scss | 0 .../iui-route}/js/fontAwesome/scss/_larger.scss | 0 .../iui-route}/js/fontAwesome/scss/_list.scss | 0 .../iui-route}/js/fontAwesome/scss/_mixins.scss | 0 .../iui-route}/js/fontAwesome/scss/_path.scss | 0 .../js/fontAwesome/scss/_rotated-flipped.scss | 0 .../iui-route}/js/fontAwesome/scss/_stacked.scss | 0 .../iui-route}/js/fontAwesome/scss/_variables.scss | 0 .../js/fontAwesome/scss/font-awesome.scss | 0 .../iframeResizer.contentWindow.min.js | 0 .../js/iframeResizer/iframeResizer.min.js | 0 .../js/jquery-validation/additional-methods.js | 20 +- .../js/jquery-validation/additional-methods.min.js | 0 .../js/jquery-validation/jquery.validate.js | 0 .../js/jquery-validation/jquery.validate.min.js | 0 .../jquery-validation/localization/messages_ar.js | 1 - .../localization/messages_ar.min.js | 0 .../jquery-validation/localization/messages_bg.js | 18 - .../localization/messages_bg.min.js | 0 .../jquery-validation/localization/messages_ca.js | 18 - .../localization/messages_ca.min.js | 0 .../jquery-validation/localization/messages_cs.js | 18 - .../localization/messages_cs.min.js | 0 .../jquery-validation/localization/messages_da.js | 18 - .../localization/messages_da.min.js | 0 .../jquery-validation/localization/messages_de.js | 18 - .../localization/messages_de.min.js | 0 .../jquery-validation/localization/messages_el.js | 18 - .../localization/messages_el.min.js | 0 .../jquery-validation/localization/messages_es.js | 18 - .../localization/messages_es.min.js | 0 .../localization/messages_es_AR.js | 18 - .../localization/messages_es_AR.min.js | 0 .../jquery-validation/localization/messages_et.js | 18 - .../localization/messages_et.min.js | 0 .../jquery-validation/localization/messages_eu.js | 18 - .../localization/messages_eu.min.js | 0 .../jquery-validation/localization/messages_fa.js | 18 - .../localization/messages_fa.min.js | 0 .../jquery-validation/localization/messages_fi.js | 18 - .../localization/messages_fi.min.js | 0 .../jquery-validation/localization/messages_fr.js | 18 - .../localization/messages_fr.min.js | 0 .../jquery-validation/localization/messages_gl.js | 18 - .../localization/messages_gl.min.js | 0 .../jquery-validation/localization/messages_he.js | 18 - .../localization/messages_he.min.js | 0 .../jquery-validation/localization/messages_hr.js | 18 - .../localization/messages_hr.min.js | 0 .../jquery-validation/localization/messages_hu.js | 18 - .../localization/messages_hu.min.js | 0 .../jquery-validation/localization/messages_id.js | 18 - .../localization/messages_id.min.js | 0 .../jquery-validation/localization/messages_is.js | 18 - .../localization/messages_is.min.js | 0 .../jquery-validation/localization/messages_it.js | 18 - .../localization/messages_it.min.js | 0 .../jquery-validation/localization/messages_ja.js | 18 - .../localization/messages_ja.min.js | 0 .../jquery-validation/localization/messages_ka.js | 18 - .../localization/messages_ka.min.js | 0 .../jquery-validation/localization/messages_kk.js | 18 - .../localization/messages_kk.min.js | 0 .../jquery-validation/localization/messages_ko.js | 18 - .../localization/messages_ko.min.js | 0 .../jquery-validation/localization/messages_lt.js | 18 - .../localization/messages_lt.min.js | 0 .../jquery-validation/localization/messages_lv.js | 18 - .../localization/messages_lv.min.js | 0 .../jquery-validation/localization/messages_my.js | 18 - .../localization/messages_my.min.js | 0 .../jquery-validation/localization/messages_nl.js | 18 - .../localization/messages_nl.min.js | 0 .../jquery-validation/localization/messages_no.js | 18 - .../localization/messages_no.min.js | 0 .../jquery-validation/localization/messages_pl.js | 18 - .../localization/messages_pl.min.js | 0 .../localization/messages_pt_BR.js | 18 - .../localization/messages_pt_BR.min.js | 0 .../localization/messages_pt_PT.js | 18 - .../localization/messages_pt_PT.min.js | 0 .../jquery-validation/localization/messages_ro.js | 18 - .../localization/messages_ro.min.js | 0 .../jquery-validation/localization/messages_ru.js | 18 - .../localization/messages_ru.min.js | 0 .../jquery-validation/localization/messages_si.js | 18 - .../localization/messages_si.min.js | 0 .../jquery-validation/localization/messages_sk.js | 18 - .../localization/messages_sk.min.js | 0 .../jquery-validation/localization/messages_sl.js | 18 - .../localization/messages_sl.min.js | 0 .../jquery-validation/localization/messages_sr.js | 18 - .../localization/messages_sr.min.js | 0 .../localization/messages_sr_lat.js | 18 - .../localization/messages_sr_lat.min.js | 0 .../jquery-validation/localization/messages_sv.js | 18 - .../localization/messages_sv.min.js | 0 .../jquery-validation/localization/messages_th.js | 18 - .../localization/messages_th.min.js | 0 .../jquery-validation/localization/messages_tj.js | 18 - .../localization/messages_tj.min.js | 0 .../jquery-validation/localization/messages_tr.js | 18 - .../localization/messages_tr.min.js | 0 .../jquery-validation/localization/messages_uk.js | 18 - .../localization/messages_uk.min.js | 0 .../jquery-validation/localization/messages_vi.js | 18 - .../localization/messages_vi.min.js | 0 .../jquery-validation/localization/messages_zh.js | 18 - .../localization/messages_zh.min.js | 0 .../localization/messages_zh_TW.js | 18 - .../localization/messages_zh_TW.min.js | 0 .../jquery-validation/localization/methods_de.js | 22 + .../localization/methods_de.min.js | 0 .../localization/methods_es_CL.js | 22 + .../localization/methods_es_CL.min.js | 0 .../jquery-validation/localization/methods_fi.js | 22 + .../localization/methods_fi.min.js | 0 .../jquery-validation/localization/methods_nl.js | 19 + .../localization/methods_nl.min.js | 0 .../jquery-validation/localization/methods_pt.js | 19 + .../localization/methods_pt.min.js | 0 .../js/jquery.i18n/jquery.i18n.properties-1.0.9.js | 1 - .../iui-route}/js/jquery/jquery-1.10.2.min.js | 0 .../main/resources/iui-route/js/routeController.js | 3771 +++++++------ .../src/main/resources/iui-route/js/routeFunc.js | 1294 +++-- .../src/main/resources/iui-route/js/routeUtil.js | 118 +- .../src/main/resources/iui-route/js/statusUtil.js | 428 ++ .../org/onap/msb/apiroute/SyncDataManagerTest.java | 56 + .../apiroute/health/ApiRouteHealthCheckTest.java | 69 + .../apiroute/health/ConsulLinkHealthCheckTest.java | 103 + .../apiroute/health/OpenRestyHealthCheckTest.java | 77 + .../msb/apiroute/health/RedisHealthCheckTest.java | 77 + .../wrapper/ApiRouteServiceWrapperTest.java | 252 + .../wrapper/CustomRouteServiceWrapperTest.java | 208 + .../wrapper/InitRouteServiceWrapperTest.java | 241 + .../wrapper/IuiRouteServiceWrapperTest.java | 212 + .../apiroute/wrapper/MicroServiceWrapperTest.java | 294 + .../apiroute/wrapper/consulextend/ConsulTest.java | 149 + .../consulextend/cache/ServiceHealthCacheTest.java | 24 + .../cache/ServicesCatalogCacheTest.java | 15 + ...ServiceDataEmptyAndAutoStopWatchFilterTest.java | 53 + .../expose/CheckTagAndAutoStopWatchFilterTest.java | 70 + .../consulextend/expose/ConsulIndexFilterTest.java | 42 + .../expose/ServiceModifyIndexFilterTest.java | 114 + .../expose/WatchCatalogServicesTaskTest.java | 138 + .../expose/WatchServiceHealthTaskTest.java | 156 + .../expose/WriteBufferHandlerTest.java | 46 + .../model/health/ServiceHealthTest.java | 54 + .../consulextend/model/health/ServiceTest.java | 32 + .../wrapper/consulextend/util/HttpTest.java | 80 + .../apiroute/wrapper/queue/QueueManagerTest.java | 178 + .../wrapper/service/ApiRouteServiceTest.java | 251 + .../wrapper/service/CustomRouteServiceTest.java | 241 + .../wrapper/service/IuiRouteServiceTest.java | 221 + .../service/MicroServiceFullServiceTest.java | 413 ++ .../MicroServiceChangeListenerTest.java | 666 +++ .../msb/apiroute/wrapper/util/CommonUtilTest.java | 61 + .../msb/apiroute/wrapper/util/ConfigUtilTest.java | 214 + .../apiroute/wrapper/util/HttpClientUtilTest.java | 29 + .../apiroute/wrapper/util/JacksonJsonUtilTest.java | 94 + .../msb/apiroute/wrapper/util/JedisUtilTest.java | 20 + .../wrapper/util/MicroServiceUtilTest.java | 45 + .../apiroute/wrapper/util/RegExpTestUtilTest.java | 96 + .../msb/apiroute/wrapper/util/RouteUtilTest.java | 373 ++ .../apiroute/wrapper/util/ServiceFilterTest.java | 210 + .../initApiGatewayConfig/initApiGatewayConfig.json | 3 + .../initRouteLabels/initRouteLabelsMatches.json | 12 + .../initRouteLabelsMatches.json.sample | 12 + .../test/resources/ext/initRouteLabels/readme.txt | 17 + .../resources/ext/initRouteWay/initRouteWay.json | 3 + .../src/test/resources/ext/initRouteWay/readme.txt | 5 + .../src/test/resources}/ext/initServices/msb.json | 97 +- .../test/resources}/ext/initServices/readme.txt | 143 +- .../resources}/ext/initSwaggerJson/api-doc1.json | 0 .../resources}/ext/initSwaggerJson/api-doc2.json | 0 .../ext/initUrlRootPath/initUrlRootPath.json | 4 + .../test/resources/ext/redisConf/redis.properties | 18 + .../wrapper/consulextend/util/serviceslist.json | 1 + .../apiroute-standalone/pom.xml | 53 +- .../assembly/resources/apiroute/conf/apiroute.yml | 47 + .../initApiGatewayConfig/initApiGatewayConfig.json | 3 + .../initRouteLabels/initRouteLabelsMatches.json | 7 + .../initRouteLabelsMatches.json.sample | 12 + .../apiroute/ext/initRouteLabels/readme.txt | 17 + .../apiroute/ext/initRouteWay/initRouteWay.json | 3 + .../resources/apiroute/ext/initRouteWay/readme.txt | 5 + .../resources/apiroute/ext/initServices/msb.json | 31 + .../resources/apiroute/ext/initServices/readme.txt | 63 + .../apiroute/ext/initSwaggerJson/api-doc1.json | 1 + .../apiroute/ext/initSwaggerJson/api-doc2.json | 1 + .../ext/initUrlRootPath/initUrlRootPath.json | 4 + .../apiroute/ext/redisConf/redis.properties | 18 + .../src/assembly/resources}/apiroute/run.sh | 52 +- .../src/assembly/resources/apiroute/setenv.sh | 10 + .../src/assembly/resources/apiroute/stop.sh | 59 + {msb-parent/msbparent => apiroute}/pom.xml | 218 +- build4docker.sh | 55 + ci/build_docker_image.sh | 36 + distributions/msb-apigateway/pom.xml | 191 + .../src/assembly/resources/shutdown.sh | 16 +- .../src/assembly/resources}/startup.sh | 28 +- .../src/assembly/resources/startup4docker.sh | 36 + .../msb-apigateway/src/main/docker/Dockerfile | 6 + distributions/pom.xml | 27 + msb-core/apiroute/apiroute-service/pom.xml | 165 - .../src/main/java/org/openo/msb/ApiRouteApp.java | 549 -- .../main/java/org/openo/msb/ConsulClientApp.java | 451 -- .../main/java/org/openo/msb/api/ApiRouteInfo.java | 136 - .../main/java/org/openo/msb/api/ConsulInfo.java | 38 - .../java/org/openo/msb/api/CustomRouteInfo.java | 102 - .../main/java/org/openo/msb/api/IuiRouteInfo.java | 102 - .../main/java/org/openo/msb/api/MetricsInfo.java | 191 - .../org/openo/msb/api/MicroServiceFullInfo.java | 44 - .../java/org/openo/msb/api/MicroServiceInfo.java | 38 - .../src/main/java/org/openo/msb/api/NodeInfo.java | 74 - .../src/main/java/org/openo/msb/api/Service.java | 104 - .../java/org/openo/msb/api/ServiceAccessInfo.java | 88 - .../org/openo/msb/resources/MetricsResource.java | 48 - .../openo/msb/resources/ServiceAccessResource.java | 64 - .../openo/msb/wrapper/ApiRouteServiceWrapper.java | 565 -- .../msb/wrapper/CustomRouteServiceWrapper.java | 415 -- .../openo/msb/wrapper/IuiRouteServiceWrapper.java | 392 -- .../openo/msb/wrapper/MetricsServiceWrapper.java | 91 - .../org/openo/msb/wrapper/MicroServiceWrapper.java | 515 -- .../openo/msb/wrapper/ServiceAccessWrapper.java | 171 - .../openo/msb/wrapper/consul/CatalogClient.java | 300 - .../java/org/openo/msb/wrapper/consul/Consul.java | 314 -- .../openo/msb/wrapper/consul/ConsulException.java | 57 - .../org/openo/msb/wrapper/consul/HealthClient.java | 262 - .../consul/async/ConsulResponseCallback.java | 57 - .../msb/wrapper/consul/cache/CatalogCache.java | 69 - .../msb/wrapper/consul/cache/ConsulCache.java | 245 - .../msb/wrapper/consul/cache/ConsulCache4Map.java | 257 - .../msb/wrapper/consul/cache/HealthCache.java | 69 - .../msb/wrapper/consul/cache/ServiceCache.java | 49 - .../msb/wrapper/consul/model/ConsulResponse.java | 95 - .../wrapper/consul/model/catalog/CatalogNode.java | 56 - .../consul/model/catalog/CatalogService.java | 67 - .../consul/model/catalog/ImmutableCatalogNode.java | 305 - .../model/catalog/ImmutableCatalogService.java | 625 --- .../wrapper/consul/model/catalog/ServiceInfo.java | 62 - .../wrapper/consul/model/health/ImmutableNode.java | 265 - .../consul/model/health/ImmutableService.java | 477 -- .../msb/wrapper/consul/model/health/Node.java | 50 - .../msb/wrapper/consul/model/health/Service.java | 63 - .../wrapper/consul/model/health/ServiceHealth.java | 88 - .../msb/wrapper/consul/option/CatalogOptions.java | 54 - .../msb/wrapper/consul/option/ConsistencyMode.java | 36 - .../consul/option/ImmutableCatalogOptions.java | 250 - .../consul/option/ImmutableQueryOptions.java | 530 -- .../openo/msb/wrapper/consul/option/Options.java | 44 - .../msb/wrapper/consul/option/ParamAdder.java | 38 - .../msb/wrapper/consul/option/QueryOptions.java | 115 - .../consul/util/Base64EncodingDeserializer.java | 60 - .../openo/msb/wrapper/consul/util/ClientUtil.java | 261 - .../org/openo/msb/wrapper/consul/util/Jackson.java | 49 - .../consul/util/ObjectMapperContextResolver.java | 50 - .../wrapper/consul/util/SecondsDeserializer.java | 58 - .../msb/wrapper/consul/util/SecondsSerializer.java | 49 - .../consul/util/UnsignedLongDeserializer.java | 52 - .../MicroServiceChangeListener.java | 291 - .../openo/msb/wrapper/util/JacksonJsonUtil.java | 119 - .../java/org/openo/msb/wrapper/util/JedisUtil.java | 220 - .../org/openo/msb/wrapper/util/MicroServiceDB.java | 428 -- .../java/org/openo/msb/wrapper/util/RouteUtil.java | 134 - .../src/main/resources/api-doc/WEB-INF/web.xml | 44 - .../iframeResizer.contentWindow.min.js | 9 - .../api-doc/js/iframeResizer/iframeResizer.min.js | 8 - .../src/main/resources/api-doc/o2c.html | 40 - .../apiroute-service/src/main/resources/banner.txt | 24 - .../src/main/resources/iui-metrics/css/metrics.css | 159 - .../i18n/loadi18nApp_iui-metrics_view.js | 46 - .../i18n/msb-iui-metrics-i18n-en-US.properties | 85 - .../i18n/msb-iui-metrics-i18n-zh-CN.properties | 81 - .../resources/iui-metrics/img/netnumenLogo.png | Bin 5639 -> 0 bytes .../src/main/resources/iui-metrics/index.html | 259 - .../iui-metrics/js/bootstrap/css/bootstrap-dt.css | 5798 ------------------- .../iui-metrics/js/bootstrap/css/bootstrap.min.css | 1 - .../iui-metrics/js/bootstrap/js/bootstrap.js | 1945 ------- .../js/bootstrap/js/bootstrap2-typeahead.min.js | 20 - .../iui-metrics/js/echarts/echarts-all.js | 36 - .../resources/iui-metrics/js/images/sort_both.png | Bin 5639 -> 0 bytes .../js/jquery.i18n/jquery.i18n.properties-1.0.9.js | 480 -- .../main/resources/iui-metrics/js/metricsChart.js | 420 -- .../resources/iui-metrics/js/metricsController.js | 230 - .../main/resources/iui-metrics/js/metricsUtil.js | 49 - .../main/resources/iui-route/css/animate.min.css | 6 - .../src/main/resources/iui-route/default.html | 144 - .../i18n/msb-iui-route-i18n-en-US.properties | 168 - .../i18n/msb-iui-route-i18n-zh-CN.properties | 163 - .../resources/iui-route/img/conductor-logo.png | Bin 4907 -> 0 bytes .../iui-route/img/loading-spinner-grey.gif | Bin 5203 -> 0 bytes .../src/main/resources/iui-route/img/logo.png | Bin 4907 -> 0 bytes .../main/resources/iui-route/img/netnumenLogo.png | Bin 5639 -> 0 bytes .../main/resources/iui-route/img/openo_logo_16.png | Bin 988 -> 0 bytes .../src/main/resources/iui-route/img/throbber.gif | Bin 9257 -> 0 bytes .../src/main/resources/iui-route/js/avalon.js | 5820 -------------------- .../iui-route/js/bootstrap/js/bootstrap.min.js | 7 - .../js/dataTables/dataTables.bootstrap.css | 309 -- .../js/dataTables/dataTables.bootstrap.min.js | 8 - .../js/dataTables/jquery.dataTables.min.js | 160 - .../iui-route/js/fontAwesome/css/font-awesome.css | 2026 ------- .../js/fontAwesome/css/font-awesome.css.map | 7 - .../js/fontAwesome/css/font-awesome.min.css | 1 - .../iui-route/js/fontAwesome/fonts/FontAwesome.otf | Bin 106260 -> 0 bytes .../js/fontAwesome/fonts/fontawesome-webfont.eot | Bin 68875 -> 0 bytes .../js/fontAwesome/fonts/fontawesome-webfont.svg | 640 --- .../js/fontAwesome/fonts/fontawesome-webfont.ttf | Bin 138204 -> 0 bytes .../js/fontAwesome/fonts/fontawesome-webfont.woff | Bin 81284 -> 0 bytes .../js/fontAwesome/fonts/fontawesome-webfont.woff2 | Bin 64464 -> 0 bytes .../iui-route/js/fontAwesome/less/animated.less | 34 - .../js/fontAwesome/less/bordered-pulled.less | 25 - .../iui-route/js/fontAwesome/less/core.less | 12 - .../iui-route/js/fontAwesome/less/fixed-width.less | 6 - .../js/fontAwesome/less/font-awesome.less | 17 - .../iui-route/js/fontAwesome/less/icons.less | 677 --- .../iui-route/js/fontAwesome/less/larger.less | 13 - .../iui-route/js/fontAwesome/less/list.less | 19 - .../iui-route/js/fontAwesome/less/mixins.less | 26 - .../iui-route/js/fontAwesome/less/path.less | 15 - .../js/fontAwesome/less/rotated-flipped.less | 20 - .../iui-route/js/fontAwesome/less/stacked.less | 20 - .../iui-route/js/fontAwesome/less/variables.less | 688 --- .../iui-route/js/fontAwesome/scss/_animated.scss | 34 - .../js/fontAwesome/scss/_bordered-pulled.scss | 25 - .../iui-route/js/fontAwesome/scss/_core.scss | 12 - .../js/fontAwesome/scss/_fixed-width.scss | 6 - .../iui-route/js/fontAwesome/scss/_icons.scss | 677 --- .../iui-route/js/fontAwesome/scss/_larger.scss | 13 - .../iui-route/js/fontAwesome/scss/_list.scss | 19 - .../iui-route/js/fontAwesome/scss/_mixins.scss | 26 - .../iui-route/js/fontAwesome/scss/_path.scss | 15 - .../js/fontAwesome/scss/_rotated-flipped.scss | 20 - .../iui-route/js/fontAwesome/scss/_stacked.scss | 20 - .../iui-route/js/fontAwesome/scss/_variables.scss | 688 --- .../js/fontAwesome/scss/font-awesome.scss | 17 - .../jquery-validation/localization/methods_de.js | 40 - .../localization/methods_es_CL.js | 40 - .../jquery-validation/localization/methods_fi.js | 40 - .../jquery-validation/localization/methods_nl.js | 37 - .../jquery-validation/localization/methods_pt.js | 37 - .../iui-route/js/jquery/jquery-1.10.2.min.js | 4 - .../src/main/resources/swagger.properties | 51 - .../msb/wrapper/ApiRouteServiceWrapperTest.java | 164 - .../msb/wrapper/CustomRouteServiceWrapperTest.java | 137 - .../msb/wrapper/IuiRouteServiceWrapperTest.java | 137 - .../openo/msb/wrapper/MicroServiceWrapperTest.java | 148 - .../msb/wrapper/util/JacksonJsonUtilTest.java | 48 - .../openo/msb/wrapper/util/RegExpTestUtilTest.java | 86 - .../org/openo/msb/wrapper/util/RouteUtilTest.java | 64 - .../assembly/resource/apiroute/apirouteService.exe | Bin 59392 -> 0 bytes .../assembly/resource/apiroute/apirouteService.xml | 33 - .../assembly/resource/apiroute/conf/apiroute.yml | 71 - .../ext/initUrlRootPath/initUrlRootPath.json | 4 - .../initVisualRange/initVisualRangeMatches.json | 3 - .../apiroute/ext/initVisualRange/readme.txt | 33 - .../resource/apiroute/find_kill_process.bat | 27 - .../src/assembly/resource/apiroute/run.bat | 59 - .../src/assembly/resource/apiroute/stop.bat | 38 - .../src/assembly/resource/apiroute/stop.sh | 47 - msb-core/apiroute/pom.xml | 39 - msb-core/distributions/pom.xml | 43 - msb-core/distributions/standalone/pom.xml | 250 - .../src/assembly/resource/servicesInstall.bat | 38 - .../src/assembly/resource/servicesRestart.bat | 38 - .../src/assembly/resource/servicesStatus.bat | 38 - .../src/assembly/resource/servicesUninstall.bat | 41 - .../standalone/src/assembly/resource/startup.bat | 46 - .../standalone/src/assembly/resource/stop.bat | 44 - msb-core/eag-openresty-ext/pom.xml | 119 - .../openresty/nginx/sites-enabled/openomsb.conf | 181 - .../resources/openresty/lualib/resty/http.lua | 850 --- .../openresty/lualib/resty/http_headers.lua | 62 - .../resources/openresty/nginx/conf/nginx.conf | 72 - .../openresty/nginx/luaext/customrouter.lua | 187 - .../openresty/nginx/luaext/openoadminrouter.lua | 110 - .../openresty/nginx/luaext/openoapijsonrouter.lua | 110 - .../openresty/nginx/luaext/openoapirouter.lua | 117 - .../openresty/nginx/luaext/openouirouter.lua | 115 - .../openresty/nginx/luaext/plugins/auth.lua | 171 - .../nginx/luaext/plugins/driver_manager.lua | 127 - .../openresty/nginx/sites-enabled/openomsb.conf | 181 - .../src/assembly/resources/openresty/run.bat | 55 - .../src/assembly/resources/openresty/stop.bat | 54 - msb-core/pom.xml | 47 - msb-parent/README.md | 17 - msb-parent/msbparent-lite/pom.xml | 240 - msb-parent/pom.xml | 56 - {msb-core/openresty-ext => openresty-ext}/pom.xml | 83 +- .../resources/openresty/nginx/conf/mime.types | 94 + .../resources/openresty/nginx/conf/nginx.conf | 72 + .../resources/openresty/nginx/html/cert/ca.crt | 22 + .../resources/openresty/nginx/logs/placeholder.txt | 0 .../openresty/nginx/luaext/conf/msbinit.lua | 58 + .../openresty/nginx/luaext/conf/svcconf.lua | 34 + .../resources/openresty/nginx/luaext/dao/dao.lua | 123 + .../openresty/nginx/luaext/dao/db_access.lua | 85 + .../openresty/nginx/luaext/dao/redis_db.lua | 199 + .../openresty/nginx/luaext/lib/tools/db_cache.lua | 54 + .../openresty/nginx/luaext/lib/tools/rr_cache.lua | 40 + .../nginx/luaext/lib/utils/error_handler.lua | 48 + .../openresty/nginx/luaext/lib/utils/log_util.lua | 57 +- .../openresty/nginx/luaext/lib/utils/str_util.lua | 55 +- .../openresty/nginx/luaext/lib/utils/svc_util.lua | 96 + .../nginx/luaext/lib/utils/table_util.lua | 30 + .../nginx/luaext/loadbalance/balancer.lua | 50 + .../nginx/luaext/loadbalance/baseupstream.lua | 66 + .../nginx/luaext/loadbalance/peerwatcher.lua | 107 + .../nginx/luaext/loadbalance/policy/roundrobin.lua | 68 + .../openresty/nginx/luaext/log/logger.lua | 24 + .../resources/openresty/nginx/luaext/msb.lua | 90 + .../openresty/nginx/luaext/plugins/base_plugin.lua | 35 + .../nginx/luaext/plugins/config_custom.lua | 17 +- .../nginx/luaext/plugins/config_default.lua | 19 +- .../plugins/redirect-transformer/handler.lua | 42 + .../nginx/luaext/plugins/sampleplugin/handler.lua | 50 + .../nginx/luaext/rewrite/commonrewrite.lua | 138 + .../nginx/luaext/rewrite/customrewrite.lua | 203 + .../openresty/nginx/luaext/vendor/classic.lua | 68 + .../openresty/nginx/luaext/vendor/shcache.lua | 440 ++ .../msb-enabled/location-default/msblocations.conf | 218 + .../nginx/msb-enabled/location-ext-mount/README.md | 4 + .../nginx/msb-enabled/location-ext/README.md | 11 + .../nginx/msb-enabled/location-ext/cert.conf | 19 + .../msb-enabled/location-ext/defaultpage.conf | 9 + .../nginx/msb-enabled/location-ext/homepage.conf | 20 + .../resources/openresty/nginx/msb-enabled/msb.conf | 67 + .../openresty/nginx/msb-enabled/msbhttps.conf | 22 + .../openresty/nginx/sites-enabled-mount/README.md | 4 + .../openresty/nginx/sites-enabled/README.md | 15 + .../openresty/nginx/sites-enabled/addPortTemplate | 21 + .../openresty/nginx/sites-enabled/sampleplugin | 41 + .../resources/openresty/nginx/ssl/cert/cert.crt | 21 + .../resources/openresty/nginx/ssl/cert/cert.key | 27 + .../openresty/nginx/ssl/dh-pubkey/dhparams.pem | 8 + .../nginx/stream-enabled}/placeholder.txt | 0 .../resources/openresty/nginx/temp/placeholder.txt | 0 .../src/assembly/resources/openresty/reload.sh | 7 +- .../src/assembly/resources/openresty/run.sh | 10 +- .../src/assembly/resources/openresty/run4docker.sh | 39 + .../src/assembly/resources/openresty/stop.sh | 8 +- pom.xml | 196 +- {msb-core/redis-ext => redis-ext}/pom.xml | 81 +- .../assembly/resources/linux/redis/BGREWRITEAOF.sh | 0 .../assembly/resources/linux/redis/conf/redis.conf | 4 +- .../resources/linux/redis/logs/placeholder.txt | 0 .../src/assembly/resources/linux/redis/run.sh | 10 +- .../assembly/resources/linux/redis/run4docker.sh | 46 + .../src/assembly/resources/linux/redis/stop.sh | 11 +- 648 files changed, 27611 insertions(+), 45041 deletions(-) create mode 100644 .gitignore delete mode 100644 .gitreview delete mode 100644 License.txt create mode 100644 apiroute/apiroute-service/dependency-reduced-pom.xml create mode 100644 apiroute/apiroute-service/pom.xml create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteApp.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/ApiRouteAppConfig.java (72%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/SyncDataManager.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/ApiRouteInfo.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/CustomDateSerializer.java (94%) rename msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java (72%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/DiscoverInfo.java (85%) rename msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java (55%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/MicroServiceFullInfo.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/Node.java (62%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/PublishFullAddress.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteInfo.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/RouteServer.java (73%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/exception/ExtendedInternalServerErrorException.java (92%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/api/exception/ExtendedNotFoundException.java (91%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/UnprocessableEntityException.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/health/ApiRouteHealthCheck.java (63%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheck.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/OpenRestyHealthCheck.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/RedisHealthCheck.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/resources/ApiRouteResource.java (67%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/resources/CustomRouteResource.java (66%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/resources/IuiRouteResource.java (65%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/resources/MicroServiceResource.java (64%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/CatalogClient.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/Consul.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/HealthClient.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseCallback.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/ConsulResponseHeader.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/async/OriginalConsulResponse.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ConsulCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilter.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilter.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilter.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilter.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTask.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTask.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchTask.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandler.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/Service.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealth.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/consulextend/util/Http.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOConstants.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/DAOFactory.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/RedisAccessWrapper.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/IRouteDAO.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/RouteDAOImpl.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Metadata.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Node.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/RouteInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/route/bean/Spec.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/IServiceDAO.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/ServiceDAOImpl.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Metadata.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Node.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/ServiceInfo.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/dao/service/bean/Spec.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/BaseQueue.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/QueueManager.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceConsumer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceData.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListCache.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListConsumer.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceListQueue.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/queue/ServiceQueue.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/ApiRouteService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/CustomRouteService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/IuiRouteService.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullService.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/wrapper/serviceListener/IMicroServiceChangeListener.java (50%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListener.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/RouteNotify.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/CommonUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ConfigUtil.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/wrapper/util/FileUtil.java (77%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/HttpGetResult.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/Jackson.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/JedisUtil.java rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/wrapper/util/MicroServiceUtil.java (61%) rename {msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb => apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute}/wrapper/util/RegExpTestUtil.java (64%) create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RouteUtil.java create mode 100644 apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/ServiceFilter.java rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/META-INF/MANIFEST.MF (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/api-doc/WEB-INF/web.xml rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/css/reset.css (60%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/css/screen.css (98%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/css/typography.css (67%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.eot (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.svg (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.ttf (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff2 (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.eot (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.svg (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.ttf (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff2 (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/images/explorer_icons.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/images/logo_small.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/images/pet_store_api.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/images/throbber.gif (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/images/wordnik_api.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/index.html (83%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/api-doc}/js/iframeResizer/iframeResizer.contentWindow.min.js (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/api-doc}/js/iframeResizer/iframeResizer.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/api-doc/js/tools.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js (96%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/handlebars-2.0.0.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/highlight.7.3.pack.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/jquery-1.8.0.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/jquery.ba-bbq.min.js (93%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/jquery.slideto.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/jquery.wiggle.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/marked.js (97%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/shred.bundle.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/shred/content.js (90%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/swagger-client.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/swagger-oauth.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/lib/underscore-min.js (99%) create mode 100644 apiroute/apiroute-service/src/main/resources/api-doc/o2c.html rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/swagger-ui.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/api-doc/swagger-ui.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/banner.txt rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/css/animate.min.css (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/css/base.css create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/css/chart.css rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/css/newRoute.css (76%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/css/route.css (84%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/default.html rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js (86%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-en-US.properties create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-zh-CN.properties rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/checkbox-checked.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/checkbox-init.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/details_close.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/details_open.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/down.png (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/img/loading-spinner-grey.gif (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/img/logo.png rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/sidebar-toggler-grey.jpg (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/img/throbber.gif (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/up.png (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/img/zte_logo_16.gif (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/index.html (67%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/avalon.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootbox/bootbox.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootstrap-growl.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js (99%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/bootstrap/js/bootstrap.min.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js (99%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/dataTables/dataTables.bootstrap.css (99%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/dataTables/dataTables.bootstrap.min.js (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/dataTables/jquery.dataTables.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/echarts/echarts.common.min.js create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/echarts/macarons.js rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/css/font-awesome.css (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/css/font-awesome.css.map (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/css/font-awesome.min.css (99%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/FontAwesome.otf (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/fontawesome-webfont.eot (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/fontawesome-webfont.svg (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/fontawesome-webfont.ttf (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/fontawesome-webfont.woff (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/fonts/fontawesome-webfont.woff2 (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/animated.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/bordered-pulled.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/core.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/fixed-width.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/font-awesome.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/icons.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/larger.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/list.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/mixins.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/path.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/rotated-flipped.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/stacked.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/less/variables.less (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_animated.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_bordered-pulled.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_core.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_fixed-width.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_icons.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_larger.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_list.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_mixins.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_path.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_rotated-flipped.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_stacked.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/_variables.scss (100%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/fontAwesome/scss/font-awesome.scss (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.contentWindow.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js (98%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js (99%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js (71%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js (66%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js (64%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js (58%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js (63%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js (74%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js (68%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js (69%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js (64%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js (71%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js (66%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js (81%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js (69%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js (63%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js (62%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js (64%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js (61%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js (68%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js (77%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js (73%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js (64%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js (66%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js (71%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js (62%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js (67%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js (71%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js (71%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js (67%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js (74%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js (64%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js (59%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js (65%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js (69%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js (63%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js (62%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js (74%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js (73%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js (67%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js (73%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js (61%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js (61%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js (62%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.min.js (100%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.js rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js (99%) rename {msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics => apiroute/apiroute-service/src/main/resources/iui-route}/js/jquery/jquery-1.10.2.min.js (100%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/routeController.js (70%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/routeFunc.js (93%) rename {msb-core/apiroute => apiroute}/apiroute-service/src/main/resources/iui-route/js/routeUtil.js (72%) create mode 100644 apiroute/apiroute-service/src/main/resources/iui-route/js/statusUtil.js create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/SyncDataManagerTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ApiRouteHealthCheckTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheckTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/OpenRestyHealthCheckTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/RedisHealthCheckTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapperTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapperTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapperTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapperTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapperTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/ConsulTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCacheTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCacheTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilterTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilterTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilterTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilterTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTaskTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTaskTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandlerTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealthTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/util/HttpTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/queue/QueueManagerTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/ApiRouteServiceTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/CustomRouteServiceTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/IuiRouteServiceTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullServiceTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListenerTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/CommonUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ConfigUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JedisUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RouteUtilTest.java create mode 100644 apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ServiceFilterTest.java create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initApiGatewayConfig/initApiGatewayConfig.json create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json.sample create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/readme.txt create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initRouteWay/initRouteWay.json create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initRouteWay/readme.txt rename {msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute => apiroute/apiroute-service/src/test/resources}/ext/initServices/msb.json (62%) rename {msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute => apiroute/apiroute-service/src/test/resources}/ext/initServices/readme.txt (65%) rename {msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute => apiroute/apiroute-service/src/test/resources}/ext/initSwaggerJson/api-doc1.json (100%) rename {msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute => apiroute/apiroute-service/src/test/resources}/ext/initSwaggerJson/api-doc2.json (100%) create mode 100644 apiroute/apiroute-service/src/test/resources/ext/initUrlRootPath/initUrlRootPath.json create mode 100644 apiroute/apiroute-service/src/test/resources/ext/redisConf/redis.properties create mode 100644 apiroute/apiroute-service/src/test/resources/org/onap/msb/apiroute/wrapper/consulextend/util/serviceslist.json rename {msb-core/apiroute => apiroute}/apiroute-standalone/pom.xml (79%) create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/conf/apiroute.yml create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initApiGatewayConfig/initApiGatewayConfig.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json.sample create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/readme.txt create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/initRouteWay.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/readme.txt create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/msb.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/readme.txt create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc1.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc2.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initUrlRootPath/initUrlRootPath.json create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/redisConf/redis.properties rename {msb-core/apiroute/apiroute-standalone/src/assembly/resource => apiroute/apiroute-standalone/src/assembly/resources}/apiroute/run.sh (50%) create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/setenv.sh create mode 100644 apiroute/apiroute-standalone/src/assembly/resources/apiroute/stop.sh rename {msb-parent/msbparent => apiroute}/pom.xml (63%) create mode 100644 build4docker.sh create mode 100644 ci/build_docker_image.sh create mode 100644 distributions/msb-apigateway/pom.xml rename msb-core/distributions/standalone/src/assembly/resource/stop.sh => distributions/msb-apigateway/src/assembly/resources/shutdown.sh (76%) rename {msb-core/distributions/standalone/src/assembly/resource => distributions/msb-apigateway/src/assembly/resources}/startup.sh (74%) create mode 100644 distributions/msb-apigateway/src/assembly/resources/startup4docker.sh create mode 100644 distributions/msb-apigateway/src/main/docker/Dockerfile create mode 100644 distributions/pom.xml delete mode 100644 msb-core/apiroute/apiroute-service/pom.xml delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/api-doc/WEB-INF/web.xml delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/api-doc/o2c.html delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/banner.txt delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/css/metrics.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/i18n/loadi18nApp_iui-metrics_view.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/i18n/msb-iui-metrics-i18n-en-US.properties delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/i18n/msb-iui-metrics-i18n-zh-CN.properties delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/img/netnumenLogo.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/index.html delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/css/bootstrap-dt.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/css/bootstrap.min.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/js/bootstrap.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/js/bootstrap2-typeahead.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/echarts/echarts-all.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/images/sort_both.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/jquery.i18n/jquery.i18n.properties-1.0.9.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/metricsChart.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/metricsController.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/metricsUtil.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/css/animate.min.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/default.html delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-en-US.properties delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-zh-CN.properties delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/conductor-logo.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/loading-spinner-grey.gif delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/logo.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/netnumenLogo.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/openo_logo_16.png delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/throbber.gif delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/avalon.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/jquery.dataTables.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/css/font-awesome.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/css/font-awesome.css.map delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/css/font-awesome.min.css delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/FontAwesome.otf delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.eot delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.svg delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.ttf delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff2 delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/animated.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/bordered-pulled.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/core.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/fixed-width.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/font-awesome.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/icons.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/larger.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/list.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/mixins.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/path.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/rotated-flipped.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/stacked.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/variables.less delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_animated.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_bordered-pulled.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_core.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_fixed-width.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_icons.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_larger.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_list.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_mixins.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_path.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_rotated-flipped.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_stacked.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_variables.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/font-awesome.scss delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery/jquery-1.10.2.min.js delete mode 100644 msb-core/apiroute/apiroute-service/src/main/resources/swagger.properties delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/ApiRouteServiceWrapperTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/CustomRouteServiceWrapperTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/IuiRouteServiceWrapperTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/MicroServiceWrapperTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/util/JacksonJsonUtilTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/util/RegExpTestUtilTest.java delete mode 100644 msb-core/apiroute/apiroute-service/src/test/java/org/openo/msb/wrapper/util/RouteUtilTest.java delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/apirouteService.exe delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/apirouteService.xml delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/conf/apiroute.yml delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initUrlRootPath/initUrlRootPath.json delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initVisualRange/initVisualRangeMatches.json delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initVisualRange/readme.txt delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/find_kill_process.bat delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/run.bat delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/stop.bat delete mode 100644 msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/stop.sh delete mode 100644 msb-core/apiroute/pom.xml delete mode 100644 msb-core/distributions/pom.xml delete mode 100644 msb-core/distributions/standalone/pom.xml delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/servicesInstall.bat delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/servicesRestart.bat delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/servicesStatus.bat delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/servicesUninstall.bat delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/startup.bat delete mode 100644 msb-core/distributions/standalone/src/assembly/resource/stop.bat delete mode 100644 msb-core/eag-openresty-ext/pom.xml delete mode 100644 msb-core/eag-openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled/openomsb.conf delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/lualib/resty/http.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/lualib/resty/http_headers.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/conf/nginx.conf delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/customrouter.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/openoadminrouter.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/openoapijsonrouter.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/openoapirouter.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/openouirouter.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/auth.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/driver_manager.lua delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled/openomsb.conf delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/run.bat delete mode 100644 msb-core/openresty-ext/src/assembly/resources/openresty/stop.bat delete mode 100644 msb-core/pom.xml delete mode 100644 msb-parent/README.md delete mode 100644 msb-parent/msbparent-lite/pom.xml delete mode 100644 msb-parent/pom.xml rename {msb-core/openresty-ext => openresty-ext}/pom.xml (78%) create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/conf/mime.types create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/conf/nginx.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/html/cert/ca.crt rename {msb-core/openresty-ext => openresty-ext}/src/assembly/resources/openresty/nginx/logs/placeholder.txt (100%) create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/conf/msbinit.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/conf/svcconf.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/dao.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/db_access.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/tools/db_cache.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/tools/rr_cache.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/utils/error_handler.lua rename msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/setnocacheflag.lua => openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/utils/log_util.lua (57%) rename msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/execute_auth.lua => openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/utils/str_util.lua (62%) create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/utils/svc_util.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/lib/utils/table_util.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/loadbalance/balancer.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/loadbalance/baseupstream.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/loadbalance/peerwatcher.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/loadbalance/policy/roundrobin.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/log/logger.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/msb.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/base_plugin.lua rename msb-core/eag-openresty-ext/src/assembly/resources/openresty/nginx/luaext/msbconf.lua => openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/config_custom.lua (69%) rename msb-core/openresty-ext/src/assembly/resources/openresty/nginx/luaext/msbconf.lua => openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/config_default.lua (68%) create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/redirect-transformer/handler.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/plugins/sampleplugin/handler.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/rewrite/commonrewrite.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/rewrite/customrewrite.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/vendor/classic.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/luaext/vendor/shcache.lua create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-default/msblocations.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-ext-mount/README.md create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-ext/README.md create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-ext/cert.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-ext/defaultpage.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/location-ext/homepage.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/msb.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/msb-enabled/msbhttps.conf create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled-mount/README.md create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled/README.md create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled/addPortTemplate create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/sites-enabled/sampleplugin create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/ssl/cert/cert.crt create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/ssl/cert/cert.key create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/ssl/dh-pubkey/dhparams.pem rename {msb-core/openresty-ext/src/assembly/resources/openresty/nginx/temp => openresty-ext/src/assembly/resources/openresty/nginx/stream-enabled}/placeholder.txt (100%) create mode 100644 openresty-ext/src/assembly/resources/openresty/nginx/temp/placeholder.txt rename {msb-core/openresty-ext => openresty-ext}/src/assembly/resources/openresty/reload.sh (79%) rename {msb-core/openresty-ext => openresty-ext}/src/assembly/resources/openresty/run.sh (91%) create mode 100644 openresty-ext/src/assembly/resources/openresty/run4docker.sh rename {msb-core/openresty-ext => openresty-ext}/src/assembly/resources/openresty/stop.sh (89%) rename {msb-core/redis-ext => redis-ext}/pom.xml (79%) rename {msb-core/redis-ext => redis-ext}/src/assembly/resources/linux/redis/BGREWRITEAOF.sh (100%) rename {msb-core/redis-ext => redis-ext}/src/assembly/resources/linux/redis/conf/redis.conf (99%) create mode 100644 redis-ext/src/assembly/resources/linux/redis/logs/placeholder.txt rename {msb-core/redis-ext => redis-ext}/src/assembly/resources/linux/redis/run.sh (76%) create mode 100644 redis-ext/src/assembly/resources/linux/redis/run4docker.sh rename {msb-core/redis-ext => redis-ext}/src/assembly/resources/linux/redis/stop.sh (76%) diff --git a/.gitattributes b/.gitattributes index 13e92ef..bb0dee2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.java text eol=lf *.xml text eol=lf +*.sh text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6355b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.project +.classpath +.settings/ +target/ +.vagrant +/archives/ +*.jar +*.zip +*.tar +*.gz diff --git a/.gitreview b/.gitreview deleted file mode 100644 index bb6d75f..0000000 --- a/.gitreview +++ /dev/null @@ -1,4 +0,0 @@ -[gerrit] -host=gerrit.open-o.org -port=29418 -project=common-services-microservice-bus.git diff --git a/License.txt b/License.txt deleted file mode 100644 index dd08487..0000000 --- a/License.txt +++ /dev/null @@ -1,473 +0,0 @@ -THIS LICENSE FILE CONTAINS THE LICENSE APPLICABLE DEPENDING ON THE TYPE OF CONTRIBUTIONS. - -APACHE LICENSE 2 IS APPLICABLE FOR SOURCE CODE, CREATIVE COMMONS ATTRIBUTION 4.0 INTERNATIONAL FOR DOCUMENTATION - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Attribution 4.0 International - -https://creativecommons.org/licenses/by/4.0/legalcode - ---------------------------------------------------------------------------------------- - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - ---------------------------------------------------------------------------------------- - -Creative Commons Attribution 4.0 International Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution 4.0 International Public License ("Public License"). To the -extent this Public License may be interpreted as a contract, You are -granted the Licensed Rights in consideration of Your acceptance of -these terms and conditions, and the Licensor grants You such rights in -consideration of benefits the Licensor receives from making the -Licensed Material available under these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - d. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - e. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - f. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - g. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - h. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - i. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - j. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - k. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - 4. If You Share Adapted Material You produce, the Adapter's - License You apply must not prevent recipients of the Adapted - Material from complying with this Public License. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material; and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - ---------------------------------------------------------------------------------------- - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the "Licensor." The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index dc836cc..6218077 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,8 @@ -##Microservice Bus -Within the OPEN-O architecture, there are a lot of microservices, e.g., Catalog, Res Mgr., LCM Mgr., Drivers. These microservices are distributed on multiple hosts, that make the communicate between them complex because the consumers need to know the addresses of all the service providers. Besides, some services may have multiple instances, which make the consumer even harder to locate the service provider. Microservice bus provides a service registration/ discovery and routing mechanism to simply the communications between services. The consumers only need to talk with microservice bus without any address information of individual service providers. -##Runtime Requirements -* Java 7 - -##Run - -1. Install 1.7 or higer version of JDK -1. export JAVA_HOME= "$JAVA_INSTALLATION_PATH" , please replace $JAVA_INSTALLATION_PATH with the JDK installation directory on your host -1. Compile form source or download the latest snapshot from https://nexus.open-o.org/content/repositories/snapshots/org/openo/common-services/microservice-bus/msb-core-standalone/1.0.0-SNAPSHOT/ -1. tar -xzf msb-standalone-1.0.0-SNAPSHOT-linux64.tar.gz -1. sudo -E ./startup.sh - -The default port is 80. +msb-apigateway +=============== +Service API gateway provides client request routing, client request load balancing, transformation, authentication & authorization for service request with plugin of auth service provider,service request logging,service request rate-limiting,service monitoring,request result cache,solve cross-domain issue for web application and other functionalities with the pluggable architecture capability. ## License The Microservice Bus is released under version 2.0 of the [Apache License][]. [Apache License]: http://www.apache.org/licenses/LICENSE-2.0 - - \ No newline at end of file diff --git a/apiroute/apiroute-service/dependency-reduced-pom.xml b/apiroute/apiroute-service/dependency-reduced-pom.xml new file mode 100644 index 0000000..63e1139 --- /dev/null +++ b/apiroute/apiroute-service/dependency-reduced-pom.xml @@ -0,0 +1,121 @@ + + + + apiroute-parent + org.onap.msb.apigateway.apiroute + 0.0.1-SNAPSHOT + + 4.0.0 + org.onap.msb.apigateway.apiroute + apiroute-service + onap/msb/apigateway/apiroute/apiroute-service + 0.0.1-SNAPSHOT + + + + src/main/java + + **/*.properties + + + + src/main/resources + + + + + maven-jar-plugin + 2.4 + + + + true + + + + + + maven-shade-plugin + 2.3 + + + package + + shade + + + + + + org.onap.msb.apiroute.ApiRouteApp + + + + + + + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + junit + junit + 4.11 + test + + + hamcrest-core + org.hamcrest + + + + + org.powermock + powermock-module-junit4 + 1.5.5 + test + + + powermock-module-junit4-common + org.powermock + + + + + org.powermock + powermock-api-mockito + 1.5.5 + test + + + mockito-all + org.mockito + + + powermock-api-support + org.powermock + + + + + com.fiftyonred + mock-jedis + 0.4.0 + test + + + + diff --git a/apiroute/apiroute-service/pom.xml b/apiroute/apiroute-service/pom.xml new file mode 100644 index 0000000..2a3c3e0 --- /dev/null +++ b/apiroute/apiroute-service/pom.xml @@ -0,0 +1,174 @@ + + + + + org.onap.msb.apigateway.apiroute + apiroute-parent + 0.0.1-SNAPSHOT + + 4.0.0 + org.onap.msb.apigateway.apiroute + apiroute-service + onap/msb/apigateway/apiroute/apiroute-service + jar + 0.0.1-SNAPSHOT + + + + + io.dropwizard + dropwizard-core + + + io.dropwizard + dropwizard-assets + + + io.dropwizard + dropwizard-client + + + io.swagger + swagger-jersey2-jaxrs + compile + + + + redis.clients + jedis + + + org.projectlombok + lombok + + + + junit + junit + test + + + org.powermock + powermock-module-junit4 + test + + + + org.powermock + powermock-api-mockito + test + + + com.orbitz.consul + consul-client + + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-core + + + + com.fasterxml.jackson.core + jackson-annotations + + + + org.apache.httpcomponents + httpasyncclient + + + + org.immutables + value + compile + + + + com.fiftyonred + mock-jedis + + + + commons-io + commons-io + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + package + + shade + + + + + + org.onap.msb.apiroute.ApiRouteApp + + + + + + + + + + src/main/java + + **/*.properties + + + + src/main/resources + + + + 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 { + + 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 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java similarity index 72% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java index 8338ceb..4c998e0 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteAppConfig.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/ApiRouteAppConfig.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -29,15 +29,14 @@ * limitations under the License. */ -package org.openo.msb; +package org.onap.msb.apiroute; import io.dropwizard.Configuration; import javax.validation.Valid; import org.hibernate.validator.constraints.NotEmpty; -import org.openo.msb.api.ConsulInfo; -import org.openo.msb.api.DiscoverInfo; +import org.onap.msb.apiroute.api.DiscoverInfo; import com.fasterxml.jackson.annotation.JsonProperty; @@ -47,47 +46,12 @@ public class ApiRouteAppConfig extends Configuration { @NotEmpty private String defaultName = "Stranger"; - - @NotEmpty - private String propertiesName="redis.properties"; - - @NotEmpty - private String propertiesDir="conf"; - + @Valid private DiscoverInfo discoverInfo; - @Valid - private ConsulInfo consulInfo; - - @JsonProperty - public ConsulInfo getConsulInfo() { - return consulInfo; - } - - @JsonProperty - public void setConsulInfo(ConsulInfo consulInfo) { - this.consulInfo = consulInfo; - } - - - public String getPropertiesDir() { - return propertiesDir; - } - - public void setPropertiesDir(String propertiesDir) { - this.propertiesDir = propertiesDir; - } - - public String getPropertiesName() { - return propertiesName; - } - - public void setPropertiesName(String propertiesName) { - this.propertiesName = propertiesName; - } - + @JsonProperty public String getDefaultWorkspace() { return defaultWorkspace; 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 serviceWatchTaskMap = new ConcurrentHashMap(); + + 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( + 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java similarity index 94% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java index e7d46d4..709a995 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomDateSerializer.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomDateSerializer.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api; +package org.onap.msb.apiroute.api; import java.io.IOException; import java.text.SimpleDateFormat; diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java similarity index 72% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java index df21f3e..788ce00 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MetricsUtil.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/CustomRouteInfo.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.wrapper.util; +package org.onap.msb.apiroute.api; -public class MetricsUtil { - public static String adminContextPath = "http://127.0.0.1:8086/admin/metrics"; +public class CustomRouteInfo extends RouteInfo{ + + private static final long serialVersionUID = 1L; + - public static final int SC_OK = 200; } diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java similarity index 85% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java index 5e71b29..4a4708b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/DiscoverInfo.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/DiscoverInfo.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api; +package org.onap.msb.apiroute.api; import java.io.Serializable; @@ -42,6 +42,12 @@ public class DiscoverInfo implements Serializable{ 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java similarity index 55% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java index 3d8c90e..b3f3cf6 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotSupportedException.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/IuiRouteInfo.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,15 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api.exception; +package org.onap.msb.apiroute.api; -import javax.ws.rs.NotSupportedException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -public class ExtendedNotSupportedException extends NotSupportedException { - public ExtendedNotSupportedException(final String message) { - super(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).entity(message).type(MediaType.TEXT_PLAIN).build()); - } +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 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 getNodes() { + return nodes; + } + + public void setNodes(Set 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java similarity index 62% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java index 6273ea1..c515820 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Node.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/Node.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,15 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api; +package org.onap.msb.apiroute.api; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; -import java.util.Date; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import java.util.Objects; public class Node implements Serializable { private static final long serialVersionUID = 1L; @@ -32,10 +29,17 @@ public class Node implements Serializable { @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; @@ -71,5 +75,24 @@ public class Node implements Serializable { 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java similarity index 73% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java index 0a38c7f..310e623 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/RouteServer.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/RouteServer.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api; +package org.onap.msb.apiroute.api; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; +import java.util.Objects; public class RouteServer implements Serializable{ @@ -65,4 +66,18 @@ public class RouteServer implements Serializable{ 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java similarity index 92% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java index f30cde5..de0d47a 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedInternalServerErrorException.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedInternalServerErrorException.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api.exception; +package org.onap.msb.apiroute.api.exception; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.core.MediaType; diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java similarity index 91% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java index 92956d1..34439d9 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/exception/ExtendedNotFoundException.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/api/exception/ExtendedNotFoundException.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.api.exception; +package org.onap.msb.apiroute.api.exception; import javax.ws.rs.NotFoundException; import javax.ws.rs.core.MediaType; 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java similarity index 63% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java index e4f0135..82b5f21 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/health/ApiRouteHealthCheck.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/health/ApiRouteHealthCheck.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -28,23 +28,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.health; +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 { - private final String template; - public ApiRouteHealthCheck(String template) { - this.template = template; + + public ApiRouteHealthCheck() { } @Override protected Result check() throws Exception { - final String saying = String.format(template, "TEST"); - if (!saying.contains("TEST")) { - return Result.unhealthy("template doesn't include a name"); - } + 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java index a71b978..e969e7a 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ApiRouteResource.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/ApiRouteResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.resources; +package org.onap.msb.apiroute.resources; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -22,6 +22,7 @@ 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; @@ -31,6 +32,7 @@ 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; @@ -38,13 +40,14 @@ import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.UriInfo; import org.apache.http.HttpStatus; -import org.openo.msb.api.ApiRouteInfo; -import org.openo.msb.api.DiscoverInfo; -import org.openo.msb.wrapper.ApiRouteServiceWrapper; -import org.openo.msb.wrapper.CustomRouteServiceWrapper; -import org.openo.msb.wrapper.IuiRouteServiceWrapper; -import org.openo.msb.wrapper.util.JacksonJsonUtil; -import org.openo.msb.wrapper.util.RouteUtil; +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; @@ -62,25 +65,24 @@ public class ApiRouteResource { @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get ApiRouteInfo List fail", response = String.class)}) @Produces(MediaType.APPLICATION_JSON) @Timed - public ApiRouteInfo[] getApiRoutes() { - return ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(); + public List 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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @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) { - ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfo,""); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/" + new_apiRouteInfo.getServiceName()+"/version/"+new_apiRouteInfo.getVersion()).build(); + @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(); } @@ -90,15 +92,18 @@ public class ApiRouteResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", 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 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); + return ApiRouteServiceWrapper.getInstance().getApiRouteInstance(serviceName,version,host,publish_port,routeWay); } @@ -106,7 +111,7 @@ public class ApiRouteResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @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) @@ -114,12 +119,11 @@ public class ApiRouteResource { 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 = "ApiRoute Instance Info", required = true) ApiRouteInfo apiRouteInfo, + @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) { - ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().updateApiRouteInstance(serviceName,version,apiRouteInfo,""); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/" + new_apiRouteInfo.getServiceName()+"/version/"+new_apiRouteInfo.getVersion()).build(); + 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(); } @@ -137,11 +141,12 @@ public class ApiRouteResource { @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) { - - - ApiRouteServiceWrapper.getInstance().deleteApiRoute(serviceName, version,"*",""); + @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); } @@ -153,22 +158,9 @@ public class ApiRouteResource { @Timed public String[] getApiDocs() { - String[] apiDocs = ApiRouteServiceWrapper.getInstance().getAllApiDocs(); - return apiDocs; - + return ApiRouteServiceWrapper.getInstance().getAllApiDocs(); } - - @GET - @Path("/apiGatewayPort") - @ApiOperation(value = "get apiGateway Port ", code = HttpStatus.SC_OK, response = String.class) - @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get apiGateway Port fail", response = String.class)}) - @Produces(MediaType.TEXT_PLAIN) - @Timed - public String getApiGatewayPort() { - - return ApiRouteServiceWrapper.getInstance().getApiGatewayPort(); - } @GET @Path("/discoverInfo") @@ -178,14 +170,14 @@ public class ApiRouteResource { @Timed public DiscoverInfo getServiceDiscoverInfo() { - return ApiRouteServiceWrapper.getInstance().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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable ApiRouteInfo Entity ", response = String.class), + @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) @@ -193,9 +185,12 @@ public class ApiRouteResource { 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 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,status); + ApiRouteInfo new_apiRouteInfo = ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName,version,host,publish_port,status,routeWay); return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_apiRouteInfo).build(); } @@ -207,24 +202,10 @@ public class ApiRouteResource { @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() throws Exception { - - - Object[] apirouteArray= ApiRouteServiceWrapper.getInstance().getAllApiRouteInstances(); - Object[] iuirouteArray= IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(); - Object[] customrouteArray= CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(); - - Object[] temprouteArray =RouteUtil.concat(apirouteArray, iuirouteArray); - Object[] allrouteArray=RouteUtil.concat(temprouteArray, customrouteArray); - - - String allrouteJson=JacksonJsonUtil.beanToJson(allrouteArray); - - ResponseBuilder response = Response.ok(allrouteJson); - response.header("Content-Disposition", - "attachment; filename=\"RouteService.json\""); - return response.build(); - + 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java similarity index 66% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java index 01a4291..92b3408 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/CustomRouteResource.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/CustomRouteResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.resources; +package org.onap.msb.apiroute.resources; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -22,8 +22,10 @@ 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; @@ -36,8 +38,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.http.HttpStatus; -import org.openo.msb.api.CustomRouteInfo; -import org.openo.msb.wrapper.CustomRouteServiceWrapper; +import org.onap.msb.apiroute.api.CustomRouteInfo; +import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper; import com.codahale.metrics.annotation.Timed; @@ -55,25 +57,24 @@ public class CustomRouteResource { @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get CustomRouteInfo List fail", response = String.class)}) @Produces(MediaType.APPLICATION_JSON) @Timed - public CustomRouteInfo[] getCustomRoutes() { - return CustomRouteServiceWrapper.getInstance().getAllCustomRouteInstances(); + public List 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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRouteInfo Entity ", response = String.class), + @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) { - CustomRouteInfo new_customRouteInfo = CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance(customRouteInfo,""); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/instance?serviceName=" + new_customRouteInfo.getServiceName()).build(); + @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(); } @@ -83,15 +84,18 @@ public class CustomRouteResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRoute Entity ", 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 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); + return CustomRouteServiceWrapper.getInstance().getCustomRouteInstance(serviceName,host,publish_port,routeWay); } @@ -99,16 +103,18 @@ public class CustomRouteResource { @Path("/instance") @ApiOperation(value = "update one CustomRoute by serviceName", code = HttpStatus.SC_CREATED,response = CustomRouteInfo.class) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable CustomRoute Entity ", response = String.class), + @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 = "CustomRoute Instance Info", required = true) CustomRouteInfo customRoute, + @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay + ) { - CustomRouteInfo new_customRouteInfo= CustomRouteServiceWrapper.getInstance().updateCustomRouteInstance(serviceName,customRoute,""); + CustomRouteInfo new_customRouteInfo= CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance4Rest(customRoute,routeWay); return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(new_customRouteInfo).build(); @@ -124,9 +130,12 @@ public class CustomRouteResource { @Produces(MediaType.APPLICATION_JSON) @Timed public void deleteCustomRoute( - @ApiParam(value = "CustomRoute serviceName", required = true) @QueryParam("serviceName") String serviceName) { + @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,"*",""); + CustomRouteServiceWrapper.getInstance().deleteCustomRoute(serviceName,host,publish_port,routeWay); } @@ -134,16 +143,19 @@ public class CustomRouteResource { @Path("/status") @ApiOperation(value = "update one CustomRoute status by serviceName ",code = HttpStatus.SC_CREATED, response = CustomRouteInfo.class) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable customRoute Entity ", response = String.class), + @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 status,1:abled 0:disabled", required = true) @QueryParam("status") String status) { + @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,status); + 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java index 057d15d..fea6645 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/IuiRouteResource.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/IuiRouteResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.resources; + +package org.onap.msb.apiroute.resources; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -22,22 +23,25 @@ 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.openo.msb.api.IuiRouteInfo; -import org.openo.msb.wrapper.IuiRouteServiceWrapper; +import org.onap.msb.apiroute.api.IuiRouteInfo; +import org.onap.msb.apiroute.wrapper.IuiRouteServiceWrapper; import com.codahale.metrics.annotation.Timed; @@ -55,25 +59,24 @@ public class IuiRouteResource { @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get iuiRouteInfo List fail", response = String.class)}) @Produces(MediaType.APPLICATION_JSON) @Timed - public IuiRouteInfo[] getIuiRoutes() { - return IuiRouteServiceWrapper.getInstance().getAllIuiRouteInstances(); + public List 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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable iuiRouteInfo Entity ", response = String.class), + @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) { - IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/" + new_iuiRouteInfo.getServiceName()).build(); + @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(); } @@ -83,14 +86,17 @@ public class IuiRouteResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", 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 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); + return IuiRouteServiceWrapper.getInstance().getIuiRouteInstance(serviceName,host,publish_port,routeWay); } @@ -98,19 +104,18 @@ public class IuiRouteResource { @Path("/{serviceName}") @ApiOperation(value = "update one iuiRoute by serviceName", code = HttpStatus.SC_CREATED,response = IuiRouteInfo.class) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", response = String.class), + @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 = "iuiRoute Instance Info", required = true) IuiRouteInfo iuiRouteInfo, + @ApiParam(value = "Route Way", required = false) @QueryParam("routeWay") @DefaultValue("ip")String routeWay) { - IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().updateIuiRouteInstance(serviceName,iuiRouteInfo); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/" + serviceName).build(); + IuiRouteInfo new_iuiRouteInfo = IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance4Rest(iuiRouteInfo,routeWay); + URI returnURI =uriInfo.getAbsolutePathBuilder().path("/" + serviceName).build(); return Response.created(returnURI).entity(new_iuiRouteInfo).build(); } @@ -124,9 +129,12 @@ public class IuiRouteResource { @Produces(MediaType.APPLICATION_JSON) @Timed public void deleteIuiRoute( - @ApiParam(value = "iuiRoute serviceName", required = true) @PathParam("serviceName") String serviceName) { + @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,"*"); + IuiRouteServiceWrapper.getInstance().deleteIuiRoute(serviceName,host,publish_port,routeWay); } @@ -134,19 +142,20 @@ public class IuiRouteResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable IuiRouteInfo Entity ", response = String.class), + @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 status,1:abled 0:disabled", required = true) @PathParam("status") String status) { + @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,status); - URI returnURI = - uriInfo.getAbsolutePathBuilder() - .path("/" + serviceName).build(); + 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java index dd560ff..5beb209 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MicroServiceResource.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/resources/MicroServiceResource.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.resources; + +package org.onap.msb.apiroute.resources; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -22,6 +23,7 @@ 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; @@ -38,35 +40,36 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpStatus; -import org.openo.msb.api.MicroServiceFullInfo; -import org.openo.msb.api.MicroServiceInfo; -import org.openo.msb.wrapper.MicroServiceWrapper; -import org.openo.msb.wrapper.util.MicroServiceUtil; +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"}) +// @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 - - private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class); - @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 MicroServiceFullInfo[] getMicroService() { + public List getMicroService() { return MicroServiceWrapper.getInstance().getAllMicroServiceInstances(); } @@ -74,26 +77,21 @@ public class MicroServiceResource { @Path("/") @ApiOperation(value = "add one microservice ", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @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) MicroServiceInfo microServiceInfo, + @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(); + 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(); } @@ -104,17 +102,16 @@ public class MicroServiceResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", 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, - @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port) { + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version) { - return MicroServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version,port); + return MicroServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version); } @@ -123,7 +120,7 @@ public class MicroServiceResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @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) @@ -131,35 +128,16 @@ public class MicroServiceResource { 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) MicroServiceInfo microServiceInfo) { + @ApiParam(value = "microservice Instance Info", required = true) MicroServiceFullInfo microServiceInfo, + @Context HttpServletRequest request) { - MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().updateMicroServiceInstance(serviceName, version, - microServiceInfo); + String ip=MicroServiceUtil.getRealIp(request); + MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo, + false,ip,""); return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build(); } - @PUT - @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}") - @ApiOperation(value = "update single node by serviceName and version and node", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class) - @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, 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 node fail", response = String.class)}) - @Produces(MediaType.APPLICATION_JSON) - @Timed - public Response updateNode( - @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, - @ApiParam(value = "ttl") @QueryParam("ttl") int ttl) { - - MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance().updateMicroServiceNode(serviceName, version, ip,port, ttl); - - return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build(); - - } @@ -169,7 +147,7 @@ public class MicroServiceResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", 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 @@ -190,17 +168,15 @@ public class MicroServiceResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", 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, - @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port) { - + @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version) { - MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version,port); + MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version); } @@ -208,7 +184,7 @@ public class MicroServiceResource { @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_UNSUPPORTED_MEDIA_TYPE, message = "Unprocessable MicroServiceInfo Entity ", response = String.class), + @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) @@ -223,24 +199,31 @@ public class MicroServiceResource { 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(); + } + -// @PUT -// @Path("/ttl") -// @ApiOperation(value = "test json date iso8601 ", code = 200, response = String.class) -// @Produces(MediaType.APPLICATION_JSON) -// @Timed -// public String testIso8601( -// @ApiParam(value = "microservice Instance Info", required = true) MicroServiceFullInfo microServiceInfo) { -// Set nodes=microServiceInfo.getNodes(); -// String rtn="rtn:"; -// for(NodeInfo node:nodes){ -// Date date=node.getExpiration(); -// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); -// String datettl=sdf.format(date); -// rtn+=datettl; -// } -// -// -// return rtn; -// } } 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 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 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 routeList = + JacksonJsonUtil.jsonToListBean(fileContent, new TypeReference>() {}); + 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 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 getAllMicroServiceInstances() { + + try { + return MicroServiceFullService.getInstance().getAllMicroServiceInstances(); + + } catch (Exception e) { + throw new ExtendedInternalServerErrorException(e.getMessage()); + } + + } + + public Set getAllMicroServiceKey() { + int failedNum = 0; + int retryCount=3; + int failedTimer = 5 * 1000; + + Set 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 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 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 getAllVersion(String serviceName) { + Set serviceVersionSet = new HashSet(); + try { + String pattern = MicroServiceUtil.getServiceKey(serviceName, "*"); + Set 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 TYPE_SERVICES_MAP = new TypeReference() { + }; + + + 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 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. + *

+ * /v1/catalog + * + * @return The Catalog HTTP client. + */ + public CatalogClient catalogClient() { + return catalogClient; + } + + /** + * Get the Health HTTP client. + *

+ * /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> TYPE_SERVICE_HEALTH_LIST = new TypeReference>() { + }; + + 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}&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> 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> 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 The Response type. + */ +public interface ConsulResponseCallback { + + /** + * Callback for a successful {@link com.orbitz.consul.model.ConsulResponse}. + * + * @param consulResponse The Consul response. + */ + void onComplete(ConsulResponse consulResponse); + + /** + * Callback for a successful {@link com.orbitz.consul.model.ConsulResponse}. + * + * @param consulResponse The Consul response. + */ + void onDelayComplete(OriginalConsulResponse 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 { + final HttpResponse response; + final TypeReference responseType; + + public OriginalConsulResponse(HttpResponse response, TypeReference responseType) { + this.response = response; + this.responseType = responseType; + + } + + public HttpResponse getResponse() { + return response; + } + + public TypeReference 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 + */ +public class ConsulCache { + + 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 latestIndex = new AtomicReference( + null); + private final AtomicReference state = new AtomicReference( + State.latent); + private final CountDownLatch initLatch = new CountDownLatch(1); + private final ScheduledExecutorService executorService = Executors + .newSingleThreadScheduledExecutor(); + private final CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList>(); + + private final CallbackConsumer callBackConsumer; + private final ConsulResponseCallback responseCallback; + + ConsulCache(CallbackConsumer callbackConsumer) { + + this.callBackConsumer = callbackConsumer; + + this.responseCallback = new ConsulResponseCallback() { + @Override + public void onComplete(ConsulResponse consulResponse) { + + if (consulResponse.isKnownLeader()) { + if (!isRunning()) { + return; + } + updateIndex(consulResponse); + + for (Listener 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 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 consulResponse = Http + .consulResponse(originalConsulResponse + .getResponseType(), + originalConsulResponse + .getResponse()); + + // notify customer to custom T data + for (Listener 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 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 + */ + protected interface CallbackConsumer { + void consume(BigInteger index, ConsulResponseCallback callback); + } + + /** + * Implementers can register a listener to receive a new map when it changes + * + * @param + */ + public interface Listener { + void notify(ConsulResponse newValues); + } + + public boolean addListener(Listener listener) { + boolean added = listeners.add(listener); + return added; + } + + public List> getListeners() { + return Collections.unmodifiableList(listeners); + } + + public boolean removeListener(Listener 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> { + private ServiceHealthCache(CallbackConsumer> callbackConsumer) { + super(callbackConsumer); + } + + /** + * Factory method to construct a string/{@link ServiceHealth} map for a particular service. + *

+ * 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> callbackConsumer = new CallbackConsumer>() { + @Override + public void consume(BigInteger index, + ConsulResponseCallback> 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 { + + private ServicesCatalogCache(CallbackConsumer callbackConsumer) { + super(callbackConsumer); + } + + public static ServicesCatalogCache newCache( + final CatalogClient catalogClient, + final CatalogOptions catalogOptions, + final QueryOptions queryOptions, + final int watchSeconds) { + + CallbackConsumer callbackConsumer = new CallbackConsumer() { + @Override + public void consume(BigInteger index, ConsulResponseCallback 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> { + + 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> 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> 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> data = new ServiceData>(); + 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 serviceHealthList = new ArrayList(); + 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> { + + 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 + // 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> object) { + // TODO Auto-generated method stub + + // find #ServiceHealth# which satisfy the tag conditions + List 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 getSatisfyList( + ConsulResponse> object) { + List satisfyList = new ArrayList(); + for (ServiceHealth health : object.getResponse()) { + + if (ServiceFilter.getInstance().isFilterCheck(health)) { + satisfyList.add(health); + } + } + + return satisfyList; + } + + private void writeServiceToQueue(List serviceData, + Operate operate) { + ServiceData> data = new ServiceData>(); + 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 implements WatchTask.Filter { + + private final static Logger LOGGER = LoggerFactory + .getLogger(ConsulIndexFilter.class); + + private final AtomicReference latestIndex = new AtomicReference( + null); + + @Override + public boolean filter(final ConsulResponse object) { + // TODO Auto-generated method stub + return isChanged(object); + } + + private boolean isChanged(final ConsulResponse 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> { + + private final AtomicReference> lastResponse = + new AtomicReference>(ImmutableList.of()); + + private final static Logger LOGGER = LoggerFactory.getLogger(ServiceModifyIndexFilter.class); + + + @Override + public boolean filter(ConsulResponse> object) { + // TODO Auto-generated method stub + + List newList=object.getResponse(); + if(realFilter(newList)){ + lastResponse.set(ImmutableList.copyOf(newList)); + return true; + } + + return false; + } + + private boolean realFilter(List 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 oldData, List 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.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 { + + 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) 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> { + 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>) 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> 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 { + private final CopyOnWriteArrayList> filters = new CopyOnWriteArrayList>(); + private final CopyOnWriteArrayList> handlers = new CopyOnWriteArrayList>(); + private final static Logger LOGGER = LoggerFactory + .getLogger(WatchTask.class); + + //start + public abstract boolean startWatch(); + + //stop + public abstract boolean stopWatch(); + + // filters + public interface Filter { + public boolean filter(final ConsulResponse object); + } + + public boolean addFilter(Filter filter) { + boolean added = filters.add(filter); + return added; + } + + public void removeAllFilter() { + filters.clear(); + } + + + public final CopyOnWriteArrayList> getAllFilters(){ + return filters; + } + + // handlers + public interface Handler { + void handle(final ConsulResponse object); + } + + public boolean addHandler(Handler handler) { + boolean added = handlers.add(handler); + return added; + } + + public void removeAllHandler() { + handlers.clear(); + } + + // internal listener + protected class InternalListener implements ConsulCache.Listener { + @Override + public void notify(ConsulResponse newValues) { + + long startTime = System.currentTimeMillis(); + + // filter + for (Filter f : filters) { + // false,return + if (!f.filter(newValues)) { + return; + } + } + + // handle + for (Handler 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 implements WatchTask.Handler { + + 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 object) { + // TODO Auto-generated method stub + ServiceData data = new ServiceData(); + 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 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 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 void asyncGet(String requestURI, + final TypeReference responseType, + final ConsulResponseCallback callback, final Integer... okCodes) { + // LOGGER.info("Async request:"+requestURI); + + httpAsyncClient.execute(new HttpGet(requestURI), + new FutureCallback() { + + 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 void asyncGetDelayHandle(String requestURI, + final TypeReference responseType, + final ConsulResponseCallback callback, final Integer... okCodes) { + + httpAsyncClient.execute(new HttpGet(requestURI), + new FutureCallback() { + + public void completed(final HttpResponse response) { + OriginalConsulResponse originalConsulResponse = new OriginalConsulResponse( + 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 ConsulResponse consulResponse( + TypeReference 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 consulResponse = new ConsulResponse(readResponse( + response, responseType), lastContact, knownLeader, index); + return consulResponse; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static T readResponse(HttpResponse response, + TypeReference 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 readDefaultResponse(TypeReference 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 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 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 queryMultiKeys(String keyPattern) throws Exception { + Set keySet = filterKeys(keyPattern); + List 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 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 filterKeys(String pattern) throws Exception{ + long start = System.currentTimeMillis(); + Jedis jedis = null; + Set filteredKeys = new HashSet<>(); + ScanParams scanParams = new ScanParams(); + scanParams.match(pattern); + scanParams.count(REDIS_SCAN_COUNT); + try { + jedis = JedisUtil.borrowJedisInstance(); + ScanResult 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 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 queryMultiRoute(String keyPattern) throws Exception { + List routeInfoStrList = RedisAccessWrapper.queryMultiKeys(keyPattern); + List 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 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 queryMultiService(String keyPattern) throws Exception { + List serviceInfoStrList = RedisAccessWrapper.queryMultiKeys(keyPattern); + List 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 { + + private final List>> queueArray= new ArrayList>>(); + + public BaseQueue(int queueNum,int queueCapacity) + { + for(int i=0;queueNum>0 && i>(queueCapacity)); + } + } + + public int getQueneNum(){ + return queueArray.size(); + } + + protected BlockingQueue> getQueue(int index) + { + return queueArray.get(index); + } + + public abstract void put(final ServiceData data) throws InterruptedException; + + public abstract ServiceData 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 serviceListQueue; + private final BaseQueue> 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 takeFromServiceListQueue( + int queueIndex) throws InterruptedException { + return serviceListQueue.take(queueIndex); + } + + public ServiceData> takeFromServiceQueue(int queueIndex) + throws InterruptedException { + return serviceQueue.take(queueIndex); + } + + + @SuppressWarnings("unchecked") + public void putIn(ServiceData data) throws InterruptedException { + + if (data.getDataType() == ServiceData.DataType.service_list) { + LOGGER.debug("putIn service_list queue success"); + serviceListQueue.put((ServiceData) data); + } else if (data.getDataType() == ServiceData.DataType.service) { + serviceQueue.put((ServiceData>) 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 + private final Map> lastVersionResponse = new HashMap>(); + + public ServiceConsumer(final int index) { + this.index = index; + } + + + public void run() { + + LOGGER.info("run Service Consumer Thread [" + index + "]"); + + while (isRunning) { + try { + ServiceData> 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> 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> 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 serviceNodeList = serviceData.getData(); + + + Map microServiceInfo4version = + ServiceFilter.getInstance().transMicroServiceInfoFromConsul(serviceNodeList); + + // 删除数据库中已不存在的版本号服务信息 + Set newAllVersion = microServiceInfo4version.keySet(); + + if (lastVersionResponse.containsKey(serviceName)) { + Set dbAllVersionSet = lastVersionResponse.get(serviceName); + // Set dbAllVersionSet=MicroServiceWrapper.getInstance().getAllVersion(serviceName); + Set 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 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 { + 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> serviceNameList4Cache = new AtomicReference>(new HashSet()); + + public static Set getLatestServiceNamelist() { + return serviceNameList4Cache.get(); + } + + public static void setLatestServiceNamelist(Set newServicenamelist){ + serviceNameList4Cache.set(newServicenamelist); + LOGGER.info("------current total Watch Service Num :"+ newServicenamelist.size()); + } + + public synchronized static void removeService(String serviceName){ + + Set 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 serviceData = QueueManager + .getInstance().takeFromServiceListQueue(index); + LOGGER.debug("ServiceList Consumer Thread [" + index + + "] take out serviceData from Queue successfully"); + + HttpEntity newValues = serviceData.getData(); + + Set 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 newServiceNameList) { + Set 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 newServiceNameList) { + LOGGER.info("***start to initialize service List when System startup ***"); + + Set dbServiceNameList = MicroServiceWrapper + .getInstance().getAllMicroServiceKey(); + + if(dbServiceNameList==null){ + LOGGER.error("init ServiceList from redis fail "); + return false; + } + + + // 对比删除redis脏数据 + Set 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 filterServiceList( + final Map> serviceList) { + if (serviceList == null || serviceList.isEmpty()) { + return ImmutableSet.of(); + } + + final ImmutableSet.Builder builder = ImmutableSet.builder(); + + for (Map.Entry> entry : serviceList.entrySet()) { + + String key = entry.getKey(); + if (key != null && !"consul".equals(key)) { + + List 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 filterServiceList(final HttpEntity serviceList) { + + if (serviceList == null || serviceList.getContentLength() == 0) { + return new HashSet(); + } + + final Set builder = new HashSet(); + + JsonFactory f = new JsonFactory(); + JsonParser jp = null; + List 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(); + } finally { + try { + jp.close(); + } catch (IOException e) { + LOGGER.warn("parse service list error",e); + return new HashSet(); + } + } + + 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 { + + 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 data) throws InterruptedException { + BlockingQueue> 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 take(int queueIndex) throws InterruptedException { + BlockingQueue> queue = getQueue(queueIndex); + ServiceData serviceData = queue.take(); + return serviceData; + + /*//取队列最新一条数据 + if (queue.isEmpty()) { + LOGGER.info("take a single serviceData from ServiceListQueue "); + return serviceData; + } else { + List>>> serviceDataList = + new ArrayList>>>(); + //一次性从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> { + + 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> 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>> queue=getQueue(queneIndex); + queue.put(data); + + LOGGER.info("put ServiceQueue[index:"+queneIndex+",size:"+queue.size()+"] success :[serviceName]"+serviceName); + } + + @Override + public ServiceData> 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 getMultiApiRouteInstances(String apiRedisKeyPattern) throws Exception { + List apiRouteList = new ArrayList<>(); + List 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 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 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 getMultiCustomRouteInstances(String customRedisKeyPattern) throws Exception { + List customRouteList = new ArrayList<>(); + List 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 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 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 getMultiIuiRouteInstances(String apiRedisKeyPattern) throws Exception { + List iuiRouteList = new ArrayList<>(); + List 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 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 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 getAllMicroServiceInstances() throws Exception { + String serviceKeyPattern = MicroServiceUtil.getPrefixedKey("*"); + + List microServiceFullInfoList = new ArrayList<>(); + List serviceInfoList = serviceDAO.queryMultiService(serviceKeyPattern); + for (ServiceInfo serviceInfo : serviceInfoList) { + if (serviceInfo != null) { + MicroServiceFullInfo microServiceFullInfo = MicroServiceFullAdapter.fromServiceInfo(serviceInfo); + ; + microServiceFullInfoList.add(microServiceFullInfo); + } + } + return microServiceFullInfoList; + } + + public Set getAllMicroServiceKey() throws Exception { + final Set builder = new HashSet(); + + String serviceKeyPattern = MicroServiceUtil.getPrefixedKey("*"); + Set 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 getAllVersionsOfTheService(String serviceName) throws Exception { + String serviceKeyPattern = MicroServiceUtil.getPrefixedKey(serviceName, "*"); + + List microServiceFullInfoList = new ArrayList<>(); + List 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 nodeSet = microServiceFullInfo.getNodes(); + List 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 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(nodeList)); + + Metadata metadata = serviceInfo.getMetadata(); + microServiceFullInfo.setServiceName(metadata.getName()); + microServiceFullInfo.setNamespace(metadata.getNamespace()); + + return microServiceFullInfo; + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java similarity index 50% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java index e37bb06..68e31f8 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/IMicroServiceChangeListener.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/serviceListener/IMicroServiceChangeListener.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,19 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.wrapper.serviceListener; -import org.openo.msb.api.MicroServiceInfo; -import org.openo.msb.api.Service; + +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(Service microServiceInfo,String serverPort); + public void onSave(MicroServiceFullInfo microServiceInfo) throws Exception; + + public void onDelete(MicroServiceFullInfo microServiceInfo) throws Exception; - public void onChange(String serviceName,String version,Service microServiceInfo,String serverPort); + public void onChange(String serviceName,String version,MicroServiceFullInfo microServiceInfo) throws Exception; - public void onStatusChange(String serviceName,String url,String version,String protocol,String status); + public void onStatusChange(String serviceName,String version,String host, String protocol,String publish_port, + String status); - public void onDelete(String serviceName, String url,String version,String protocol,String serverPort); + + } 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 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 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 getPublishNodes(String discoverServiceName, String version, String namespace) { + List nodes = new ArrayList(); + + 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 publishFullAddressList = + JacksonJsonUtil + .jsonToListBean(resultJson, new TypeReference>() {}); + 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 serviceListenerlist = + new ArrayList(); + + 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 + * @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 + */ + public static Set getDiffrent(Set list1, Set list2) { + + HashSet set_all = new HashSet(); + + for (T t1 : list1) { + set_all.add(t1); + } + + + Set diff = new HashSet(); + + 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 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 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 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 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 predefineLabelMapMatches = + (Map) 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) labelMap.get("customLabels"); + labelConfSource="initRouteLabelsMatches.json"; + } + + } + } else { + String[] env_routeLabels = StringUtils.split(env_ROUTE_LABELS, ","); + Map labelMap = new HashMap(); + + 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 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 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java similarity index 77% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java index baf3a1a..1e89f82 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/FileUtil.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/FileUtil.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.wrapper.util; + +package org.onap.msb.apiroute.wrapper.util; import java.io.BufferedReader; import java.io.File; @@ -39,14 +40,14 @@ public final class FileUtil { public static String readFile(String Path) throws IOException{ BufferedReader reader = null; - String fileContent = ""; + 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 += tempString; + fileContent.append(tempString); } reader.close(); } catch (IOException e) { @@ -60,6 +61,18 @@ public final class FileUtil { } } } - return fileContent; + 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 jsonToListBean(String json, TypeReference 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/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java similarity index 61% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java index 3da82ed..1081579 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceUtil.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtil.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,61 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.wrapper.util; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; +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"; - public static final String PREFIX_PATH_PORT = "discover:"; - - public static final String SUFFIX_PATH_INFO = "info"; - - public static final String REDIS_KEY_PATTERN = - "discover:microservices:(?[^:]+)(:(?[^:]*))?:info"; - - public static final String REQUEST_SUCCESS = "SUCCESS"; - - public static final String REQUEST_FAIL = "FAIL"; - - public static final String ROUTE_PATH_LOADBALANCE = "lb"; // 负载均衡路径名 + private static final Pattern SERVICE_KEY_REGEX_PATTERN = + Pattern.compile("discover:microservices:(?[^:]+)(:(?[^:]*))"); public static String getPrefixedKey(String... paths) { StringBuffer sb = new StringBuffer(); - if(paths[0].trim().equals("") || paths[0].equals(String.valueOf(JedisUtil.serverPort))){ - sb.append(PREFIX_PATH); - } - else{ - sb.append(PREFIX_PATH_PORT).append(paths[0]); - } - - for (int i = 1; i < paths.length; i++) { + sb.append(PREFIX_PATH); + + for (int i = 0; i < paths.length; i++) { sb.append(":"); sb.append(paths[i]); } return sb.toString(); } - - public static String getServiceInfoKey(String serverPort,String serviceName, String version) { - return getPrefixedKey(serverPort,serviceName, version, SUFFIX_PATH_INFO); + + public static String getServiceKey(String serviceName, String version) { + return getPrefixedKey(serviceName, version); } - - - - - public static Pattern getRedisKeyPattern() { - return Pattern.compile(REDIS_KEY_PATTERN); + public static Pattern getServiceKeyRegexPattern(){ + return SERVICE_KEY_REGEX_PATTERN; } + + public static String getRealIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java rename to apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java index 90c8cba..0edcfda 100644 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RegExpTestUtil.java +++ b/apiroute/apiroute-service/src/main/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtil.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 ZTE Corporation. + * 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. @@ -13,13 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openo.msb.wrapper.util; +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/(?[^/]+)(/(?[^/]*)).*"; + + private final static String IUI_KEY_PATTERN ="/iui/(?[^/]+)/.*"; public static boolean hostRegExpTest(String host){ @@ -66,23 +70,46 @@ public static boolean urlRegExpTest(String url){ public static boolean apiRouteUrlRegExpTest(String url){ - String urlReg = "^\\/"+RouteUtil.API_ROOT_PATH+"\\/.*$"; + String urlReg = "^\\/"+ConfigUtil.getInstance().getAPI_ROOT_PATH()+"\\/.*$"; return Pattern.matches(urlReg, url); } public static boolean iuiRouteUrlRegExpTest(String url){ - String urlReg = "^\\/"+RouteUtil.IUI_ROOT_PATH+"\\/.*$"; + 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; + } +} - - - public static void main(String[] args) { - System.out.println(urlRegExpTest("/api ")); -// System.out.println("api".startsWith("/")); - } } 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 labelMap) { + + Map labelMapMatches = ConfigUtil.getInstance().getLabelMapMatches(); + + if (labelMapMatches == null || labelMapMatches.isEmpty()) { + return true; + } + + for (Map.Entry 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 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 + * @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 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 + * @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 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 baseMap = + (Map) 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 nsMap = + (Map) 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 labelMap = + (Map) 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 transMicroServiceInfoFromConsul( + List serviceNodeList) { + // 同名多版本服务MAP + Map microServiceInfo4version = + new HashMap(); + + + 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 nodes = new HashSet(); + + Service service = serviceNode.getService(); + String serviceName = service.getService(); + + try { + List tagList = service.getTags(); + + for (String tag : tagList) { + + if (tag.startsWith("\"base\"")) { + String ms_base_json = tag.split("\"base\":")[1]; + + + Map baseMap = + (Map) 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 nsMap = + (Map) 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 labelMap = + (Map) 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 lbMap = + (Map) 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 newNodes = microServiceInfo4version.get(version).getNodes(); + // 默认node是注册信息的IP和port + newNodes.add(new Node(service.getAddress(), String.valueOf(service.getPort()))); + + // 同名多版本同步 + microServiceInfo4version.get(version).setNodes(newNodes); + + } + + + /* + * // 健康检查信息 List checks = value.getChecks(); node.setStatus("passing"); for (Check + * check : checks) { if (!"passing".equals(check.getStatus())) { + * node.setStatus(check.getStatus()); break; } } + */ + + + + } + + return microServiceInfo4version; + + } + +} diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/META-INF/MANIFEST.MF b/apiroute/apiroute-service/src/main/resources/api-doc/META-INF/MANIFEST.MF similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/META-INF/MANIFEST.MF rename to apiroute/apiroute-service/src/main/resources/api-doc/META-INF/MANIFEST.MF diff --git a/apiroute/apiroute-service/src/main/resources/api-doc/WEB-INF/web.xml b/apiroute/apiroute-service/src/main/resources/api-doc/WEB-INF/web.xml new file mode 100644 index 0000000..7d51568 --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/api-doc/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + + + ZENAP API-DOC. + + ZENAP API-DOC + + + + + index.html + index.xhtml + index.htm + index.jsp + + + + diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css b/apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css similarity index 60% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css rename to apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css index 6c9e9e6..b2b0789 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css +++ b/apiroute/apiroute-service/src/main/resources/api-doc/css/reset.css @@ -1,21 +1,3 @@ -/** - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */ html, body, diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css b/apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css similarity index 98% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css rename to apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css index 92881b7..32b199b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css +++ b/apiroute/apiroute-service/src/main/resources/api-doc/css/screen.css @@ -1,21 +1,3 @@ -/** - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ /* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ .swagger-section pre code { display: block; diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css b/apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css rename to apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css index 877304f..27c3751 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css +++ b/apiroute/apiroute-service/src/main/resources/api-doc/css/typography.css @@ -1,21 +1,3 @@ -/** - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ /* droid-sans-regular - latin */ @font-face { font-family: 'Droid Sans'; diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.eot b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.eot similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.eot rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.eot diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.svg b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.svg similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.svg rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.svg diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.ttf b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.ttf similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.ttf rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.ttf diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff2 b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff2 similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff2 rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-700.woff2 diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.eot b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.eot similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.eot rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.eot diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.svg b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.svg similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.svg rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.svg diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.ttf b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.ttf similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.ttf rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.ttf diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff2 b/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff2 similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff2 rename to apiroute/apiroute-service/src/main/resources/api-doc/fonts/droid-sans-v6-latin-regular.woff2 diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/explorer_icons.png b/apiroute/apiroute-service/src/main/resources/api-doc/images/explorer_icons.png similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/explorer_icons.png rename to apiroute/apiroute-service/src/main/resources/api-doc/images/explorer_icons.png diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/logo_small.png b/apiroute/apiroute-service/src/main/resources/api-doc/images/logo_small.png similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/logo_small.png rename to apiroute/apiroute-service/src/main/resources/api-doc/images/logo_small.png diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/pet_store_api.png b/apiroute/apiroute-service/src/main/resources/api-doc/images/pet_store_api.png similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/pet_store_api.png rename to apiroute/apiroute-service/src/main/resources/api-doc/images/pet_store_api.png diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/throbber.gif b/apiroute/apiroute-service/src/main/resources/api-doc/images/throbber.gif similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/throbber.gif rename to apiroute/apiroute-service/src/main/resources/api-doc/images/throbber.gif diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/wordnik_api.png b/apiroute/apiroute-service/src/main/resources/api-doc/images/wordnik_api.png similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/images/wordnik_api.png rename to apiroute/apiroute-service/src/main/resources/api-doc/images/wordnik_api.png diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/index.html b/apiroute/apiroute-service/src/main/resources/api-doc/index.html similarity index 83% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/index.html rename to apiroute/apiroute-service/src/main/resources/api-doc/index.html index ee78118..944b1f3 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/index.html +++ b/apiroute/apiroute-service/src/main/resources/api-doc/index.html @@ -1,121 +1,120 @@ - - - - - Swagger UI - - - - - - - - - - - - - - - - - - - - - - - - - -

- -
 
-
- - - + + + + + Swagger UI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+
+ + + diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/iframeResizer/iframeResizer.contentWindow.min.js b/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/iframeResizer/iframeResizer.contentWindow.min.js rename to apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/iframeResizer/iframeResizer.min.js b/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/iframeResizer/iframeResizer.min.js rename to apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js diff --git a/apiroute/apiroute-service/src/main/resources/api-doc/js/tools.js b/apiroute/apiroute-service/src/main/resources/api-doc/js/tools.js new file mode 100644 index 0000000..21ecd51 --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/api-doc/js/tools.js @@ -0,0 +1,1054 @@ +/* + * Copyright (C) 2015 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. + */ +////合并hk.min.js +/*! store2 - v2.3.0 - 2015-05-22 +* Copyright (c) 2015 Nathan Bubna; Licensed MIT, GPL */ +;(function(window, define) { + var _ = { + version: "2.3.0", + areas: {}, + apis: {}, + + // utilities + inherit: function(api, o) { + for (var p in api) { + if (!o.hasOwnProperty(p)) { + o[p] = api[p]; + } + } + return o; + }, + stringify: function(d) { + return d === undefined || typeof d === "function" ? d+'' : JSON.stringify(d); + }, + parse: function(s) { + // if it doesn't parse, return as is + try{ return JSON.parse(s); }catch(e){ return s; } + }, + + // extension hooks + fn: function(name, fn) { + _.storeAPI[name] = fn; + for (var api in _.apis) { + _.apis[api][name] = fn; + } + }, + get: function(area, key){ return area.getItem(key); }, + set: function(area, key, string){ area.setItem(key, string); }, + remove: function(area, key){ area.removeItem(key); }, + key: function(area, i){ return area.key(i); }, + length: function(area){ return area.length; }, + clear: function(area){ area.clear(); }, + + // core functions + Store: function(id, area, namespace) { + var store = _.inherit(_.storeAPI, function(key, data, overwrite) { + if (arguments.length === 0){ return store.getAll(); } + if (data !== undefined){ return store.set(key, data, overwrite); } + if (typeof key === "string"){ return store.get(key); } + if (!key){ return store.clear(); } + return store.setAll(key, data);// overwrite=data, data=key + }); + store._id = id; + try { + var testKey = '_safariPrivate_'; + area.setItem(testKey, 'sucks'); + store._area = area; + area.removeItem(testKey); + } catch (e) {} + if (!store._area) { + store._area = _.inherit(_.storageAPI, { items: {}, name: 'fake' }); + } + store._ns = namespace || ''; + if (!_.areas[id]) { + _.areas[id] = store._area; + } + if (!_.apis[store._ns+store._id]) { + _.apis[store._ns+store._id] = store; + } + return store; + }, + storeAPI: { + // admin functions + area: function(id, area) { + var store = this[id]; + if (!store || !store.area) { + store = _.Store(id, area, this._ns);//new area-specific api in this namespace + if (!this[id]){ this[id] = store; } + } + return store; + }, + namespace: function(namespace, noSession) { + if (!namespace){ + return this._ns ? this._ns.substring(0,this._ns.length-1) : ''; + } + var ns = namespace, store = this[ns]; + if (!store || !store.namespace) { + store = _.Store(this._id, this._area, this._ns+ns+'.');//new namespaced api + if (!this[ns]){ this[ns] = store; } + if (!noSession){ store.area('session', _.areas.session); } + } + return store; + }, + isFake: function(){ return this._area.name === 'fake'; }, + toString: function() { + return 'store'+(this._ns?'.'+this.namespace():'')+'['+this._id+']'; + }, + + // storage functions + has: function(key) { + if (this._area.has) { + return this._area.has(this._in(key));//extension hook + } + return !!(this._in(key) in this._area); + }, + size: function(){ return this.keys().length; }, + each: function(fn, and) { + for (var i=0, m=_.length(this._area); i _.length(this._area)) { m--; i--; }// in case of removeItem + } + return and || this; + }, + keys: function() { + return this.each(function(k, list){ list.push(k); }, []); + }, + get: function(key, alt) { + var s = _.get(this._area, this._in(key)); + return s !== null ? _.parse(s) : alt || s;// support alt for easy default mgmt + }, + getAll: function() { + return this.each(function(k, all){ all[k] = this.get(k); }, {}); + }, + set: function(key, data, overwrite) { + var d = this.get(key); + if (d != null && overwrite === false) { + return data; + } + return _.set(this._area, this._in(key), _.stringify(data), overwrite) || d; + }, + setAll: function(data, overwrite) { + var changed, val; + for (var key in data) { + val = data[key]; + if (this.set(key, val, overwrite) !== val) { + changed = true; + } + } + return changed; + }, + remove: function(key) { + var d = this.get(key); + _.remove(this._area, this._in(key)); + return d; + }, + clear: function() { + if (!this._ns) { + _.clear(this._area); + } else { + this.each(function(k){ _.remove(this._area, this._in(k)); }, 1); + } + return this; + }, + clearAll: function() { + var area = this._area; + for (var id in _.areas) { + if (_.areas.hasOwnProperty(id)) { + this._area = _.areas[id]; + this.clear(); + } + } + this._area = area; + return this; + }, + + // internal use functions + _in: function(k) { + if (typeof k !== "string"){ k = _.stringify(k); } + return this._ns ? this._ns + k : k; + }, + _out: function(k) { + return this._ns ? + k && k.indexOf(this._ns) === 0 ? + k.substring(this._ns.length) : + undefined : // so each() knows to skip it + k; + } + },// end _.storeAPI + storageAPI: { + length: 0, + has: function(k){ return this.items.hasOwnProperty(k); }, + key: function(i) { + var c = 0; + for (var k in this.items){ + if (this.has(k) && i === c++) { + return k; + } + } + }, + setItem: function(k, v) { + if (!this.has(k)) { + this.length++; + } + this.items[k] = v; + }, + removeItem: function(k) { + if (this.has(k)) { + delete this.items[k]; + this.length--; + } + }, + getItem: function(k){ return this.has(k) ? this.items[k] : null; }, + clear: function(){ for (var k in this.list){ this.removeItem(k); } }, + toString: function(){ return this.length+' items in '+this.name+'Storage'; } + }// end _.storageAPI + }; + + // setup the primary store fn + if (window.store){ _.conflict = window.store; } + var store = + // safely set this up (throws error in IE10/32bit mode for local files) + _.Store("local", (function(){try{ return localStorage; }catch(e){}})()); + store.local = store;// for completeness + store._ = _;// for extenders and debuggers... + // safely setup store.session (throws exception in FF for file:/// urls) + store.area("session", (function(){try{ return sessionStorage; }catch(e){}})()); + + //Expose store to the global object + window.store = store; + + if (typeof define === 'function' && define.amd !== undefined) { + define(function () { + return store; + }); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = store; + } + +})(this, null); + +// XHook - v1.3.3 - https://github.com/jpillora/xhook +// Jaime Pillora - MIT Copyright 2015 +(function(window,undefined) { +var AFTER, BEFORE, COMMON_EVENTS, EventEmitter, FIRE, FormData, NativeFormData, NativeXMLHttp, OFF, ON, READY_STATE, UPLOAD_EVENTS, XHookFormData, XHookHttpRequest, XMLHTTP, convertHeaders, depricatedProp, document, fakeEvent, mergeObjects, msie, proxyEvents, slice, xhook, _base, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + +document = window.document; + +BEFORE = 'before'; + +AFTER = 'after'; + +READY_STATE = 'readyState'; + +ON = 'addEventListener'; + +OFF = 'removeEventListener'; + +FIRE = 'dispatchEvent'; + +XMLHTTP = 'XMLHttpRequest'; + +FormData = 'FormData'; + +UPLOAD_EVENTS = ['load', 'loadend', 'loadstart']; + +COMMON_EVENTS = ['progress', 'abort', 'error', 'timeout']; + +msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]); + +if (isNaN(msie)) { + msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]); +} + +(_base = Array.prototype).indexOf || (_base.indexOf = function(item) { + var i, x, _i, _len; + for (i = _i = 0, _len = this.length; _i < _len; i = ++_i) { + x = this[i]; + if (x === item) { + return i; + } + } + return -1; +}); + +slice = function(o, n) { + return Array.prototype.slice.call(o, n); +}; + +depricatedProp = function(p) { + return p === "returnValue" || p === "totalSize" || p === "position"; +}; + +mergeObjects = function(src, dst) { + var k, v; + for (k in src) { + v = src[k]; + if (depricatedProp(k)) { + continue; + } + try { + dst[k] = src[k]; + } catch (_error) {} + } + return dst; +}; + +proxyEvents = function(events, src, dst) { + var event, p, _i, _len; + p = function(event) { + return function(e) { + var clone, k, val; + clone = {}; + for (k in e) { + if (depricatedProp(k)) { + continue; + } + val = e[k]; + clone[k] = val === src ? dst : val; + } + return dst[FIRE](event, clone); + }; + }; + for (_i = 0, _len = events.length; _i < _len; _i++) { + event = events[_i]; + if (dst._has(event)) { + src["on" + event] = p(event); + } + } +}; + +fakeEvent = function(type) { + var msieEventObject; + if (document.createEventObject != null) { + msieEventObject = document.createEventObject(); + msieEventObject.type = type; + return msieEventObject; + } else { + try { + return new Event(type); + } catch (_error) { + return { + type: type + }; + } + } +}; + +EventEmitter = function(nodeStyle) { + var emitter, events, listeners; + events = {}; + listeners = function(event) { + return events[event] || []; + }; + emitter = {}; + emitter[ON] = function(event, callback, i) { + events[event] = listeners(event); + if (events[event].indexOf(callback) >= 0) { + return; + } + i = i === undefined ? events[event].length : i; + events[event].splice(i, 0, callback); + }; + emitter[OFF] = function(event, callback) { + var i; + if (event === undefined) { + events = {}; + return; + } + if (callback === undefined) { + events[event] = []; + } + i = listeners(event).indexOf(callback); + if (i === -1) { + return; + } + listeners(event).splice(i, 1); + }; + emitter[FIRE] = function() { + var args, event, i, legacylistener, listener, _i, _len, _ref; + args = slice(arguments); + event = args.shift(); + if (!nodeStyle) { + args[0] = mergeObjects(args[0], fakeEvent(event)); + } + legacylistener = emitter["on" + event]; + if (legacylistener) { + legacylistener.apply(undefined, args); + } + _ref = listeners(event).concat(listeners("*")); + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + listener = _ref[i]; + listener.apply(undefined, args); + } + }; + emitter._has = function(event) { + return !!(events[event] || emitter["on" + event]); + }; + if (nodeStyle) { + emitter.listeners = function(event) { + return slice(listeners(event)); + }; + emitter.on = emitter[ON]; + emitter.off = emitter[OFF]; + emitter.fire = emitter[FIRE]; + emitter.once = function(e, fn) { + var fire; + fire = function() { + emitter.off(e, fire); + return fn.apply(null, arguments); + }; + return emitter.on(e, fire); + }; + emitter.destroy = function() { + return events = {}; + }; + } + return emitter; +}; + +xhook = EventEmitter(true); + +xhook.EventEmitter = EventEmitter; + +xhook[BEFORE] = function(handler, i) { + if (handler.length < 1 || handler.length > 2) { + throw "invalid hook"; + } + return xhook[ON](BEFORE, handler, i); +}; + +xhook[AFTER] = function(handler, i) { + if (handler.length < 2 || handler.length > 3) { + throw "invalid hook"; + } + return xhook[ON](AFTER, handler, i); +}; + +xhook.enable = function() { + window[XMLHTTP] = XHookHttpRequest; + if (NativeFormData) { + window[FormData] = XHookFormData; + } +}; + +xhook.disable = function() { + window[XMLHTTP] = xhook[XMLHTTP]; + window[FormData] = NativeFormData; +}; + +convertHeaders = xhook.headers = function(h, dest) { + var header, headers, k, name, v, value, _i, _len, _ref; + if (dest == null) { + dest = {}; + } + switch (typeof h) { + case "object": + headers = []; + for (k in h) { + v = h[k]; + name = k.toLowerCase(); + headers.push("" + name + ":\t" + v); + } + return headers.join('\n'); + case "string": + headers = h.split('\n'); + for (_i = 0, _len = headers.length; _i < _len; _i++) { + header = headers[_i]; + if (/([^:]+):\s*(.+)/.test(header)) { + name = (_ref = RegExp.$1) != null ? _ref.toLowerCase() : void 0; + value = RegExp.$2; + if (dest[name] == null) { + dest[name] = value; + } + } + } + return dest; + } +}; + +NativeFormData = window[FormData]; + +XHookFormData = function(form) { + var entries; + this.fd = form ? new NativeFormData(form) : new NativeFormData(); + this.form = form; + entries = []; + Object.defineProperty(this, 'entries', { + get: function() { + var fentries; + fentries = !form ? [] : slice(form.querySelectorAll("input,select")).filter(function(e) { + var _ref; + return ((_ref = e.type) !== 'checkbox' && _ref !== 'radio') || e.checked; + }).map(function(e) { + return [e.name, e.type === "file" ? e.files : e.value]; + }); + return fentries.concat(entries); + } + }); + this.append = (function(_this) { + return function() { + var args; + args = slice(arguments); + entries.push(args); + return _this.fd.append.apply(_this.fd, args); + }; + })(this); +}; + +if (NativeFormData) { + xhook[FormData] = NativeFormData; + window[FormData] = XHookFormData; +} + +NativeXMLHttp = window[XMLHTTP]; + +xhook[XMLHTTP] = NativeXMLHttp; + +XHookHttpRequest = window[XMLHTTP] = function() { + var ABORTED, currentState, emitFinal, emitReadyState, facade, hasError, hasErrorHandler, readBody, readHead, request, response, setReadyState, status, transiting, writeBody, writeHead, xhr; + ABORTED = -1; + xhr = new xhook[XMLHTTP](); + request = {}; + status = null; + hasError = void 0; + transiting = void 0; + response = void 0; + readHead = function() { + var key, name, val, _ref; + response.status = status || xhr.status; + if (!(status === ABORTED && msie < 10)) { + response.statusText = xhr.statusText; + } + if (status !== ABORTED) { + _ref = convertHeaders(xhr.getAllResponseHeaders()); + for (key in _ref) { + val = _ref[key]; + if (!response.headers[key]) { + name = key.toLowerCase(); + response.headers[name] = val; + } + } + } + }; + readBody = function() { + if (!xhr.responseType || xhr.responseType === "text") { + response.text = xhr.responseText; + response.data = xhr.responseText; + } else if (xhr.responseType === "document") { + response.xml = xhr.responseXML; + response.data = xhr.responseXML; + } else { + response.data = xhr.response; + } + try{ + if(response.data){ + // checked login time out reload to login + var data = $.parseJSON(response.data); + if(data.source && data.redirect_uri && data.source === "smagent"){ + var redirect_uri = data.redirect_uri; + if(top){ + top.location = redirect_uri.replace('$1', encodeURIComponent(top.location)); + }else{ + window.location = redirect_uri.replace('$1', encodeURIComponent(window.location)); + } + } + } + }catch(e){} + + if ("responseURL" in xhr) { + response.finalUrl = xhr.responseURL; + } + }; + writeHead = function() { + facade.status = response.status; + facade.statusText = response.statusText; + }; + writeBody = function() { + if ('text' in response) { + facade.responseText = response.text; + } + if ('xml' in response) { + facade.responseXML = response.xml; + } + if ('data' in response) { + facade.response = response.data; + } + if ('finalUrl' in response) { + facade.responseURL = response.finalUrl; + } + }; + emitReadyState = function(n) { + while (n > currentState && currentState < 4) { + facade[READY_STATE] = ++currentState; + if (currentState === 1) { + facade[FIRE]("loadstart", {}); + } + if (currentState === 2) { + writeHead(); + } + if (currentState === 4) { + writeHead(); + writeBody(); + } + facade[FIRE]("readystatechange", {}); + if (currentState === 4) { + setTimeout(emitFinal, 0); + } + } + }; + emitFinal = function() { + if (!hasError) { + facade[FIRE]("load", {}); + } + facade[FIRE]("loadend", {}); + if (hasError) { + facade[READY_STATE] = 0; + } + }; + currentState = 0; + setReadyState = function(n) { + var hooks, process; + if (n !== 4) { + emitReadyState(n); + return; + } + hooks = xhook.listeners(AFTER); + process = function() { + var hook; + if (!hooks.length) { + return emitReadyState(4); + } + hook = hooks.shift(); + if (hook.length === 2) { + hook(request, response); + return process(); + } else if (hook.length === 3 && request.async) { + return hook(request, response, process); + } else { + return process(); + } + }; + process(); + }; + facade = request.xhr = EventEmitter(); + xhr.onreadystatechange = function(event) { + try { + if (xhr[READY_STATE] === 2) { + readHead(); + } + } catch (_error) {} + if (xhr[READY_STATE] === 4) { + transiting = false; + readHead(); + readBody(); + } + setReadyState(xhr[READY_STATE]); + }; + hasErrorHandler = function() { + hasError = true; + }; + facade[ON]('error', hasErrorHandler); + facade[ON]('timeout', hasErrorHandler); + facade[ON]('abort', hasErrorHandler); + facade[ON]('progress', function() { + if (currentState < 3) { + setReadyState(3); + } else { + facade[FIRE]("readystatechange", {}); + } + }); + if ('withCredentials' in xhr || xhook.addWithCredentials) { + facade.withCredentials = false; + } + facade.status = 0; + facade.open = function(method, url, async, user, pass) { + currentState = 0; + hasError = false; + transiting = false; + request.headers = {}; + request.headerNames = {}; + request.status = 0; + response = {}; + response.headers = {}; + request.method = method; + request.url = url; + request.async = async !== false; + request.user = user; + request.pass = pass; + setReadyState(1); + }; + facade.send = function(body) { + var hooks, k, modk, process, send, _i, _len, _ref; + _ref = ['type', 'timeout', 'withCredentials']; + if(navigator.userAgent.indexOf("Firefox/") != -1){http://atmosphere-framework.2306103.n4.nabble.com/Atmosphere-js-withCredentials-true-does-not-work-in-Firefox-td4656661.html + _ref = ['type', 'timeout']; + } + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + modk = k === "type" ? "responseType" : k; + if (modk in facade) { + request[k] = facade[modk]; + } + } + request.body = body; + send = function() { + var header, value, _j, _len1, _ref1, _ref2; + proxyEvents(COMMON_EVENTS, xhr, facade); + if (facade.upload) { + proxyEvents(COMMON_EVENTS.concat(UPLOAD_EVENTS), xhr.upload, facade.upload); + } + transiting = true; + xhr.open(request.method, request.url, request.async, request.user, request.pass); + _ref1 = ['type', 'timeout', 'withCredentials']; + if(navigator.userAgent.indexOf("Firefox/") != -1){//http://atmosphere-framework.2306103.n4.nabble.com/Atmosphere-js-withCredentials-true-does-not-work-in-Firefox-td4656661.html + _ref1 = ['type', 'timeout']; + } + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + k = _ref1[_j]; + modk = k === "type" ? "responseType" : k; + if (k in request) { + xhr[modk] = request[k]; + } + } + _ref2 = request.headers; + for (header in _ref2) { + value = _ref2[header]; + xhr.setRequestHeader(header, value); + } + if (request.body instanceof XHookFormData) { + request.body = request.body.fd; + } + xhr.send(request.body); + }; + hooks = xhook.listeners(BEFORE); + process = function() { + var done, hook; + if (!hooks.length) { + return send(); + } + done = function(userResponse) { + if (typeof userResponse === 'object' && (typeof userResponse.status === 'number' || typeof response.status === 'number')) { + mergeObjects(userResponse, response); + if (__indexOf.call(userResponse, 'data') < 0) { + userResponse.data = userResponse.response || userResponse.text; + } + setReadyState(4); + return; + } + process(); + }; + done.head = function(userResponse) { + mergeObjects(userResponse, response); + return setReadyState(2); + }; + done.progress = function(userResponse) { + mergeObjects(userResponse, response); + return setReadyState(3); + }; + hook = hooks.shift(); + if (hook.length === 1) { + return done(hook(request)); + } else if (hook.length === 2 && request.async) { + return hook(request, done); + } else { + return done(); + } + }; + process(); + }; + facade.abort = function() { + status = ABORTED; + if (transiting) { + xhr.abort(); + } else { + facade[FIRE]('abort', {}); + } + }; + facade.setRequestHeader = function(header, value) { + var lName, name; + lName = header != null ? header.toLowerCase() : void 0; + name = request.headerNames[lName] = request.headerNames[lName] || header; + if (request.headers[name]) { + value = request.headers[name] + ', ' + value; + } + request.headers[name] = value; + }; + facade.getResponseHeader = function(header) { + var name; + name = header != null ? header.toLowerCase() : void 0; + return response.headers[name]; + }; + facade.getAllResponseHeaders = function() { + return convertHeaders(response.headers); + }; + if (xhr.overrideMimeType) { + facade.overrideMimeType = function() { + return xhr.overrideMimeType.apply(xhr, arguments); + }; + } + if (xhr.upload) { + facade.upload = request.upload = EventEmitter(); + } + return facade; +}; +/* +if (typeof this.define === "function" && this.define.amd) { + define("xhook", [], function() { + return xhook; + }); +} else {*/ + (this.exports || this).xhook = xhook; +//} + +}.call(this,window)); + +xhook.before(function(request) { + var zte_headers = store('zte_http_headers'); + if (zte_headers && zte_headers.length > 0) { + for (i = 0; i < zte_headers.length; i++) { + if (zte_headers[i].store === true) { + if ( !! store(zte_headers[i].value)) { + request.headers[zte_headers[i].key] = store(zte_headers[i].value); + } + } else { + request.headers[zte_headers[i].key] = zte_headers[i].value; + } + } + } +}); +/** + * 初始化脚本文件装载工具 + * zongying 2010.12 + * modify: + */ +$Boot = {}; + +/** + * 创建命名空间 + * @param {Object} name + * @param {Object} object + */ +$Boot.createNamespace = function(name, object) { + var splits = name.split("."); + var parent = window; + //document.window浏览器内置对象 + var part = splits[0]; + for (var i = 0, len = splits.length - 1; i < len; i++, part = splits[i]) { + if (!parent[part]) { + parent = parent[part] = {}; + } else { + parent = parent[part]; + } + } + // 存放对象 + parent[part] = object; + // 返回 last part name (例如:classname) + return part; +} + +$Boot.isDefined = function(o) { + return typeof (o) != "undefined" +} +/** + * 启动配置类 + */ +$Boot.Config = function() { + + function isDefined(o) { + return typeof (o) != "undefined" + } + + //用户应用当前目录 + if (!isDefined(window.$userAppDir)) { + window.$userAppDir = './' + } + //组件库目录 + if (!isDefined(window.$userFrameDir)) { + window.$userFrameDir = '/common/' + } + //用户i18文件目录 + if (!isDefined(window.$userI18nDir)) { + window.$userI18nDir = './' + } + + //当前语言 默认为英语 + var language = "zh-CN"; + //var languageList = ['ar', 'ba', 'cr', 'cs', 'de', 'el', 'es', 'fi', 'fr', 'fr-FR', 'hu-HU', 'id', 'it', 'ja', 'nb-NO', 'nl', 'pl', 'pl-PL', 'pt', 'pt-BR', 'ro-RO', 'ru-RU', 'sk', 'sr', 'sr-Latn', 'sv-SE', 'en-US','uk-UA', 'zh-CN', 'zh-TW']; + var languageList = ['en-US', 'zh-CN']; + + //从服务端取客户端接受语言类型 + var getAcceptLangFromServer = true; + + + /** + * 创建XMLHttpRequest对象 + */ + function createXMLHttpRequest() { + if (window.ActiveXObject) { + return new ActiveXObject("Microsoft.XMLHTTP"); + } else if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } else { + throw new Error("This Brower do not support XMLHTTP!!"); + } + } + + + /** + * 同步发送xml http 请求 + * @param {Object} url + * @param {Object} data + * @param {Object} method + */ + function httpRequest(method, url, data) { + var xmlhttp; + xmlhttp = createXMLHttpRequest(); + var sendData = null; + if (method == "get") { + url = url + "?" + data; + + } else if (method == "post") { + sendData = data; + } + xmlhttp.open(method, url, false); + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + xmlhttp.setRequestHeader("If-Modified-Since", "0"); + xmlhttp.send(sendData); + if (xmlhttp.status == 200) + return xmlhttp.responseText; + } + + /** + * 同步发送xml http 请求(给外部调用) + * @param {Object} url + * @param {Object} data + * @param {Object} method + */ + this.httpRequestStatic = function(method, url, data) { + var xmlhttp; + xmlhttp = createXMLHttpRequest(); + var sendData = null; + if (method == "get") { + url = url + "?" + data; + + } else if (method == "post") { + sendData = data; + } + xmlhttp.open(method, url, false); + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + xmlhttp.setRequestHeader("If-Modified-Since", "0"); + xmlhttp.send(sendData); + if (xmlhttp.status == 200) + return xmlhttp.responseText; + } + + function inArray(array, obj) { + for (var i = 0; i < array.length; i++) { + if (array[i] == obj) { + return true; + } + } + return false; + + } + + /** + * 取得浏览器语言信息 + */ + this.getLanguage = function() { + var rtnLanguage = localStorage.getItem("language-option"); + if( rtnLanguage == "null" || rtnLanguage == null ){ + rtnLanguage = window.navigator.userLanguage||window.navigator.language; + } + if( rtnLanguage == '"zh-CN"' || rtnLanguage == "zh-CN" ){ + return "zh-CN"; + }else{ + return "en-US"; + } + //return "en-US"; + } + + this.getUrlParam=function(name){ + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 + var search =decodeURIComponent(location.search.substring(1)); //decodeURIComponent() 函数可对 encodeURIComponent() 函数编码的 URI 进行解码。 + var r =search.match(reg); //匹配目标参数 + if (r != null) return unescape(r[2]); //unescape() 函数可对通过 escape() 编码的字符串进行解码。 + return null; //返回参数值 + } + + +} + +//创建命名空间 +$Boot.createNamespace("com.zte.ums.aos.framework.BootConfig", $Boot.Config); +//创建基础配置对象实例 +$Boot.bootConfig = new com.zte.ums.aos.framework.BootConfig(); + +function getLanguage(){ + return $Boot.bootConfig.getLanguage(); +} + +function getStringWidth(text,fontSize) +{ + var span = document.getElementById("_ictframework_getwidth"); + if (span == null) { + span = document.createElement("span"); + span.id = "_ictframework_getwidth"; + document.body.appendChild(span); + } + span.innerText = text; + span.style.whiteSpace = "nowrap"; + $("#_ictframework_getwidth").attr('style','font-size:'+fontSize+'px;'); + var width = span.offsetWidth; + $("#_ictframework_getwidth").attr('style','display:none'); + return width; +} + +function getUrlParam(name){ + return $Boot.bootConfig.getUrlParam(name); +} + +function httpRequest(method, url, data) { + return $Boot.bootConfig.httpRequestStatic(method, url, data) +} + +// 定义JQUERY AJAX 完成函数,判断返回状态,如果状态正常,但HEADER头里有session超时信息,则刷新重登录 +// 如果状态为 401, 也刷新重登录 +// 注意如果在$.ajax() 函数中定义了 complete,则覆盖了这里预定义complete内容,以$.ajax()函数中定义的为准,这里预定义的函数则失效,如果 +// 要继续判断session超时,则需要在 $.ajax()函数中定义的complete函数中加入这里预定义内容。 +if (jQuery) { + $.ajaxSetup({ + complete:function(XMLHttpRequest,textStatus){ + if (XMLHttpRequest.status == 401) { + window.location.replace("login.html"); + } + // if (XMLHttpRequest.status == 200) { + // var sessionstatus=XMLHttpRequest.getResponseHeader("sessionstatus"); ////通过XMLHttpRequest取得响应头,sessionstatus, + // if(sessionstatus=="timeout"){ + // window.location.replace("/"); + // } + // } else if (XMLHttpRequest.status == 401) { + // window.location.replace("/"); + // } + } + }); +} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js b/apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js similarity index 96% rename from msb-core/apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js rename to apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js index 28acba2..a3f544b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js +++ b/apiroute/apiroute-service/src/main/resources/api-doc/lib/backbone-min.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ // Backbone.js 1.1.2 (function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$(' + + + + + + + + + + + + + \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js b/apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js similarity index 86% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js rename to apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js index 17642ab..f1b0277 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/i18n/loadi18nApp_iui-route_view.js @@ -1,20 +1,17 @@ /* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. + * 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 + * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn */ function loadPropertiesSideMenu(lang, propertiesFileNamePrefix, propertiesFilePath){ jQuery.i18n.properties({ @@ -24,7 +21,7 @@ function loadPropertiesSideMenu(lang, propertiesFileNamePrefix, propertiesFilePa mode:'map', // 用 Map 的方式使用资源文件中的值 callback: function() {// 加载成功后设置显示内容 - var i18nItems = $('[name_i18n=org_openo_msb_route_ui_i18n]'); + var i18nItems = $('[name_i18n=org_onap_msb_route_ui_i18n]'); for(var i=0;iep1;d-f0p@BiNacDA~@ zy1M$S??0-#nGgboWmx{yMeX^~IOou3@y}8HXd{N|qyC#`nD^+lHQOg$auM)&9GV{f z4=|dxO;IWm*8pP+v5tpom)Sneq@&lYUH#GU;~EAk$!OG?ezdV!c;2nPZ7;2wb`VTB z_iU(`G!fAy_>{{p^>_U0nN8hm-n|qUe9SfNDy%<#fc+enKSSX~zuhv=H9?4bJ;OL0 z8FOjlSN;$Z2Q-ZHO!FS!wBFE0k3MeFqD$a_3omeEKh*1hS}a7-t}}{uIln=Mm<*%TOPzopV5r~sN+z7DBBPLeQZO$ zx6F2FOn)T*mfIgD$GIEzJ=C{R)5R6gwHs8Rwjhh%%}jHNx_`a5-**;3%@KzIn*M2C zHg`Q9zaZe8Maa4f)XK`m4HumE=!ipRL(7XVzi6!A@EWMOShcg8E^Z zK)nf78H6$3g!(Y*1EqkCV*2}%Cz)*@4V>SZJmPRKcIhQBcJASEH1n7Fj`L;+NPA== zg830Qn|*5J%o&H&UA_oX#~o{URaMs_=!pfFm3^y%CMX;s2Yj$V+QV#*61y?ifzGM3 zz!*6em``yaSP{-oNVd|-ysi^amhMOYDc1NwgnEnm;esUxX^f|!-bR>09W_`${g`>) zLS|WK*#|VN@A&RHkX&#QVq=tFcfk(6QaS><6zW`>j7$1p~-jI=j6_vk2*3!y^B#BK4;hS zxCqSOCs4@&d;kGD&rc-&JN2#k(0=|xK(LP2EbGo4sqE|Tws+0TIIgRqiDZ3T2mwt< z^|qul74Nrq-Np@Lxi@;$iJfPj0bQq^3eNa(|H4gk9=aBfmBDv%Q_Pr z=T~;or%i+Epny_D^exu|VJ%I0{{(K*0a2AL7zJD$Iab3wVa@kHn{m%hh_hvbEQRE6ac}qbs zy&Tj31e)FXieufLte@&^KW!lxa}L%qfVvFXb!90?cheGH5=}qruq=I5Ydim_D``8z z_jHx}t%hl@YVGhp=}yLwQiyTG`Y{0~!!OVsc+Q?Ysj=m(??TJWuVt9;|CkAXzD(1U z$^ijo@Am_wJ?A|aP+pHZq7SoAL6eDkrHuH49^}-00MxIe9vo0kfo_xZ=Tia4ua%ai zzY;H_?!A)TgWRmhK>Zo_y|ryK4u__Br+}@*=Ax;88G(2|L|Cy>3Z_xnl+MI{x2@e? zwWU3`x~-F?99xg#!%Aa(GIyOfTuWTJ>#IjsHGk~{G9150pll7OJtClN?EpUkB?9jXI5s|{d@zNE_l6L&dyD+N1NAonbq+#3W*_>bzY8d@NG4=@xgs=L(la$PG{(94*gH`BrmNR{d~8cV(u<5yAl{>iNPGZl>K$Y5cAFWUc)kceKc5U>;9F_mPHlI5qs!wxWPt3N2Ws2&L!%CYH-G_jLzs${ z(MC!JC_!!gbO_Ty*Mwwn?kEXF{~(z^$ZcrcM?ls3^W1jd+_oc50CQw*@rsWxSx(Ee zx_Ww-k{)-HBB!Dw zoD*IG!Kp9~UpApE#g9WW3AdxJ7@$AhBQ-MZR4NoW-P4PE^q@==m6FyE`oXLVBe)HU zOhGLSG5wn&12yj~_Lhbzq}@Hu{^9?+Vk(YP?OR@4s1$$& zZYsmp@jORMGluQxf)|ERHSl~(ap`=wLg2-*KVt7_%PVZL`yvW0l29Ia|B~{HP@h44 zaR6;s^um58qMqE#xnZw*~$TB5vjh5dva;8Ig7Aa}RU4{xO85heAG<)&(L1 zb!78KsM+)Zc(Hilfg?L|iva>i=t&kMKn2FdEDt!2Al3=Y8iE=)_k_YdHOs7cI~QsW zT?OJ`7V1_oycV6$5wtAt1~6t(%53zOkDz{S)D^n2x7HPl9s>MV9fu{}%dj^J5XeIA|vrW<^4C70%D_SWrvF>4rl?y3c3ePAk0y|M1bVg7_d*A>D zZ(>N`VGY8AxmxBbOP31C%szqoLYeK+{@cG8LLkwefTttgJFRv#N2uq^3;`|YzAV|a zteGjzG(Utp*1Cyrz6h~&hv?pa?lZokyvjuWl@r=q+3R{R`M2D*U9GLf*IHYVfdzAG z$GCP~9rt5#m3e*Ubcwl^;)J6Bgl@3Cq<(uq8*?SAI{kP! zCxxV5(u45e{|JRO|9=j!Xq4A{Rk933q=XxL0ZkgB=Y(m@Y1dcjHoKWnc$?w12yM^? z=-&>tk5Ig9_K@JpHX+2~x^*kpSM6+ru7Vcprj-oLOlca-eEOaKI~T_ zwsWuqQK@W!!fvf{J4=Dx(hydq{SSS;^qGKtAZm%a+5WGA5Y^hz)`+n4( zK_1f!1N|P^T*SND3OoFj0WF8SGD;`*Dc$IDh0HNVk;Nf_&;!uFeXoy6GALc%Jw{Hd z*M=H|jP-2*ctFHVe$@TGqW>?l-;uSO-hlcKo`lMdjR-t_2{IpwLHP5lQ?!PpJUKs8evkzLPKTXvok-`4ao zc&=8=qM^dji?-73>q` z3I87Y-cv|VZKsICT8)AOr-@;hHy+22<}Qet6kQ%2+aA&huu zu?3@RIX(L$1cecloEG^+Og^=us)e#WE0MItk={@^r=)FSpbKHoK3^W1uPM5J8!eD+ znlcezwBpGMAobB2D>$Blb~K@NWt+5*#fmXnQ~xW}UqE4L zFb(Bx_Y=|wZk7*=e871K%=f%l0B@Igva9X+%rKdS+GQoI?p{^CO%?v+pJ* z+<*6(=4E3IkkcE$XF9_&+Q~z2LH4YepgCdpA((Gh{H#%BH9>_(@a{RY1`+8sKp<-|82!iHU>#As!R1>*OC&=>zC7 zb&1L<(Bts}yOMhyY@t1AYzE!&tWT_W)rqG9Y)tk~%xOL=&G+px2btp zz63z+f(RQ}1Dx&4(SM^)>s(i9H@~5I8Av9kgYI=hwYdo?+pR+|lS{BjnvHU=A)x#( o4GznfOxW-jr-$W>ApbAG04<(o9W)*Oxc~qF07*qoM6N<$f`{filmGw# literal 0 HcmV?d00001 diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/sidebar-toggler-grey.jpg b/apiroute/apiroute-service/src/main/resources/iui-route/img/sidebar-toggler-grey.jpg similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/sidebar-toggler-grey.jpg rename to apiroute/apiroute-service/src/main/resources/iui-route/img/sidebar-toggler-grey.jpg diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/img/throbber.gif b/apiroute/apiroute-service/src/main/resources/iui-route/img/throbber.gif similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/img/throbber.gif rename to apiroute/apiroute-service/src/main/resources/iui-route/img/throbber.gif diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/up.png b/apiroute/apiroute-service/src/main/resources/iui-route/img/up.png similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/up.png rename to apiroute/apiroute-service/src/main/resources/iui-route/img/up.png diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/zte_logo_16.gif b/apiroute/apiroute-service/src/main/resources/iui-route/img/zte_logo_16.gif similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/zte_logo_16.gif rename to apiroute/apiroute-service/src/main/resources/iui-route/img/zte_logo_16.gif diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/index.html b/apiroute/apiroute-service/src/main/resources/iui-route/index.html similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/index.html rename to apiroute/apiroute-service/src/main/resources/iui-route/index.html index 6b024af..1ee0d07 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/index.html +++ b/apiroute/apiroute-service/src/main/resources/iui-route/index.html @@ -1,1040 +1,1028 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -
-
-
- - - -
- - - - -
- - - -
- -
-
- - -
-
- - {{route.version}} - -
- - - - - - - - - - - - -
- -
- -
- - -
-
-
- - -
- - - -
- - - -
- -
-
- - -
-
- - {{route.servers[0].ip}}:{{route.servers[0].port}} -
- - - - - - - - - -
- -
- -
- -
- -
-
- - -
- - - -
- - - - -
-
- {{routeUtil.showGroupName($index,el)}} - {{customGroupRouteArray[$index].length}} - -
- -
-
-
-
-
-
- - -
-
- - {{elem.servers[0].ip}}:{{elem.servers[0].port}} -
- - - - - - - - - -
- -
-
- -
- - - -
- -
- - -
-
- - -
- - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {{node.ip}}:{{node.port}}:{{node.ttl}} - {{msb.url==""?"/":msb.url}} - - - - -
- -
- - - - - -
- -
- -
- - - -
-
- -
-
- - -
- -
- -
- -
-
- -
- -
-
- - - -
-
- - -
- -
-
- - - - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + +
+ + +
+
+
+ + + +
+ + + + +
+ + + +
+
+ + {{apiGroupByPortArray[$index].length}} + +
+ +
+
+
+ + +
+ +
+
+ + {{routeUtil.showPotocol(route.publish_port,route.publishProtocol)|html}} +
+
+ + {{route.version}} + +
+ + + + + + + + + + + + +
+ +
+
+
+ +
+ + +
+
+
+ + +
+ + + +
+ + + +
+
+ + {{iuiGroupByPortArray[$index].length}} + +
+ +
+
+
+ + +
+ +
+
+ + {{routeUtil.showPotocol(route.publish_port,route.publishProtocol)|html}} +
+
+ + {{route.servers[0].ip}}:{{route.servers[0].port}} +
+ + + + + + + + + +
+ +
+
+
+ +
+ +
+ +
+
+ + +
+ + + +
+ + + + +
+
+ + {{customGroupByPortArray[$index].length}} + +
+ +
+
+
+ + +
+ +
+
+ + {{routeUtil.showPotocol(elem.publish_port,elem.publishProtocol)|html}} +
+
+ + + {{elem.servers[0].ip}}:{{elem.servers[0].port}} +
+ + + + + + + + + +
+ +
+
+ +
+ + + +
+ +
+ + +
+
+ + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{node.ip}}:{{node.port}}:{{node.ttl}} + {{msb.url==""?"/":msb.url}} + + + + +
+ +
+ + + + + +
+ +
+ +
+ + + +
+
+ +
+
+ + +
+ +
+ +
+ +
+
+ +
+ +
+
+ + + +
+ + +
+
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/avalon.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/avalon.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/avalon.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/avalon.js index 5eae6ca..a22bb7d 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/avalon.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/avalon.js @@ -1,4 +1,3 @@ - /*================================================== Copyright (c) 2013-2015 司徒正美 and other contributors http://www.cnblogs.com/rubylouvre/ diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootbox/bootbox.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootbox/bootbox.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootbox/bootbox.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootbox/bootbox.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap-growl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap-growl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap-growl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap-growl.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css index 8ec95e1..2828337 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap-dt.css @@ -1,3 +1,9 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + /*! normalize.css v3.0.0 | MIT License | git.io/normalize */ html { font-family: sans-serif; diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css index 9611bd2..679272d 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/css/bootstrap.min.css @@ -1 +1,7 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + /*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js index a5271e0..8ae571b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.js @@ -1,3 +1,9 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') } /* ======================================================================== diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/js/bootstrap.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/js/bootstrap.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js index fc51ad7..b04a0e8 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/bootstrap/js/bootstrap.min.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js @@ -1,6 +1,6 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js index 65cec39..1d11b34 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap2-typeahead.min.js @@ -17,4 +17,5 @@ * limitations under the License. * ============================================================ */ + !function(t){"use strict";var e=function(e,s){this.$element=t(e),this.options=t.extend({},t.fn.typeahead.defaults,s),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=t(this.options.menu),this.shown=!1,this.listen()};e.prototype={constructor:e,select:function(){var t=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(t)).change(),this.hide()},updater:function(t){return t},show:function(){var e=t.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:e.top+e.height,left:e.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(){var e;return this.query=this.$element.val(),!this.query||this.query.length"+e+""})},render:function(e){var s=this;return e=t(e).map(function(e,i){return e=t(s.options.item).attr("data-value",i),e.find("a").html(s.highlighter(i)),e[0]}),e.first().addClass("active"),this.$menu.html(e),this},next:function(){var e=this.$menu.find(".active").removeClass("active"),s=e.next();s.length||(s=t(this.$menu.find("li")[0])),s.addClass("active")},prev:function(){var t=this.$menu.find(".active").removeClass("active"),e=t.prev();e.length||(e=this.$menu.find("li").last()),e.addClass("active")},listen:function(){this.$element.on("focus",t.proxy(this.focus,this)).on("blur",t.proxy(this.blur,this)).on("keypress",t.proxy(this.keypress,this)).on("keyup",t.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",t.proxy(this.keydown,this)),this.$menu.on("click",t.proxy(this.click,this)).on("mouseenter","li",t.proxy(this.mouseenter,this)).on("mouseleave","li",t.proxy(this.mouseleave,this))},eventSupported:function(t){var e=t in this.$element;return e||(this.$element.setAttribute(t,"return;"),e="function"==typeof this.$element[t]),e},move:function(t){if(this.shown){switch(t.keyCode){case 9:case 13:case 27:t.preventDefault();break;case 38:t.preventDefault(),this.prev();break;case 40:t.preventDefault(),this.next()}t.stopPropagation()}},keydown:function(e){this.suppressKeyPressRepeat=~t.inArray(e.keyCode,[40,38,9,13,27]),this.move(e)},keypress:function(t){this.suppressKeyPressRepeat||this.move(t)},keyup:function(t){switch(t.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}t.stopPropagation(),t.preventDefault()},focus:function(){this.focused=!0},blur:function(){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(t){t.stopPropagation(),t.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(e){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),t(e.currentTarget).addClass("active")},mouseleave:function(){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var s=t.fn.typeahead;t.fn.typeahead=function(s){return this.each(function(){var i=t(this),n=i.data("typeahead"),h="object"==typeof s&&s;n||i.data("typeahead",n=new e(this,h)),"string"==typeof s&&n[s]()})},t.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1},t.fn.typeahead.Constructor=e,t.fn.typeahead.noConflict=function(){return t.fn.typeahead=s,this},t(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(){var e=t(this);e.data("typeahead")||e.typeahead(e.data())})}(window.jQuery); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/dataTables.bootstrap.css b/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/dataTables.bootstrap.css rename to apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css index 4279313..c80d1bf 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/dataTables.bootstrap.css +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css @@ -1,4 +1,3 @@ - div.dataTables_length label { font-weight: normal; text-align: left; diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/dataTables.bootstrap.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/dataTables.bootstrap.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/jquery.dataTables.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/jquery.dataTables.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/dataTables/jquery.dataTables.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/jquery.dataTables.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/echarts/echarts.common.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/echarts/echarts.common.min.js new file mode 100644 index 0000000..98fff8b --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/echarts/echarts.common.min.js @@ -0,0 +1,29 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.echarts=e():t.echarts=e()}(this,function(){return function(t){function e(n){if(i[n])return i[n].exports;var r=i[n]={exports:{},id:n,loaded:!1};return t[n].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){t.exports=i(2),i(100),i(94),i(104),i(178),i(191),i(215),i(192),i(31),i(206),i(199),i(198),i(197),i(181),i(207),i(222)},function(t,e){function i(t){if(null==t||"object"!=typeof t)return t;var e=t,n=O.call(t);if("[object Array]"===n){e=[];for(var r=0,o=t.length;re.get("hoverLayerThreshold")&&!w.node&&i.traverse(function(t){t.isGroup||(t.useHoverLayer=!0)})}function x(t,e){var i=0;e.group.traverse(function(t){"group"===t.type||t.ignore||i++});var n=+t.get("progressive"),r=i>t.get("progressiveThreshold")&&n&&!w.node;r&&e.group.traverse(function(t){t.isGroup||(t.progressive=r?Math.floor(i++/n):-1,r&&t.stopAnimation(!0))});var o=t.get("blendMode")||null;e.group.traverse(function(t){t.isGroup||t.setStyle("blend",o)})}function _(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function b(t){function e(t,e){for(var i=0;i=0&&E.each(t,function(t){var r=t.coordinateSystem;if(r&&r.containPoint)i|=!!r.containPoint(e);else if("seriesModels"===n){var o=this._chartsMap[t.__viewId];o&&o.containPoint&&(i|=o.containPoint(e,t))}},this)},this),!!i},K.getVisual=function(t,e){var i=this._model;t=D.parseFinder(i,t,{defaultMainType:"series"});var n=t.seriesModel,r=n.getData(),o=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?r.indexOfRawIndex(t.dataIndex):null;return null!=o?r.getItemVisual(o,e):r.getVisual(e)};var J={update:function(t){var e=this._model,i=this._api,n=this._coordSysMgr,r=this._zr;if(e){e.restoreData(),n.create(this._model,this._api),f.call(this,e,i),p.call(this,e),n.update(e,i),m.call(this,e,t),v.call(this,e,t);var o=e.get("backgroundColor")||"transparent",a=r.painter;if(a.isSingleCanvas&&a.isSingleCanvas())r.configLayer(0,{clearColor:o});else{if(!w.canvasSupported){var s=N.parse(o);o=N.stringify(s,"rgb"),0===s[3]&&(o="transparent")}o.colorStops||o.image?(r.configLayer(0,{clearColor:o}),this[Y]=!0,this._dom.style.background="transparent"):(this[Y]&&r.configLayer(0,{clearColor:null}),this[Y]=!1,this._dom.style.background=o)}}},updateView:function(t){var e=this._model;e&&(e.eachSeries(function(t){t.getData().clearAllVisual()}),m.call(this,e,t),c.call(this,"updateView",e,t))},updateVisual:function(t){var e=this._model;e&&(e.eachSeries(function(t){t.getData().clearAllVisual()}),m.call(this,e,t,!0),c.call(this,"updateVisual",e,t))},updateLayout:function(t){var e=this._model;e&&(g.call(this,e,t),c.call(this,"updateLayout",e,t))},prepareAndUpdate:function(t){var e=this._model;d.call(this,"component",e),d.call(this,"chart",e),this.__lastOnlyGraphic?(V(this._componentsViews,function(i){var n=i.__model;n&&"graphic"===n.mainType&&(i.render(n,e,this._api,t),_(n,i))},this),this.__lastOnlyGraphic=!1):J.update.call(this,t)}};K.resize=function(t){this[X]=!0,this._zr.resize(t);var e=this._model&&this._model.resetOption("media"),i=e?"prepareAndUpdate":"update";J[i].call(this),this._loadingFX&&this._loadingFX.resize(),this[X]=!1;var n=t&&t.silent;h.call(this,n),u.call(this,n)},K.showLoading=function(t,e){if(E.isObject(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),st[t]){var i=st[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},K.hideLoading=function(){this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null},K.makeActionFromEvent=function(t){var e=E.extend({},t);return e.type=it[t.type],e},K.dispatchAction=function(t,e){if(E.isObject(e)||(e={silent:!!e}),et[t.type]){if(this[X])return void this._pendingActions.push(t);l.call(this,t,e.silent),e.flush?this._zr.flush(!0):e.flush!==!1&&w.browser.weChat&&this._throttledZrFlush(),h.call(this,e.silent),u.call(this,e.silent)}},K.on=n("on"),K.off=n("off"),K.one=n("one");var tt=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];K._initEvents=function(){V(tt,function(t){this._zr.on(t,function(e){var i,n=this.getModel(),r=e.target;if("globalout"===t)i={};else if(r&&null!=r.dataIndex){var o=r.dataModel||n.getSeriesByIndex(r.seriesIndex);i=o&&o.getDataParams(r.dataIndex,r.dataType)||{}}else r&&r.eventData&&(i=E.extend({},r.eventData));i&&(i.event=e,i.type=t,this.trigger(t,i))},this)},this),V(it,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},K.isDisposed=function(){return this._disposed},K.clear=function(){this.setOption({series:[]},!0)},K.dispose=function(){if(!this._disposed){this._disposed=!0;var t=this._api,e=this._model;V(this._componentsViews,function(i){i.dispose(e,t)}),V(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete lt[this.id]}},E.mixin(o,R);var et=[],it={},nt=[],rt=[],ot=[],at={},st={},lt={},ht={},ut=new Date-0,ct=new Date-0,dt="_echarts_instance_",ft={version:"3.4.0",dependencies:{zrender:"3.3.0"}};ft.init=function(t,e,i){var n=new o(t,e,i);return n.id="ec_"+ut++,lt[n.id]=n,t.setAttribute&&t.setAttribute(dt,n.id),b(n),n},ft.connect=function(t){if(E.isArray(t)){var e=t;t=null,E.each(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+ct++,E.each(e,function(e){e.group=t})}return ht[t]=!0,t},ft.disConnect=function(t){ht[t]=!1},ft.dispose=function(t){E.isDom(t)?t=ft.getInstanceByDom(t):"string"==typeof t&&(t=lt[t]),t instanceof o&&!t.isDisposed()&&t.dispose()},ft.getInstanceByDom=function(t){var e=t.getAttribute(dt);return lt[e]},ft.getInstanceById=function(t){return lt[t]},ft.registerTheme=function(t,e){at[t]=e},ft.registerPreprocessor=function(t){rt.push(t)},ft.registerProcessor=function(t,e){"function"==typeof t&&(e=t,t=G),nt.push({prio:t,func:e})},ft.registerAction=function(t,e,i){"function"==typeof e&&(i=e,e="");var n=E.isObject(t)?t.type:[t,t={event:e}][0];t.event=(t.event||n).toLowerCase(),e=t.event,E.assert(Q.test(n)&&Q.test(e)),et[n]||(et[n]={action:i,actionInfo:t}),it[e]=n},ft.registerCoordinateSystem=function(t,e){T.register(t,e)},ft.registerLayout=function(t,e){"function"==typeof t&&(e=t,t=W),ot.push({prio:t,func:e,isLayout:!0})},ft.registerVisual=function(t,e){"function"==typeof t&&(e=t,t=q),ot.push({prio:t,func:e})},ft.registerLoading=function(t,e){st[t]=e},ft.extendComponentModel=function(t){return I.extend(t)},ft.extendComponentView=function(t){return k.extend(t)},ft.extendSeriesModel=function(t){return C.extend(t)},ft.extendChartView=function(t){return L.extend(t)},ft.setCanvasCreator=function(t){E.createCanvas=t},ft.registerVisual(Z,i(139)),ft.registerPreprocessor(i(133)),ft.registerLoading("default",i(124)),ft.registerAction({type:"highlight",event:"highlight",update:"highlight"},E.noop),ft.registerAction({type:"downplay",event:"downplay",update:"downplay"},E.noop),ft.List=i(14),ft.Model=i(11),ft.graphic=i(3),ft.number=i(4),ft.format=i(8),ft.throttle=O.throttle,ft.matrix=i(20),ft.vector=i(5),ft.color=i(19),ft.util={},V(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend","defaults","clone"],function(t){ft.util[t]=E[t]}),ft.PRIORITY={PROCESSOR:{FILTER:G,STATISTIC:H},VISUAL:{LAYOUT:W,GLOBAL:Z,CHART:q,COMPONENT:j,BRUSH:U}},t.exports=ft},function(t,e,i){"use strict";function n(t){return null!=t&&"none"!=t}function r(t){return"string"==typeof t?_.lift(t,-.1):t}function o(t){if(t.__hoverStlDirty){var e=t.style.stroke,i=t.style.fill,o=t.__hoverStl;o.fill=o.fill||(n(i)?r(i):null),o.stroke=o.stroke||(n(e)?r(e):null);var a={};for(var s in o)o.hasOwnProperty(s)&&(a[s]=t.style[s]);t.__normalStl=a,t.__hoverStlDirty=!1}}function a(t){t.__isHover||(o(t),t.useHoverLayer?t.__zr&&t.__zr.addHover(t,t.__hoverStl):(t.setStyle(t.__hoverStl),t.z2+=1),t.__isHover=!0)}function s(t){if(t.__isHover){var e=t.__normalStl;t.useHoverLayer?t.__zr&&t.__zr.removeHover(t):(e&&t.setStyle(e),t.z2-=1),t.__isHover=!1}}function l(t){"group"===t.type?t.traverse(function(t){"group"!==t.type&&a(t)}):a(t)}function h(t){"group"===t.type?t.traverse(function(t){"group"!==t.type&&s(t)}):s(t)}function u(t,e){t.__hoverStl=t.hoverStyle||e||{},t.__hoverStlDirty=!0,t.__isHover&&o(t)}function c(t){this.__hoverSilentOnTouch&&t.zrByTouch||!this.__isEmphasis&&l(this)}function d(t){this.__hoverSilentOnTouch&&t.zrByTouch||!this.__isEmphasis&&h(this)}function f(){this.__isEmphasis=!0,l(this)}function p(){this.__isEmphasis=!1,h(this)}function g(t,e,i,n,r,o){"function"==typeof r&&(o=r,r=null);var a=n&&n.isAnimationEnabled();if(a){var s=t?"Update":"",l=n.getShallow("animationDuration"+s),h=n.getShallow("animationEasing"+s),u=n.getShallow("animationDelay"+s);"function"==typeof u&&(u=u(r,n.getAnimationDelayParams?n.getAnimationDelayParams(e,r):null)),"function"==typeof l&&(l=l(r)),l>0?e.animateTo(i,l,u||0,h,o):(e.attr(i),o&&o())}else e.attr(i),o&&o()}var m=i(1),v=i(169),y=Math.round,x=i(7),_=i(19),b=i(20),w=i(5),M={};M.Group=i(34),M.Image=i(49),M.Text=i(76),M.Circle=i(160),M.Sector=i(166),M.Ring=i(165),M.Polygon=i(162),M.Polyline=i(163),M.Rect=i(164),M.Line=i(161),M.BezierCurve=i(159),M.Arc=i(158),M.CompoundPath=i(153),M.LinearGradient=i(91),M.RadialGradient=i(154),M.BoundingRect=i(9),M.extendShape=function(t){return x.extend(t)},M.extendPath=function(t,e){return v.extendFromString(t,e)},M.makePath=function(t,e,i,n){var r=v.createFromString(t,e),o=r.getBoundingRect();if(i){var a=o.width/o.height;if("center"===n){var s,l=i.height*a;l<=i.width?s=i.height:(l=i.width,s=l/a);var h=i.x+i.width/2,u=i.y+i.height/2;i.x=h-l/2,i.y=u-s/2,i.width=l,i.height=s}M.resizePath(r,i)}return r},M.mergePath=v.mergePath,M.resizePath=function(t,e){if(t.applyTransform){var i=t.getBoundingRect(),n=i.calculateTransform(e);t.applyTransform(n)}},M.subPixelOptimizeLine=function(t){var e=M.subPixelOptimize,i=t.shape,n=t.style.lineWidth;return y(2*i.x1)===y(2*i.x2)&&(i.x1=i.x2=e(i.x1,n,!0)),y(2*i.y1)===y(2*i.y2)&&(i.y1=i.y2=e(i.y1,n,!0)),t},M.subPixelOptimizeRect=function(t){var e=M.subPixelOptimize,i=t.shape,n=t.style.lineWidth,r=i.x,o=i.y,a=i.width,s=i.height;return i.x=e(i.x,n,!0),i.y=e(i.y,n,!0),i.width=Math.max(e(r+a,n,!1)-i.x,0===a?0:1),i.height=Math.max(e(o+s,n,!1)-i.y,0===s?0:1),t},M.subPixelOptimize=function(t,e,i){var n=y(2*t);return(n+y(e))%2===0?n/2:(n+(i?1:-1))/2},M.setHoverStyle=function(t,e,i){t.__hoverSilentOnTouch=i&&i.hoverSilentOnTouch,"group"===t.type?t.traverse(function(t){"group"!==t.type&&u(t,e)}):u(t,e),t.on("mouseover",c).on("mouseout",d),t.on("emphasis",f).on("normal",p)},M.setText=function(t,e,i){var n=e.getShallow("position")||"inside",r=e.getShallow("offset"),o=n.indexOf("inside")>=0?"white":i,a=e.getModel("textStyle");m.extend(t,{textDistance:e.getShallow("distance")||5,textFont:a.getFont(),textPosition:n,textOffset:r,textFill:a.getTextColor()||o})},M.updateProps=function(t,e,i,n,r){g(!0,t,e,i,n,r)},M.initProps=function(t,e,i,n,r){g(!1,t,e,i,n,r)},M.getTransform=function(t,e){for(var i=b.identity([]);t&&t!==e;)b.mul(i,t.getLocalTransform(),i),t=t.parent;return i},M.applyTransform=function(t,e,i){return i&&(e=b.invert([],e)),w.applyTransform([],t,e)},M.transformDirection=function(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),r=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),o=["left"===t?-n:"right"===t?n:0,"top"===t?-r:"bottom"===t?r:0];return o=M.applyTransform(o,e,i),Math.abs(o[0])>Math.abs(o[1])?o[0]>0?"right":"left":o[1]>0?"bottom":"top"},M.groupTransition=function(t,e,i,n){function r(t){var e={};return t.traverse(function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}function o(t){var e={position:w.clone(t.position),rotation:t.rotation};return t.shape&&(e.shape=m.extend({},t.shape)),e}if(t&&e){var a=r(t);e.traverse(function(t){if(!t.isGroup&&t.anid){var e=a[t.anid];if(e){var n=o(t);t.attr(o(e)),M.updateProps(t,n,i,t.dataIndex)}}})}},t.exports=M},function(t,e){function i(t){return t.replace(/^\s+/,"").replace(/\s+$/,"")}var n={},r=1e-4;n.linearMap=function(t,e,i,n){var r=e[1]-e[0],o=i[1]-i[0];if(0===r)return 0===o?i[0]:(i[0]+i[1])/2;if(n)if(r>0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/r*o+i[0]},n.parsePercent=function(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?i(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t},n.round=function(t,e){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),+(+t).toFixed(e)},n.asc=function(t){return t.sort(function(t,e){return t-e}),t},n.getPrecision=function(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i},n.getPrecisionSafe=function(t){var e=t.toString(),i=e.indexOf(".");return i<0?0:e.length-1-i},n.getPixelPrecision=function(t,e){var i=Math.log,n=Math.LN10,r=Math.floor(i(t[1]-t[0])/n),o=Math.round(i(Math.abs(e[1]-e[0]))/n),a=Math.min(Math.max(-r+o,0),20);return isFinite(a)?a:20},n.MAX_SAFE_INTEGER=9007199254740991,n.remRadian=function(t){var e=2*Math.PI;return(t%e+e)%e},n.isRadianAroundZero=function(t){return t>-r&&t=0},t.exports=n},function(t,e){var i="undefined"==typeof Float32Array?Array:Float32Array,n={create:function(t,e){var n=new i(2);return null==t&&(t=0),null==e&&(e=0),n[0]=t,n[1]=e,n},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t},clone:function(t){var e=new i(2);return e[0]=t[0],e[1]=t[1],e},set:function(t,e,i){return t[0]=e,t[1]=i,t},add:function(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t},scaleAndAdd:function(t,e,i,n){return t[0]=e[0]+i[0]*n,t[1]=e[1]+i[1]*n,t},sub:function(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t},len:function(t){return Math.sqrt(this.lenSquare(t))},lenSquare:function(t){return t[0]*t[0]+t[1]*t[1]},mul:function(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t},div:function(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t},dot:function(t,e){return t[0]*e[0]+t[1]*e[1]},scale:function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t},normalize:function(t,e){var i=n.len(e);return 0===i?(t[0]=0,t[1]=0):(t[0]=e[0]/i,t[1]=e[1]/i),t},distance:function(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))},distanceSquare:function(t,e){return(t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1])},negate:function(t,e){return t[0]=-e[0],t[1]=-e[1],t},lerp:function(t,e,i,n){return t[0]=e[0]+n*(i[0]-e[0]),t[1]=e[1]+n*(i[1]-e[1]),t},applyTransform:function(t,e,i){var n=e[0],r=e[1];return t[0]=i[0]*n+i[2]*r+i[4],t[1]=i[1]*n+i[3]*r+i[5],t},min:function(t,e,i){return t[0]=Math.min(e[0],i[0]),t[1]=Math.min(e[1],i[1]),t},max:function(t,e,i){return t[0]=Math.max(e[0],i[0]),t[1]=Math.max(e[1],i[1]),t}};n.length=n.len,n.lengthSquare=n.lenSquare,n.dist=n.distance,n.distSquare=n.distanceSquare,t.exports=n},function(t,e,i){function n(t,e){return t&&t.hasOwnProperty(e)}var r=i(8),o=i(4),a=i(11),s=i(1),l=s.each,h=s.isObject,u={};u.normalizeToArray=function(t){return t instanceof Array?t:null==t?[]:[t]},u.defaultEmphasis=function(t,e){if(t){var i=t.emphasis=t.emphasis||{},n=t.normal=t.normal||{};l(e,function(t){var e=s.retrieve(i[t],n[t]);null!=e&&(i[t]=e)})}},u.LABEL_OPTIONS=["position","offset","show","textStyle","distance","formatter"],u.getDataItemValue=function(t){return t&&(null==t.value?t:t.value)},u.isDataItemOption=function(t){return h(t)&&!(t instanceof Array)},u.converDataValue=function(t,e){var i=e&&e.type;return"ordinal"===i?t:("time"!==i||isFinite(t)||null==t||"-"===t||(t=+o.parseDate(t)),null==t||""===t?NaN:+t)},u.createDataFormatModel=function(t,e){var i=new a;return s.mixin(i,u.dataFormatMixin),i.seriesIndex=e.seriesIndex,i.name=e.name||"",i.mainType=e.mainType,i.subType=e.subType,i.getData=function(){return t},i},u.dataFormatMixin={getDataParams:function(t,e){var i=this.getData(e),n=this.seriesIndex,r=this.name,o=this.getRawValue(t,e),a=i.getRawIndex(t),s=i.getName(t,!0),l=i.getRawDataItem(t);return{componentType:this.mainType,componentSubType:this.subType,seriesType:"series"===this.mainType?this.subType:null,seriesIndex:n,seriesName:r,name:s,dataIndex:a,data:l,dataType:e,value:o,color:i.getItemVisual(t,"color"),$vars:["seriesName","name","value"]}},getFormattedLabel:function(t,e,i,n){e=e||"normal";var o=this.getData(i),a=o.getItemModel(t),s=this.getDataParams(t,i);null!=n&&s.value instanceof Array&&(s.value=s.value[n]);var l=a.get(["label",e,"formatter"]);return"function"==typeof l?(s.status=e,l(s)):"string"==typeof l?r.formatTpl(l,s):void 0},getRawValue:function(t,e){var i=this.getData(e),n=i.getRawDataItem(t);if(null!=n)return!h(n)||n instanceof Array?n:n.value},formatTooltip:s.noop},u.mappingToExists=function(t,e){e=(e||[]).slice();var i=s.map(t||[],function(t,e){return{exist:t}});return l(e,function(t,n){if(h(t)){for(var r=0;r=i.length&&i.push({option:t})}}),i},u.makeIdAndName=function(t){var e={};l(t,function(t,i){var n=t.exist;n&&(e[n.id]=t)}),l(t,function(t,i){var n=t.option;s.assert(!n||null==n.id||!e[n.id]||e[n.id]===t,"id duplicates: "+(n&&n.id)),n&&null!=n.id&&(e[n.id]=t),!t.keyInfo&&(t.keyInfo={})}),l(t,function(t,i){var n=t.exist,r=t.option,o=t.keyInfo;if(h(r)){if(o.name=null!=r.name?r.name+"":n?n.name:"\0-",n)o.id=n.id;else if(null!=r.id)o.id=r.id+"";else{var a=0;do o.id="\0"+o.name+"\0"+a++;while(e[o.id])}e[o.id]=t}})},u.isIdInner=function(t){return h(t)&&t.id&&0===(t.id+"").indexOf("\0_ec_\0")},u.compressBatches=function(t,e){function i(t,e,i){for(var n=0,r=t.length;n1e-10&&(r.width+=o/a,r.height+=o/a,r.x-=o/a/2,r.y-=o/a/2)}return r}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this.getBoundingRect(),r=this.style;if(t=i[0],e=i[1],n.contain(t,e)){var o=this.path.data;if(r.hasStroke()){var a=r.lineWidth,l=r.strokeNoScale?this.getLineScale():1;if(l>1e-10&&(r.hasFill()||(a=Math.max(a,this.strokeContainThreshold)),s.containStroke(o,a/l,t,e)))return!0}if(r.hasFill())return s.contain(o,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):r.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(o.isObject(t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&u(t[0]-1)>1e-10&&u(t[3]-1)>1e-10?Math.sqrt(u(t[0]*t[3]-t[2]*t[1])):1}},n.extend=function(t){var e=function(e){n.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var r=this.shape;for(var o in i)!r.hasOwnProperty(o)&&i.hasOwnProperty(o)&&(r[o]=i[o])}t.init&&t.init.call(this,e)};o.inherits(e,n);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},o.inherits(n,r),t.exports=n},function(t,e,i){var n=i(1),r=i(4),o=i(17),a={};a.addCommas=function(t){return isNaN(t)?"-":(t=(t+"").split("."),t[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t.length>1?"."+t[1]:""))},a.toCamelCase=function(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t},a.normalizeCssArray=function(t){var e=t.length;return"number"==typeof t?[t,t,t,t]:2===e?[t[0],t[1],t[0],t[1]]:3===e?[t[0],t[1],t[2],t[1]]:t};var s=a.encodeHTML=function(t){return String(t).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},l=["a","b","c","d","e","f","g"],h=function(t,e){return"{"+t+(null==e?"":e)+"}"};a.formatTpl=function(t,e,i){n.isArray(e)||(e=[e]);var r=e.length;if(!r)return"";for(var o=e[0].$vars||[],a=0;a=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new n(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},n.create=function(t){return new n(t.x,t.y,t.width,t.height)},t.exports=n},function(t,e){function i(t){var e={},i={},n=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge\/([\d.]+)/),a=/micromessenger/i.test(t);return n&&(i.firefox=!0,i.version=n[1]),r&&(i.ie=!0,i.version=r[1]),o&&(i.edge=!0,i.version=o[1]),a&&(i.weChat=!0),{browser:i,os:e,node:!1,canvasSupported:!!document.createElement("canvas").getContext,touchEventsSupported:"ontouchstart"in window&&!i.ie&&!i.edge,pointerEventsSupported:"onpointerdown"in window&&(i.edge||i.ie&&i.version>=11)}}var n={};n="undefined"==typeof navigator?{browser:{},os:{},node:!0,canvasSupported:!0}:i(navigator.userAgent),t.exports=n},function(t,e,i){function n(t,e,i){this.parentModel=e,this.ecModel=i,this.option=t}function r(t,e,i){for(var n=0;nn||l.newline?(o=0,u=m,a+=s+i,s=f.height):s=Math.max(s,f.height)}else{var v=f.height+(g?-g.y+f.y:0);c=a+v,c>r||l.newline?(o+=s+i,a=0,c=v,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=o,d[1]=a,"horizontal"===t?o=u+i:a=c+i)})}var r=i(1),o=i(9),a=i(4),s=i(8),l=a.parsePercent,h=r.each,u={},c=u.LOCATION_PARAMS=["left","right","top","bottom","width","height"];u.box=n,u.vbox=r.curry(n,"vertical"),u.hbox=r.curry(n,"horizontal"),u.getAvailableSize=function(t,e,i){var n=e.width,r=e.height,o=l(t.x,n),a=l(t.y,r),h=l(t.x2,n),u=l(t.y2,r);return(isNaN(o)||isNaN(parseFloat(t.x)))&&(o=0),(isNaN(h)||isNaN(parseFloat(t.x2)))&&(h=n),(isNaN(a)||isNaN(parseFloat(t.y)))&&(a=0),(isNaN(u)||isNaN(parseFloat(t.y2)))&&(u=r),i=s.normalizeCssArray(i||0),{width:Math.max(h-o-i[1]-i[3],0),height:Math.max(u-a-i[0]-i[2],0)}},u.getLayoutRect=function(t,e,i){i=s.normalizeCssArray(i||0);var n=e.width,r=e.height,a=l(t.left,n),h=l(t.top,r),u=l(t.right,n),c=l(t.bottom,r),d=l(t.width,n),f=l(t.height,r),p=i[2]+i[0],g=i[1]+i[3],m=t.aspect;switch(isNaN(d)&&(d=n-u-g-a),isNaN(f)&&(f=r-c-p-h),isNaN(d)&&isNaN(f)&&(m>n/r?d=.8*n:f=.8*r),null!=m&&(isNaN(d)&&(d=m*f),isNaN(f)&&(f=d/m)),isNaN(a)&&(a=n-u-d-g),isNaN(h)&&(h=r-c-f-p),t.left||t.right){case"center":a=n/2-d/2-i[3];break;case"right":a=n-d-g}switch(t.top||t.bottom){case"middle":case"center":h=r/2-f/2-i[0];break;case"bottom":h=r-f-p}a=a||0,h=h||0,isNaN(d)&&(d=n-a-(u||0)),isNaN(f)&&(f=r-h-(c||0));var v=new o(a+i[3],h+i[0],d,f);return v.margin=i,v},u.positionElement=function(t,e,i,n,a){var s=!a||!a.hv||a.hv[0],l=!a||!a.hv||a.hv[1],h=a&&a.boundingMode||"all";if(s||l){var c;if("raw"===h)c="group"===t.type?new o(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(c=t.getBoundingRect(),t.needLocalTransform()){var d=t.getLocalTransform();c=c.clone(),c.applyTransform(d)}e=u.getLayoutRect(r.defaults({width:c.width, +height:c.height},e),i,n);var f=t.position,p=s?e.x-c.x:0,g=l?e.y-c.y:0;t.attr("position","raw"===h?[p,g]:[f[0]+p,f[1]+g])}},u.mergeLayoutParam=function(t,e,i){function n(n){var r={},s=0,l={},u=0,c=i.ignoreSize?1:2;if(h(n,function(e){l[e]=t[e]}),h(n,function(t){o(e,t)&&(r[t]=l[t]=e[t]),a(r,t)&&s++,a(l,t)&&u++}),u!==c&&s){if(s>=c)return r;for(var d=0;d=0;r--)n=o.merge(n,t[r],!0);l.set(this,"__defaultOption",n)}return l.get(this,"__defaultOption")},getReferringComponents:function(t){return this.ecModel.queryComponents({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});l.enableClassManagement(u,{registerWhenExtend:!0}),s.enableSubTypeDefaulter(u),s.enableTopologicalTravel(u,n),o.mixin(u,i(129)),t.exports=u},function(t,e,i){(function(e){function n(t){return d.isArray(t)||(t=[t]),t}function r(t,e){var i=t.dimensions,n=new v(d.map(i,t.getDimensionInfo,t),t.hostModel);m(n,t);for(var r=n._storage={},o=t._storage,a=0;a=0?r[s]=new l.constructor(o[s].length):r[s]=o[s]}return n}var o="undefined",a="undefined"==typeof window?e:window,s=typeof a.Float64Array===o?Array:a.Float64Array,l=typeof a.Int32Array===o?Array:a.Int32Array,h={"float":s,"int":l,ordinal:Array,number:Array,time:Array},u=i(11),c=i(43),d=i(1),f=i(6),p=d.isObject,g=["stackedOn","hasItemOption","_nameList","_idList","_rawData"],m=function(t,e){d.each(g.concat(e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods},v=function(t,e){t=t||["x","y"];for(var i={},n=[],r=0;r0&&(w+="__ec__"+u[b]),u[b]++),w&&(l[c]=w)}this._nameList=e,this._idList=l},y.count=function(){return this.indices.length},y.get=function(t,e,i){var n=this._storage,r=this.indices[e];if(null==r)return NaN;var o=n[t]&&n[t][r];if(i){var a=this._dimensionInfos[t];if(a&&a.stackable)for(var s=this.stackedOn;s;){var l=s.get(t,e);(o>=0&&l>0||o<=0&&l<0)&&(o+=l),s=s.stackedOn}}return o},y.getValues=function(t,e,i){var n=[];d.isArray(t)||(i=e,e=t,t=this.dimensions);for(var r=0,o=t.length;rl&&(l=o));return this._extent[t+!!e]=[s,l]}return[1/0,-(1/0)]},y.getSum=function(t,e){var i=this._storage[t],n=0;if(i)for(var r=0,o=this.count();rt))return o;r=o-1}}return-1},y.indexOfNearest=function(t,e,i,n){var r=this._storage,o=r[t];null==n&&(n=1/0);var a=-1;if(o)for(var s=Number.MAX_VALUE,l=0,h=this.count();l0)&&(s=c,a=l)}return a},y.getRawIndex=function(t){var e=this.indices[t];return null==e?-1:e},y.getRawDataItem=function(t){return this._rawData[this.getRawIndex(t)]},y.getName=function(t){return this._nameList[this.indices[t]]||""},y.getId=function(t){return this._idList[this.indices[t]]||this.getRawIndex(t)+""},y.each=function(t,e,i,r){"function"==typeof t&&(r=i,i=e,e=t,t=[]),t=d.map(n(t),this.getDimension,this);var o=[],a=t.length,s=this.indices;r=r||this;for(var l=0;lp-g&&(d=p-g,u.length=d);for(var m=0;m',g=this.name;return"\0-"===g&&(g=""),e?c+f(this.name)+" : "+l:(g&&f(g)+"
    ")+c+(h?f(h)+" : "+l:l)},isAnimationEnabled:function(){if(h.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){c(this,"data",d(this,"dataBeforeProcessed").cloneShallow())},getColorFromPalette:function(t,e){var i=this.ecModel,n=l.getColorFromPalette.call(this,t,e);return n||(n=i.getColorFromPalette(t,e)),n},getAxisTooltipDataIndex:null,getTooltipPosition:null});n.mixin(g,a.dataFormatMixin),n.mixin(g,l),t.exports=g},function(t,e,i){function n(t,e){var i=t+":"+e;if(l[i])return l[i];for(var n=(t+"").split("\n"),r=0,o=0,a=n.length;ou&&(h=0,l={}),h++,l[i]=r,r}function r(t,e,i,r){var o=((t||"")+"").split("\n").length,a=n(t,e),s=n("国",e),l=o*s,h=new d(0,0,a,l);switch(h.lineHeight=s,r){case"bottom":case"alphabetic":h.y-=s;break;case"middle":h.y-=s/2}switch(i){case"end":case"right":h.x-=h.width;break;case"center":h.x-=h.width/2}return h}function o(t,e,i,n){var r=e.x,o=e.y,a=e.height,s=e.width,l=i.height,h=a/2-l/2,u="left";switch(t){case"left":r-=n,o+=h,u="right";break;case"right":r+=n+s,o+=h,u="left";break;case"top":r+=s/2,o-=n+l,u="center";break;case"bottom":r+=s/2,o+=a+n,u="center";break;case"inside":r+=s/2,o+=h,u="center";break;case"insideLeft":r+=n,o+=h,u="left";break;case"insideRight":r+=s-n,o+=h,u="right";break;case"insideTop":r+=s/2,o+=n,u="center";break;case"insideBottom":r+=s/2,o+=a-l-n,u="center";break;case"insideTopLeft":r+=n,o+=n,u="left";break;case"insideTopRight":r+=s-n,o+=n,u="right";break;case"insideBottomLeft":r+=n,o+=a-l-n;break;case"insideBottomRight":r+=s-n,o+=a-l-n,u="right"}return{x:r,y:o,textAlign:u,textBaseline:"top"}}function a(t,e,i,r,o){if(!e)return"";o=o||{},r=f(r,"...");for(var a=f(o.maxIterations,2),l=f(o.minChar,0),h=n("国",i),u=n("a",i),c=f(o.placeholder,""),d=e=Math.max(0,e-1),p=0;p=u;p++)d-=u;var g=n(r);g>d&&(r="",g=0),d=e-g;for(var m=(t+"").split("\n"),p=0,v=m.length;p=a){y+=r;break}var b=0===_?s(y,d,u,h):x>0?Math.floor(y.length*d/x):0;y=y.substr(0,b),x=n(y,i)}""===y&&(y=c),m[p]=y}}return m.join("\n")}function s(t,e,i,n){for(var r=0,o=0,a=t.length;o-w&&tw||t<-w}function o(t,e,i,n,r){var o=1-r;return o*o*(o*t+3*r*e)+r*r*(r*n+3*o*i)}function a(t,e,i,n,r){var o=1-r;return 3*(((e-t)*o+2*(i-e)*r)*o+(n-i)*r*r)}function s(t,e,i,r,o,a){var s=r+3*(e-i)-t,l=3*(i-2*e+t),h=3*(e-t),u=t-o,c=l*l-3*s*h,d=l*h-9*s*u,f=h*h-3*l*u,p=0;if(n(c)&&n(d))if(n(l))a[0]=0;else{var g=-h/l;g>=0&&g<=1&&(a[p++]=g)}else{var m=d*d-4*c*f;if(n(m)){var v=d/c,g=-l/s+v,y=-v/2;g>=0&&g<=1&&(a[p++]=g),y>=0&&y<=1&&(a[p++]=y)}else if(m>0){var x=b(m),w=c*l+1.5*s*(-d+x),M=c*l+1.5*s*(-d-x);w=w<0?-_(-w,T):_(w,T),M=M<0?-_(-M,T):_(M,T);var g=(-l-(w+M))/(3*s);g>=0&&g<=1&&(a[p++]=g)}else{var A=(2*c*l-3*s*d)/(2*b(c*c*c)),I=Math.acos(A)/3,C=b(c),k=Math.cos(I),g=(-l-2*C*k)/(3*s),y=(-l+C*(k+S*Math.sin(I)))/(3*s),L=(-l+C*(k-S*Math.sin(I)))/(3*s);g>=0&&g<=1&&(a[p++]=g),y>=0&&y<=1&&(a[p++]=y),L>=0&&L<=1&&(a[p++]=L)}}return p}function l(t,e,i,o,a){var s=6*i-12*e+6*t,l=9*e+3*o-3*t-9*i,h=3*e-3*t,u=0;if(n(l)){if(r(s)){var c=-h/s;c>=0&&c<=1&&(a[u++]=c)}}else{var d=s*s-4*l*h;if(n(d))a[0]=-s/(2*l);else if(d>0){var f=b(d),c=(-s+f)/(2*l),p=(-s-f)/(2*l);c>=0&&c<=1&&(a[u++]=c),p>=0&&p<=1&&(a[u++]=p)}}return u}function h(t,e,i,n,r,o){var a=(e-t)*r+t,s=(i-e)*r+e,l=(n-i)*r+i,h=(s-a)*r+a,u=(l-s)*r+s,c=(u-h)*r+h;o[0]=t,o[1]=a,o[2]=h,o[3]=c,o[4]=c,o[5]=u,o[6]=l,o[7]=n}function u(t,e,i,n,r,a,s,l,h,u,c){var d,f,p,g,m,v=.005,y=1/0;A[0]=h,A[1]=u;for(var _=0;_<1;_+=.05)I[0]=o(t,i,r,s,_),I[1]=o(e,n,a,l,_),g=x(A,I),g=0&&g=0&&c<=1&&(a[u++]=c)}}else{var d=l*l-4*s*h;if(n(d)){var c=-l/(2*s);c>=0&&c<=1&&(a[u++]=c)}else if(d>0){var f=b(d),c=(-l+f)/(2*s),p=(-l-f)/(2*s);c>=0&&c<=1&&(a[u++]=c),p>=0&&p<=1&&(a[u++]=p)}}return u}function p(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function g(t,e,i,n,r){var o=(e-t)*n+t,a=(i-e)*n+e,s=(a-o)*n+o;r[0]=t,r[1]=o,r[2]=s,r[3]=s,r[4]=a,r[5]=i}function m(t,e,i,n,r,o,a,s,l){var h,u=.005,d=1/0;A[0]=a,A[1]=s;for(var f=0;f<1;f+=.05){I[0]=c(t,i,r,f),I[1]=c(e,n,o,f);var p=x(A,I);p=0&&p255?255:t}function n(t){return t=Math.round(t),t<0?0:t>360?360:t}function r(t){return t<0?0:t>1?1:t}function o(t){return i(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function a(t){return r(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function s(t,e,i){return i<0?i+=1:i>1&&(i-=1),6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function l(t,e,i){return t+(e-t)*i}function h(t){if(t){t+="";var e=t.replace(/ /g,"").toLowerCase();if(e in x)return x[e].slice();if("#"!==e.charAt(0)){var i=e.indexOf("("),n=e.indexOf(")");if(i!==-1&&n+1===e.length){var r=e.substr(0,i),s=e.substr(i+1,n-(i+1)).split(","),l=1;switch(r){case"rgba":if(4!==s.length)return;l=a(s.pop());case"rgb":if(3!==s.length)return;return[o(s[0]),o(s[1]),o(s[2]),l];case"hsla":if(4!==s.length)return;return s[3]=a(s[3]),u(s);case"hsl":if(3!==s.length)return;return u(s);default:return}}}else{if(4===e.length){var h=parseInt(e.substr(1),16);if(!(h>=0&&h<=4095))return;return[(3840&h)>>4|(3840&h)>>8,240&h|(240&h)>>4,15&h|(15&h)<<4,1]}if(7===e.length){var h=parseInt(e.substr(1),16);if(!(h>=0&&h<=16777215))return;return[(16711680&h)>>16,(65280&h)>>8,255&h,1]}}}}function u(t){var e=(parseFloat(t[0])%360+360)%360/360,n=a(t[1]),r=a(t[2]),o=r<=.5?r*(n+1):r+n-r*n,l=2*r-o,h=[i(255*s(l,o,e+1/3)),i(255*s(l,o,e)),i(255*s(l,o,e-1/3))];return 4===t.length&&(h[3]=t[3]),h}function c(t){if(t){var e,i,n=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(n,r,o),s=Math.max(n,r,o),l=s-a,h=(s+a)/2;if(0===l)e=0,i=0;else{i=h<.5?l/(s+a):l/(2-s-a);var u=((s-n)/6+l/2)/l,c=((s-r)/6+l/2)/l,d=((s-o)/6+l/2)/l;n===s?e=d-c:r===s?e=1/3+u-d:o===s&&(e=2/3+c-u),e<0&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,h];return null!=t[3]&&f.push(t[3]),f}}function d(t,e){var i=h(t);if(i){for(var n=0;n<3;n++)e<0?i[n]=i[n]*(1-e)|0:i[n]=(255-i[n])*e+i[n]|0;return y(i,4===i.length?"rgba":"rgb")}}function f(t,e){var i=h(t);if(i)return((1<<24)+(i[0]<<16)+(i[1]<<8)+ +i[2]).toString(16).slice(1)}function p(t,e,n){if(e&&e.length&&t>=0&&t<=1){n=n||[0,0,0,0];var r=t*(e.length-1),o=Math.floor(r),a=Math.ceil(r),s=e[o],h=e[a],u=r-o;return n[0]=i(l(s[0],h[0],u)),n[1]=i(l(s[1],h[1],u)),n[2]=i(l(s[2],h[2],u)),n[3]=i(l(s[3],h[3],u)),n}}function g(t,e,n){if(e&&e.length&&t>=0&&t<=1){var o=t*(e.length-1),a=Math.floor(o),s=Math.ceil(o),u=h(e[a]),c=h(e[s]),d=o-a,f=y([i(l(u[0],c[0],d)),i(l(u[1],c[1],d)),i(l(u[2],c[2],d)),r(l(u[3],c[3],d))],"rgba");return n?{color:f,leftIndex:a,rightIndex:s,value:o}:f}}function m(t,e,i,r){if(t=h(t))return t=c(t),null!=e&&(t[0]=n(e)),null!=i&&(t[1]=a(i)),null!=r&&(t[2]=a(r)),y(u(t),"rgba")}function v(t,e){if(t=h(t),t&&null!=e)return t[3]=r(e),y(t,"rgba")}function y(t,e){var i=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(i+=","+t[3]),e+"("+i+")"}var x={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};t.exports={parse:h,lift:d,toHex:f,fastMapToColor:p,mapToColor:g,modifyHSL:m,modifyAlpha:v,stringify:y}},function(t,e){var i="undefined"==typeof Float32Array?Array:Float32Array,n={create:function(){var t=new i(6);return n.identity(t),t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t},mul:function(t,e,i){var n=e[0]*i[0]+e[2]*i[1],r=e[1]*i[0]+e[3]*i[1],o=e[0]*i[2]+e[2]*i[3],a=e[1]*i[2]+e[3]*i[3],s=e[0]*i[4]+e[2]*i[5]+e[4],l=e[1]*i[4]+e[3]*i[5]+e[5];return t[0]=n,t[1]=r,t[2]=o,t[3]=a,t[4]=s,t[5]=l,t},translate:function(t,e,i){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+i[0],t[5]=e[5]+i[1],t},rotate:function(t,e,i){var n=e[0],r=e[2],o=e[4],a=e[1],s=e[3],l=e[5],h=Math.sin(i),u=Math.cos(i);return t[0]=n*u+a*h,t[1]=-n*h+a*u,t[2]=r*u+s*h,t[3]=-r*h+u*s,t[4]=u*o+h*l,t[5]=u*l-h*o,t},scale:function(t,e,i){var n=i[0],r=i[1];return t[0]=e[0]*n,t[1]=e[1]*r,t[2]=e[2]*n,t[3]=e[3]*r,t[4]=e[4]*n,t[5]=e[5]*r,t},invert:function(t,e){var i=e[0],n=e[2],r=e[4],o=e[1],a=e[3],s=e[5],l=i*a-o*n;return l?(l=1/l,t[0]=a*l,t[1]=-o*l,t[2]=-n*l,t[3]=i*l,t[4]=(n*s-a*r)*l,t[5]=(o*r-i*s)*l,t):null}};t.exports=n},function(t,e){var i=Array.prototype.slice,n=function(){this._$handlers={}};n.prototype={constructor:n,one:function(t,e,i){var n=this._$handlers;if(!e||!t)return this;n[t]||(n[t]=[]);for(var r=0;r3&&(e=i.call(e,1));for(var r=this._$handlers[t],o=r.length,a=0;a4&&(e=i.call(e,1,e.length-1));for(var r=e[e.length-1],o=this._$handlers[t],a=o.length,s=0;s0&&u>0&&!c&&(h=0),h<0&&u<0&&!d&&(u=0)),[h,u]},h.niceScaleExtent=function(t,e){var i=t.scale,n=h.getScaleExtent(t,e),r=null!=e.getMin(),o=null!=e.getMax(),a=e.get("splitNumber");"log"===i.type&&(i.base=e.get("logBase")),i.setExtent(n[0],n[1]),i.niceExtent(a,r,o);var s=e.get("minInterval");if(isFinite(s)&&!r&&!o&&"interval"===i.type){var l=i.getInterval(),u=Math.max(Math.abs(l),s)/l;n=i.getExtent();var c=(n[1]+n[0])/2;i.setExtent(u*(n[0]-c)+c,u*(n[1]-c)+c),i.niceExtent(a)}var l=e.get("interval");null!=l&&i.setInterval&&i.setInterval(l)},h.createScaleByModel=function(t,e){if(e=e||t.get("type"))switch(e){case"category":return new n(t.getCategories(),[1/0,-(1/0)]);case"value":return new r;default:return(o.getClass(e)||r).create(t)}},h.ifAxisCrossZero=function(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(i>0&&n>0||i<0&&n<0)},h.getAxisLabelInterval=function(t,e,i,n){var r,o=0,a=0,s=1;e.length>40&&(s=Math.floor(e.length/40));for(var h=0;h1?s:(o+1)*s-1},h.getFormattedLabels=function(t,e){var i=t.scale,n=i.getTicksLabels(),r=i.getTicks();return"string"==typeof e?(e=function(t){return function(e){return t.replace("{value}",null!=e?e:"")}}(e),s.map(n,e)):"function"==typeof e?s.map(r,function(n,r){return e("category"===t.type?i.getLabel(n):n,r)},this):n},t.exports=h},function(t,e,i){"use strict";function n(){this._coordinateSystems=[]}var r=i(1),o={};n.prototype={constructor:n,create:function(t,e){var i=[];r.each(o,function(n,r){var o=n.create(t,e);i=i.concat(o||[])}),this._coordinateSystems=i},update:function(t,e){r.each(this._coordinateSystems,function(i){i.update&&i.update(t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},n.register=function(t,e){o[t]=e},n.get=function(t){return o[t]},t.exports=n},function(t,e,i){"use strict";var n=i(3),r=i(9),o=n.extendShape({type:"triangle", +shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,r=e.width/2,o=e.height/2;t.moveTo(i,n-o),t.lineTo(i+r,n+o),t.lineTo(i-r,n+o),t.closePath()}}),a=n.extendShape({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var i=e.cx,n=e.cy,r=e.width/2,o=e.height/2;t.moveTo(i,n-o),t.lineTo(i+r,n),t.lineTo(i,n+o),t.lineTo(i-r,n),t.closePath()}}),s=n.extendShape({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,r=e.width/5*3,o=Math.max(r,e.height),a=r/2,s=a*a/(o-a),l=n-o+a+s,h=Math.asin(s/a),u=Math.cos(h)*a,c=Math.sin(h),d=Math.cos(h);t.arc(i,l,a,Math.PI-h,2*Math.PI+h);var f=.6*a,p=.7*a;t.bezierCurveTo(i+u-c*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-u+c*f,l+s+d*f,i-u,l+s),t.closePath()}}),l=n.extendShape({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.height,n=e.width,r=e.x,o=e.y,a=n/3*2;t.moveTo(r,o),t.lineTo(r+a,o+i),t.lineTo(r,o+i/4*3),t.lineTo(r-a,o+i),t.lineTo(r,o),t.closePath()}}),h={line:n.Line,rect:n.Rect,roundRect:n.Rect,square:n.Rect,circle:n.Circle,diamond:a,pin:s,arrow:l,triangle:o},u={line:function(t,e,i,n,r){r.x1=t,r.y1=e+n/2,r.x2=t+i,r.y2=e+n/2},rect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r.height=n},roundRect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r.height=n,r.r=Math.min(i,n)/4},square:function(t,e,i,n,r){var o=Math.min(i,n);r.x=t,r.y=e,r.width=o,r.height=o},circle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.r=Math.min(i,n)/2},diamond:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r.height=n},pin:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r.height=n},arrow:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r.height=n},triangle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r.height=n}},c={};for(var d in h)h.hasOwnProperty(d)&&(c[d]=new h[d]);var f=n.extendShape({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},beforeBrush:function(){var t=this.style,e=this.shape;"pin"===e.symbolType&&"inside"===t.textPosition&&(t.textPosition=["50%","40%"],t.textAlign="center",t.textVerticalAlign="middle")},buildPath:function(t,e,i){var n=e.symbolType,r=c[n];"none"!==e.symbolType&&(r||(n="rect",r=c[n]),u[n](e.x,e.y,e.width,e.height,r.shape),r.buildPath(t,r.shape,i))}}),p=function(t){if("image"!==this.type){var e=this.style,i=this.shape;i&&"line"===i.symbolType?e.stroke=t:this.__isEmptyBrush?(e.stroke=t,e.fill="#fff"):(e.fill&&(e.fill=t),e.stroke&&(e.stroke=t)),this.dirty(!1)}},g={createSymbol:function(t,e,i,o,a,s){var l=0===t.indexOf("empty");l&&(t=t.substr(5,1).toLowerCase()+t.substr(6));var h;return h=0===t.indexOf("image://")?new n.Image({style:{image:t.slice(8),x:e,y:i,width:o,height:a}}):0===t.indexOf("path://")?n.makePath(t.slice(7),{},new r(e,i,o,a)):new f({shape:{symbolType:t,x:e,y:i,width:o,height:a}}),h.__isEmptyBrush=l,h.setColor=p,h.setColor(s),h}};t.exports=g},function(t,e,i){"use strict";function n(t){return t.getBoundingClientRect?t.getBoundingClientRect():{left:0,top:0}}function r(t,e,i,n){return i=i||{},n||!u.canvasSupported?o(t,e,i):u.browser.firefox&&null!=e.layerX&&e.layerX!==e.offsetX?(i.zrX=e.layerX,i.zrY=e.layerY):null!=e.offsetX?(i.zrX=e.offsetX,i.zrY=e.offsetY):o(t,e,i),i}function o(t,e,i){var r=n(t);i.zrX=e.clientX-r.left,i.zrY=e.clientY-r.top}function a(t,e,i){if(e=e||window.event,null!=e.zrX)return e;var n=e.type,o=n&&n.indexOf("touch")>=0;if(o){var a="touchend"!=n?e.targetTouches[0]:e.changedTouches[0];a&&r(t,a,e,i)}else r(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;return e}function s(t,e,i){c?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function l(t,e,i){c?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}var h=i(21),u=i(10),c="undefined"!=typeof window&&!!window.addEventListener,d=c?function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0}:function(t){t.returnValue=!1,t.cancelBubble=!0};t.exports={clientToLocal:r,normalizeEvent:a,addEventListener:s,removeEventListener:l,stop:d,Dispatcher:h}},function(t,e){"use strict";var i={};t.exports={register:function(t,e){i[t]=e},get:function(t){return i[t]}}},function(t,e,i){function n(t,e,i,n){if(!e)return t;var s=r(e[0]),l=o.isArray(s)&&s.length||1;i=i||[],n=n||"extra";for(var h=0;hthis._ux||y(e-this._yi)>this._uy||this._len<5;return this.addData(l.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,r,o){return this.addData(l.C,t,e,i,n,r,o),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,r,o):this._ctx.bezierCurveTo(t,e,i,n,r,o)),this._xi=r,this._yi=o,this},quadraticCurveTo:function(t,e,i,n){return this.addData(l.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,r,o){return this.addData(l.A,t,e,i,i,n,r-n,0,o?0:1),this._ctx&&this._ctx.arc(t,e,i,n,r,o),this._xi=g(r)*i+t,this._yi=m(r)*i+t,this},arcTo:function(t,e,i,n,r){return this._ctx&&this._ctx.arcTo(t,e,i,n,r),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(l.R,t,e,i,n),this},closePath:function(){this.addData(l.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;ie.length&&(this._expandData(),e=this.data);for(var i=0;i0&&g<=t||u<0&&g>=t||0==u&&(c>0&&m<=e||c<0&&m>=e);)n=this._dashIdx,i=a[n],g+=u*i,m+=c*i,this._dashIdx=(n+1)%y,u>0&&gl||c>0&&mh||s[n%2?"moveTo":"lineTo"](u>=0?f(g,t):p(g,t),c>=0?f(m,e):p(m,e));u=g-t,c=m-e,this._dashOffset=-v(u*u+c*c)},_dashedBezierTo:function(t,e,i,r,o,a){var s,l,h,u,c,d=this._dashSum,f=this._dashOffset,p=this._lineDash,g=this._ctx,m=this._xi,y=this._yi,x=n.cubicAt,_=0,b=this._dashIdx,w=p.length,M=0;for(f<0&&(f=d+f),f%=d,s=0;s<1;s+=.1)l=x(m,t,i,o,s+.1)-x(m,t,i,o,s),h=x(y,e,r,a,s+.1)-x(y,e,r,a,s),_+=v(l*l+h*h);for(;bf));b++);for(s=(M-f)/_;s<=1;)u=x(m,t,i,o,s),c=x(y,e,r,a,s),b%2?g.moveTo(u,c):g.lineTo(u,c),s+=p[b]/_,b=(b+1)%w;b%2!==0&&g.lineTo(o,a),l=o-u,h=a-c,this._dashOffset=-v(l*l+h*h)},_dashedQuadraticTo:function(t,e,i,n){var r=i,o=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,r,o)},toStatic:function(){var t=this.data;t instanceof Array&&(t.length=this._len,x&&(this.data=new Float32Array(t)))},getBoundingRect:function(){h[0]=h[1]=c[0]=c[1]=Number.MAX_VALUE,u[0]=u[1]=d[0]=d[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,n=0,s=0,f=0;fh||y(a-r)>u||d===c-1)&&(t.lineTo(o,a),n=o,r=a);break;case l.C:t.bezierCurveTo(s[d++],s[d++],s[d++],s[d++],s[d++],s[d++]),n=s[d-2],r=s[d-1];break;case l.Q:t.quadraticCurveTo(s[d++],s[d++],s[d++],s[d++]),n=s[d-2],r=s[d-1];break;case l.A:var p=s[d++],v=s[d++],x=s[d++],_=s[d++],b=s[d++],w=s[d++],M=s[d++],S=s[d++],T=x>_?x:_,A=x>_?1:x/_,I=x>_?_/x:1,C=Math.abs(x-_)>.001,k=b+w;C?(t.translate(p,v),t.rotate(M),t.scale(A,I),t.arc(0,0,T,b,k,1-S),t.scale(1/A,1/I),t.rotate(-M),t.translate(-p,-v)):t.arc(p,v,T,b,k,1-S),1==d&&(e=g(b)*x+p,i=m(b)*_+v),n=g(k)*x+p,r=m(k)*_+v;break;case l.R:e=n=s[d],i=r=s[d+1],t.rect(s[d++],s[d++],s[d++],s[d++]);break;case l.Z:t.closePath(),n=e,r=i}}}},_.CMD=l,t.exports=_},function(t,e,i){var n=i(1);t.exports=function(t){for(var e=0;e=0)){var a=this.getShallow(o);null!=a&&(i[t[r][0]]=a)}}return i}}},function(t,e,i){"use strict";var n=i(3),r=i(1),o=i(2);i(53),i(109),o.extendComponentView({type:"grid",render:function(t,e){this.group.removeAll(),t.get("show")&&this.group.add(new n.Rect({shape:t.coordinateSystem.getRect(),style:r.defaults({fill:t.get("backgroundColor")},t.getItemStyle()),silent:!0,z2:-1}))}}),o.registerPreprocessor(function(t){t.xAxis&&t.yAxis&&!t.grid&&(t.grid={})})},function(t,e,i){function n(){this._extent=[1/0,-(1/0)],this._interval=0,this.init&&this.init.apply(this,arguments)}var r=i(15),o=n.prototype;o.parse=function(t){return t},o.contain=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},o.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},o.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},o.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},o.unionExtentFromData=function(t,e){this.unionExtent(t.getDataExtent(e,!0))},o.getExtent=function(){return this._extent.slice()},o.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},o.getTicksLabels=function(){for(var t=[],e=this.getTicks(),i=0;i=0&&(i.splice(n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToMap(t),t instanceof a&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var e=this.__zr,i=this.__storage,r=this._children,o=n.indexOf(r,t);return o<0?this:(r.splice(o,1),t.parent=null,i&&(i.delFromMap(t.id),t instanceof a&&t.delChildrenFromStorage(i)),e&&e.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;e=0&&r(t)?function(t,e,i,n){return d.isDataItemOption(t)&&(x.hasItemOption=!0),n===y?i:g(p(t),v[n])}:function(t,e,i,n){var r=p(t),o=g(r&&r[n],v[n]);d.isDataItemOption(t)&&(x.hasItemOption=!0);var a=s&&s.categoryAxesModels;return a&&a[e]&&"string"==typeof o&&(b[e]=b[e]||a[e].getCategories(),o=c.indexOf(b[e],o),o<0&&!isNaN(o)&&(o=+o)),o};return x.hasItemOption=!1,x.initData(t,_,w),x}function a(t){return"category"!==t&&"time"!==t}function s(t){return"category"===t?"ordinal":"time"===t?"time":"float"}function l(t,e){var i,n=[],r=t&&t.dimensions[t.categoryIndex];if(r&&(i=t.categoryAxesModels[r.name]),i){var o=i.getCategories();if(o){var a=e.length;if(c.isArray(e[0])&&e[0].length>1){n=[];for(var s=0;se[1]&&(e[1]=t[1]),u.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval||this.niceTicks(),this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice()},getTicks:function(){this._interval||this.niceTicks();var t=this._interval,e=this._extent,i=[],n=1e4;if(t){var r=this._niceExtent,o=l(t)+2;e[0]n)return[];e[1]>(i.length?i[i.length-1]:r[1])&&i.push(e[1])}return i},getTicksLabels:function(){for(var t=[],e=this.getTicks(),i=0;i0?100:20}},getFirstTargetAxisModel:function(){var t;return d(function(e){if(null==t){var i=this.get(e.axisIndex);i.length&&(t=this.dependentModels[e.axis][i[0]])}},this),t},eachTargetAxis:function(t,e){var i=this.ecModel;d(function(n){c(this.get(n.axisIndex),function(r){t.call(e,n,r,this,i)},this)},this)},getAxisProxy:function(t,e){return this._axisProxies[t+"_"+e]},setRawRange:function(t){c(["start","end","startValue","endValue"],function(e){this.option[e]=t[e]},this)},getPercentRange:function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},getValueRange:function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var i=this.findRepresentativeAxisProxy();return i?i.getDataValueWindow():void 0},findRepresentativeAxisProxy:function(){var t=this._axisProxies;for(var e in t)if(t.hasOwnProperty(e)&&t[e].hostedBy(this))return t[e];for(var e in t)if(t.hasOwnProperty(e)&&!t[e].hostedBy(this))return t[e]}});t.exports=f},function(t,e,i){var n=i(59);t.exports=n.extend({type:"dataZoom",render:function(t,e,i,n){this.dataZoomModel=t,this.ecModel=e,this.api=i},getTargetCoordInfo:function(){function t(t,e,i,n){for(var r,o=0;o=i&&t<=n},containData:function(t){return this.contain(this.dataToCoord(t))},getExtent:function(){var t=this._extent.slice();return t},getPixelPrecision:function(t){return r.getPixelPrecision(t||this.scale.getExtent(),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,e){var i=this._extent,r=this.scale;return t=r.normalize(t),this.onBand&&"ordinal"===r.type&&(i=i.slice(),n(i,r.count())),o(t,s,i,e)},coordToData:function(t,e){var i=this._extent,r=this.scale;this.onBand&&"ordinal"===r.type&&(i=i.slice(),n(i,r.count()));var a=o(t,i,s,e);return this.scale.scale(a)},getTicksCoords:function(t){if(this.onBand&&!t){for(var e=this.getBands(),i=[],n=0;n=0&&i.push(t)}),i}t.topologicalTravel=function(t,e,r,o){function a(t){h[t].entryCount--,0===h[t].entryCount&&u.push(t)}function s(t){c[t]=!0,a(t)}if(t.length){var l=i(e),h=l.graph,u=l.noEntryList,c={};for(n.each(t,function(t){c[t]=!0});u.length;){var d=u.pop(),f=h[d],p=!!c[d];p&&(r.call(o,d,f.originalDeps.slice()),delete c[d]),n.each(f.successor,p?s:a)}n.each(c,function(){throw new Error("Circle dependency may exists")})}}},t.exports=s},function(t,e){t.exports=function(t,e,i,n,r){n.eachRawSeriesByType(t,function(t){var r=t.getData(),o=t.get("symbol")||e,a=t.get("symbolSize");r.setVisual({legendSymbol:i||o,symbol:o,symbolSize:a}),n.isSeriesFiltered(t)||("function"==typeof a&&r.each(function(e){var i=t.getRawValue(e),n=t.getDataParams(e);r.setItemVisual(e,"symbolSize",a(i,n))}),r.each(function(t){var e=r.getItemModel(t),i=e.getShallow("symbol",!0),n=e.getShallow("symbolSize",!0);null!=i&&r.setItemVisual(t,"symbol",i),null!=n&&r.setItemVisual(t,"symbolSize",n)}))})}},function(t,e){function i(t){for(var e=0;t>=u;)e|=1&t,t>>=1;return t+e}function n(t,e,i,n){var o=e+1;if(o===i)return 1;if(n(t[o++],t[e])<0){for(;o=0;)o++;return o-e}function r(t,e,i){for(i--;e>>1,r(a,t[o])<0?l=o:s=o+1;var h=n-s;switch(h){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;h>0;)t[s+h]=t[s+h-1],h--}t[s]=a}}function a(t,e,i,n,r,o){var a=0,s=0,l=1;if(o(t,e[i+r])>0){for(s=n-r;l0;)a=l,l=(l<<1)+1,l<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}else{for(s=r+1;ls&&(l=s);var h=a;a=r-l,l=r-h}for(a++;a>>1);o(t,e[i+u])>0?a=u+1:l=u}return l}function s(t,e,i,n,r,o){var a=0,s=0,l=1;if(o(t,e[i+r])<0){for(s=r+1;ls&&(l=s);var h=a;a=r-l,l=r-h}else{for(s=n-r;l=0;)a=l,l=(l<<1)+1,l<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}for(a++;a>>1);o(t,e[i+u])<0?l=u:a=u+1}return l}function l(t,e){function i(t,e){u[y]=t,f[y]=e,y+=1}function n(){for(;y>1;){var t=y-2;if(t>=1&&f[t-1]<=f[t]+f[t+1]||t>=2&&f[t-2]<=f[t]+f[t-1])f[t-1]f[t+1])break;o(t)}}function r(){for(;y>1;){var t=y-2;t>0&&f[t-1]=c||g>=c);if(m)break;v<0&&(v=0),v+=2}if(p=v,p<1&&(p=1),1===n){for(l=0;l=0;l--)t[g+l]=t[f+l];return void(t[d]=x[u])}for(var m=p;;){var v=0,y=0,_=!1;do if(e(x[u],t[h])<0){if(t[d--]=t[h--],v++,y=0,0===--n){_=!0;break}}else if(t[d--]=x[u--],y++,v=0,1===--o){_=!0;break}while((v|y)=0;l--)t[g+l]=t[f+l];if(0===n){_=!0;break}}if(t[d--]=x[u--],1===--o){_=!0;break}if(y=o-a(t[h],x,0,o,o-1,e),0!==y){for(d-=y,u-=y,o-=y,g=d+1,f=u+1,l=0;l=c||y>=c);if(_)break;m<0&&(m=0),m+=2}if(p=m,p<1&&(p=1),1===o){for(d-=n,h-=n,g=d+1,f=h+1,l=n-1;l>=0;l--)t[g+l]=t[f+l];t[d]=x[u]}else{if(0===o)throw new Error;for(f=d-(o-1),l=0;l>>1);var x=[];v=g<120?5:g<1542?10:g<119151?19:40,u=[],f=[],this.mergeRuns=n,this.forceMergeRuns=r,this.pushRun=i}function h(t,e,r,a){r||(r=0),a||(a=t.length);var s=a-r;if(!(s<2)){var h=0;if(sd&&(f=d),o(t,r,r+f,r+h,e),h=f}c.pushRun(r,h),c.mergeRuns(),s-=h,r+=h}while(0!==s);c.forceMergeRuns()}}var u=32,c=7,d=256;t.exports=h},function(t,e){var i={},n="\0__throttleOriginMethod",r="\0__throttleRate",o="\0__throttleType";i.throttle=function(t,e,i){function n(){h=(new Date).getTime(),u=null,t.apply(a,s||[])}var r,o,a,s,l=0,h=0,u=null;e=e||0;var c=function(){r=(new Date).getTime(),a=this,s=arguments,o=r-(i?l:h)-e,clearTimeout(u),i?u=setTimeout(n,e):o>=0?n():u=setTimeout(n,-o),l=r};return c.clear=function(){u&&(clearTimeout(u),u=null)},c},i.createOrUpdate=function(t,e,a,s){var l=t[e];if(l){var h=l[n]||l,u=l[o],c=l[r];if(c!==a||u!==s){if(null==a||!s)return t[e]=h;l=t[e]=i.throttle(h,a,"debounce"===s),l[n]=h,l[o]=s,l[r]=a}return l}},i.clear=function(t,e){var i=t[e];i&&i[n]&&(t[e]=i[n])},t.exports=i},function(t,e,i){var n=i(33);t.exports=function(){if(0!==n.debugMode)if(1==n.debugMode)for(var t in arguments)throw new Error(arguments[t]);else if(n.debugMode>1)for(var t in arguments)console.log(arguments[t])}},function(t,e,i){function n(t){r.call(this,t)}var r=i(36),o=i(9),a=i(1),s=i(151),l=new s(50);n.prototype={constructor:n,type:"image",brush:function(t,e){var i,n=this.style,r=n.image;if(n.bind(t,this,e),i="string"==typeof r?this._image:r,!i&&r){var o=l.get(r);if(!o)return i=new Image,i.onload=function(){i.onload=null;for(var t=0;t0?"top":"bottom",n="center"):f(o-v)?(r=i>0?"bottom":"top",n="center"):(r="middle",n=o>0&&o0?"right":"left":i>0?"left":"right"),{rotation:o,textAlign:n,verticalAlign:r}}function o(t,e,i,n){var r,o,a=d(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return f(a-v/2)?(o=l?"bottom":"top",r="center"):f(a-1.5*v)?(o=l?"top":"bottom",r="center"):(o="middle",r=a<1.5*v&&a>v/2?l?"left":"right":l?"right":"left"),{rotation:a,textAlign:r,verticalAlign:o}}function a(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)}var s=i(1),l=i(8),h=i(3),u=i(11),c=i(4),d=c.remRadian,f=c.isRadianAroundZero,p=i(5),g=p.applyTransform,m=s.retrieve,v=Math.PI,y=function(t,e){this.opt=e,this.axisModel=t,s.defaults(e,{labelOffset:0,nameDirection:1,tickDirection:1,labelDirection:1,silent:!0}),this.group=new h.Group;var i=new h.Group({position:e.position.slice(),rotation:e.rotation});i.updateTransform(),this._transform=i.transform,this._dumbGroup=i};y.prototype={constructor:y,hasBuilder:function(t){return!!x[t]},add:function(t){x[t].call(this)},getGroup:function(){return this.group}};var x={axisLine:function(){var t=this.opt,e=this.axisModel;if(e.get("axisLine.show")){var i=this.axisModel.axis.getExtent(),n=this._transform,r=[i[0],0],o=[i[1],0];n&&(g(r,r,n),g(o,o,n)),this.group.add(new h.Line(h.subPixelOptimizeLine({anid:"line",shape:{x1:r[0],y1:r[1],x2:o[0],y2:o[1]},style:s.extend({lineCap:"round"},e.getModel("axisLine.lineStyle").getLineStyle()),strokeContainThreshold:t.strokeContainThreshold||5,silent:!0,z2:1})))}},axisTick:function(){var t=this.axisModel,e=t.axis;if(t.get("axisTick.show")&&!e.isBlank())for(var i=t.getModel("axisTick"),n=this.opt,r=i.getModel("lineStyle"),o=i.get("length"),a=b(i,n.labelInterval),l=e.getTicksCoords(i.get("alignWithLabel")),u=e.scale.getTicks(),c=[],d=[],f=this._transform,p=0;pg[1]?-1:1,x=["start"===c?g[0]-y*p:"end"===c?g[1]+y*p:(g[0]+g[1])/2,"middle"===c?t.labelOffset+d*p:0],_=e.get("nameRotate");null!=_&&(_=_*v/180);var b;"middle"===c?u=r(t,null!=_?_:t.rotation,d):(u=o(t,c,_||0,g),b=t.axisNameAvailableWidth,null!=b&&(b=Math.abs(b/Math.sin(u.rotation)),!isFinite(b)&&(b=null)));var w=f.getFont(),M=e.get("nameTruncate",!0)||{},S=M.ellipsis,T=m(M.maxWidth,b),A=null!=S&&null!=T?l.truncateText(i,T,w,S,{minChar:2,placeholder:M.placeholder}):i,I=e.get("tooltip",!0),C=e.mainType,k={componentType:C,name:i,$vars:["name"]};k[C+"Index"]=e.componentIndex;var L=new h.Text({anid:"name",__fullText:i,__truncatedText:A,style:{text:A,textFont:w,fill:f.getTextColor()||e.get("axisLine.lineStyle.color"),textAlign:u.textAlign,textVerticalAlign:u.verticalAlign},position:x,rotation:u.rotation,silent:a(e),z2:1,tooltip:I&&I.show?s.extend({content:i,formatter:function(){return i},formatterParams:k},I):null});e.get("triggerEvent")&&(L.eventData=n(e),L.eventData.targetType="axisName",L.eventData.name=i),this._dumbGroup.add(L),L.updateTransform(),this.group.add(L),L.decomposeTransform()}}},_=y.ifIgnoreOnTick=function(t,e,i){var n,r=t.scale;return"ordinal"===r.type&&("function"==typeof i?(n=r.getTicks()[e],!i(n,r.getLabel(n))):e%(i+1))},b=y.getInterval=function(t,e){var i=t.get("interval");return null!=i&&"auto"!=i||(i=e),i};t.exports=y},function(t,e,i){function n(t){return r.isObject(t)&&null!=t.value?t.value:t}var r=i(1),o=i(22);t.exports={getFormattedLabels:function(){return o.getFormattedLabels(this.axis,this.get("axisLabel.formatter"))},getCategories:function(){return"category"===this.get("type")&&r.map(this.get("data"),n)},getMin:function(t){var e=this.option,i=t||null==e.rangeStart?e.min:e.rangeStart;return null==i||"dataMin"===i||r.eqNaN(i)||(i=this.axis.scale.parse(i)),i},getMax:function(t){var e=this.option,i=t||null==e.rangeEnd?e.max:e.rangeEnd;return null==i||"dataMax"===i||r.eqNaN(i)||(i=this.axis.scale.parse(i)),i},getNeedCrossZero:function(){var t=this.option;return null==t.rangeStart&&null==t.rangeEnd&&!t.scale},getCoordSysModel:r.noop,setRange:function(t,e){this.option.rangeStart=t,this.option.rangeEnd=e},resetRange:function(){this.option.rangeStart=this.option.rangeEnd=null}}},function(t,e,i){function n(t,e,i){return t.getCoordSysModel()===e}function r(t){var e,i=t.model,n=i.getFormattedLabels(),r=i.getModel("axisLabel.textStyle"),o=1,a=n.length;a>40&&(o=Math.ceil(a/40));for(var s=0;s.5?e:t}function s(t,e,i,n,r){var a=t.length;if(1==r)for(var s=0;sr;if(o)t.length=r;else for(var a=n;a=0&&!(A[i]<=e);i--);i=Math.min(i,x-2)}else{for(i=F;ie);i++);i=Math.min(i-1,x-2)}F=i,G=e;var n=A[i+1]-A[i];if(0!==n)if(E=(e-A[i])/n,v)if(R=I[i],N=I[0===i?i:i-1],B=I[i>x-2?x-1:i+1],V=I[i>x-3?x-1:i+2],w)u(N,R,B,V,E,E*E,E*E*E,d(t,r),T);else{var l;if(M)l=u(N,R,B,V,E,E*E,E*E*E,H,1),l=f(H);else{if(S)return a(R,B,E);l=c(N,R,B,V,E,E*E,E*E*E)}p(t,r,l)}else if(w)s(I[i],I[i+1],E,d(t,r),T);else{var l;if(M)s(I[i],I[i+1],E,H,1),l=f(H);else{if(S)return a(I[i],I[i+1],E);l=o(I[i],I[i+1],E)}p(t,r,l)}},Z=new g({target:t._target,life:_,loop:t._loop,delay:t._delay,onframe:W,ondestroy:i});return e&&"spline"!==e&&(Z.easing=e),Z}}}var g=i(145),m=i(19),v=i(1),y=v.isArrayLike,x=Array.prototype.slice,_=function(t,e,i,o){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||n,this._setter=o||r,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};_.prototype={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var r=this._getter(this._target,n);if(null==r)continue;0!==t&&i[n].push({time:0,value:d(r)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},_doneCallback:function(){this._tracks={},this._clipList.length=0;for(var t=this._doneList,e=t.length,i=0;i0},extendFrom:function(t,e){if(t){var i=this;for(var n in t)!t.hasOwnProperty(n)||!e&&i.hasOwnProperty(n)||(i[n]=t[n])}},set:function(t,e){"string"==typeof t?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(t,e,r){for(var o="radial"===e.type?n:i,a=o(t,e,r),s=e.colorStops,l=0;l=2){if(a&&"spline"!==a){var s=r(o,a,i,e.smoothConstraint);t.moveTo(o[0][0],o[0][1]);for(var l=o.length,h=0;h<(i?l:l-1);h++){var u=s[2*h],c=s[2*h+1],d=o[(h+1)%l];t.bezierCurveTo(u[0],u[1],c[0],c[1],d[0],d[1])}}else{"spline"===a&&(o=n(o,i)),t.moveTo(o[0][0],o[0][1]);for(var h=1,f=o.length;h=0},o.createNameEach=function(t,e){t=t.slice();var i=r.map(t,n.capitalFirst);e=(e||[]).slice();var o=r.map(e,n.capitalFirst);return function(n,a){r.each(t,function(t,r){for(var s={name:t,capital:i[r]},l=0;l=0}function o(t,n){var o=!1;return e(function(e){r.each(i(t,e)||[],function(t){n.records[e.name][t]&&(o=!0)})}),o}function a(t,n){n.nodes.push(t),e(function(e){r.each(i(t,e)||[],function(t){n.records[e.name][t]=!0})})}return function(i){function r(t){!n(t,s)&&o(t,s)&&(a(t,s),l=!0)}var s={nodes:[],records:{}};if(e(function(t){s.records[t.name]={}}),!i)return s;a(i,s);var l;do l=!1,t(r);while(l);return s}},t.exports=o},function(t,e,i){var n=i(1);t.exports={updateSelectedMap:function(t){this._selectTargetMap=n.reduce(t||[],function(t,e){return t[e.name]=e,t},{})},select:function(t){var e=this._selectTargetMap,i=e[t],r=this.get("selectedMode"); +"single"===r&&n.each(e,function(t){t.selected=!1}),i&&(i.selected=!0)},unSelect:function(t){var e=this._selectTargetMap[t];e&&(e.selected=!1)},toggleSelected:function(t){var e=this._selectTargetMap[t];if(null!=e)return this[e.selected?"unSelect":"select"](t),e.selected},isSelected:function(t){var e=this._selectTargetMap[t];return e&&e.selected}}},function(t,e,i){function n(t){r.defaultEmphasis(t.label,r.LABEL_OPTIONS)}var r=i(6),o=i(1),a=i(10),s=i(8),l=s.addCommas,h=s.encodeHTML,u=i(2).extendComponentModel({type:"marker",dependencies:["series","grid","polar","geo"],init:function(t,e,i,n){this.mergeDefaultAndTheme(t,i),this.mergeOption(t,i,n.createdBySelf,!0)},isAnimationEnabled:function(){if(a.node)return!1;var t=this.__hostSeries;return this.getShallow("animation")&&t&&t.isAnimationEnabled()},mergeOption:function(t,e,i,r){var a=this.constructor,s=this.mainType+"Model";i||e.eachSeries(function(t){var i=t.get(this.mainType),l=t[s];return i&&i.data?(l?l.mergeOption(i,e,!0):(r&&n(i),o.each(i.data,function(t){t instanceof Array?(n(t[0]),n(t[1])):n(t)}),l=new a(i,this,e),o.extend(l,{mainType:this.mainType,seriesIndex:t.seriesIndex,name:t.name,createdBySelf:!0}),l.__hostSeries=t),void(t[s]=l)):void(t[s]=null)},this)},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=o.isArray(i)?o.map(i,l).join(", "):l(i),r=e.getName(t),a=h(this.name);return(null!=i||r)&&(a+="
    "),r&&(a+=h(r),null!=i&&(a+=" : ")),null!=i&&(a+=h(n)),a},getData:function(){return this._data},setData:function(t){this._data=t}});o.mixin(u,r.dataFormatMixin),t.exports=u},function(t,e,i){t.exports=i(2).extendComponentView({type:"marker",init:function(){this.markerGroupMap={}},render:function(t,e,i){var n=this.markerGroupMap;for(var r in n)n.hasOwnProperty(r)&&(n[r].__keep=!1);var o=this.type+"Model";e.eachSeries(function(t){var n=t[o];n&&this.renderSeries(t,n,e,i)},this);for(var r in n)n.hasOwnProperty(r)&&!n[r].__keep&&this.group.remove(n[r].group)},renderSeries:function(){}})},function(t,e,i){function n(t){return!(isNaN(parseFloat(t.x))&&isNaN(parseFloat(t.y)))}function r(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}function o(t,e,i){var n=-1;do n=Math.max(l.getPrecision(t.get(e,i)),n),t=t.stackedOn;while(t);return n}function a(t,e,i,n,r,a){var s=[],l=m(e,n,t),h=e.indexOfNearest(n,l,!0);s[r]=e.get(i,h,!0),s[a]=e.get(n,h,!0);var u=o(e,n,h);return u>=0&&(s[a]=+s[a].toFixed(u)),s}var s=i(1),l=i(4),h=s.indexOf,u=s.curry,c={min:u(a,"min"),max:u(a,"max"),average:u(a,"average")},d=function(t,e){var i=t.getData(),n=t.coordinateSystem;if(e&&!r(e)&&!s.isArray(e.coord)&&n){var o=n.dimensions,a=f(e,i,n,t);if(e=s.clone(e),e.type&&c[e.type]&&a.baseAxis&&a.valueAxis){var l=h(o,a.baseAxis.dim),u=h(o,a.valueAxis.dim);e.coord=c[e.type](i,a.baseDataDim,a.valueDataDim,l,u),e.value=e.coord[u]}else{for(var d=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],p=0;p<2;p++)if(c[d[p]]){var g=t.coordDimToDataDim(o[p])[0];d[p]=m(i,g,d[p])}e.coord=d}}return e},f=function(t,e,i,n){var r={};return null!=t.valueIndex||null!=t.valueDim?(r.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,r.valueAxis=i.getAxis(n.dataDimToCoordDim(r.valueDataDim)),r.baseAxis=i.getOtherAxis(r.valueAxis),r.baseDataDim=n.coordDimToDataDim(r.baseAxis.dim)[0]):(r.baseAxis=n.getBaseAxis(),r.valueAxis=i.getOtherAxis(r.baseAxis),r.baseDataDim=n.coordDimToDataDim(r.baseAxis.dim)[0],r.valueDataDim=n.coordDimToDataDim(r.valueAxis.dim)[0]),r},p=function(t,e){return!(t&&t.containData&&e.coord&&!n(e))||t.containData(e.coord)},g=function(t,e,i,n){return n<2?t.coord&&t.coord[n]:t.value},m=function(t,e,i){if("average"===i){var n=0,r=0;return t.each(e,function(t,e){isNaN(t)||(n+=t,r++)},!0),n/r}return t.getDataExtent(e,!0)["max"===i?1:0]};t.exports={dataTransform:d,dataFilter:p,dimValueGetter:g,getAxisInfo:f,numCalculate:m}},,function(t,e){t.exports=function(t,e){var i={};e.eachRawSeriesByType(t,function(t){var n=t.getRawData(),r={};if(!e.isSeriesFiltered(t)){var o=t.getData();o.each(function(t){var e=o.getRawIndex(t);r[e]=t}),n.each(function(e){var a=r[e],s=null!=a&&o.getItemVisual(a,"color",!0);if(s)n.setItemVisual(e,"color",s);else{var l=n.getItemModel(e),h=l.get("itemStyle.normal.color")||t.getColorFromPalette(n.getName(e),i);n.setItemVisual(e,"color",h),null!=a&&o.setItemVisual(a,"color",h)}})}})}},function(t,e,i){var n=i(5),r=i(18),o={},a=Math.min,s=Math.max,l=Math.sin,h=Math.cos,u=n.create(),c=n.create(),d=n.create(),f=2*Math.PI;o.fromPoints=function(t,e,i){if(0!==t.length){var n,r=t[0],o=r[0],l=r[0],h=r[1],u=r[1];for(n=1;n1e-4)return p[0]=t-i,p[1]=e-r,g[0]=t+i,void(g[1]=e+r);if(u[0]=h(o)*i+t,u[1]=l(o)*r+e,c[0]=h(a)*i+t,c[1]=l(a)*r+e,m(p,u,c),v(g,u,c),o%=f,o<0&&(o+=f),a%=f,a<0&&(a+=f),o>a&&!s?a+=f:oo&&(d[0]=h(_)*i+t,d[1]=l(_)*r+e,m(p,d,p),v(g,d,g))},t.exports=o},function(t,e,i){var n=i(36),r=i(1),o=i(17),a=function(t){n.call(this,t)};a.prototype={constructor:a,type:"text",brush:function(t,e){var i=this.style,n=i.x||0,r=i.y||0,a=i.text;if(null!=a&&(a+=""),i.bind(t,this,e),a){this.setTransform(t);var s,l=i.textAlign,h=i.textFont||i.font;if(i.textVerticalAlign){var u=o.getBoundingRect(a,h,i.textAlign,"top");switch(s="middle",i.textVerticalAlign){case"middle":r-=u.height/2-u.lineHeight/2;break;case"bottom":r-=u.height-u.lineHeight/2;break;default:r+=u.lineHeight/2}}else s=i.textBaseline;t.font=h||"12px sans-serif",t.textAlign=l||"left",t.textAlign!==l&&(t.textAlign="left"),t.textBaseline=s||"alphabetic",t.textBaseline!==s&&(t.textBaseline="alphabetic");for(var c=o.measureText("国",t.font).width,d=a.split("\n"),f=0;f=0?parseFloat(t)/100*e:parseFloat(t):t}var r=i(17),o=i(9),a=new o,s=function(){};s.prototype={constructor:s,drawRectText:function(t,e,i){var o=this.style,s=o.text;if(null!=s&&(s+=""),s){t.save();var l,h,u=o.textPosition,c=o.textOffset,d=o.textDistance,f=o.textAlign,p=o.textFont||o.font,g=o.textBaseline,m=o.textVerticalAlign;i=i||r.getBoundingRect(s,p,f,g);var v=this.transform;if(o.textTransform?this.setTransform(t):v&&(a.copy(e),a.applyTransform(v),e=a),u instanceof Array){if(l=e.x+n(u[0],e.width),h=e.y+n(u[1],e.height),f=f||"left",g=g||"top",m){switch(m){case"middle":h-=i.height/2-i.lineHeight/2;break;case"bottom":h-=i.height-i.lineHeight/2;break;default:h+=i.lineHeight/2}g="middle"}}else{var y=r.adjustTextPositionOnRect(u,e,i,d);l=y.x,h=y.y,f=f||y.textAlign,g=g||y.textBaseline}c&&(l+=c[0],h+=c[1]),t.textAlign=f||"left",t.textBaseline=g||"alphabetic";var x=o.textFill,_=o.textStroke;x&&(t.fillStyle=x),_&&(t.strokeStyle=_),t.font=p||"12px sans-serif",t.shadowBlur=o.textShadowBlur,t.shadowColor=o.textShadowColor||"transparent",t.shadowOffsetX=o.textShadowOffsetX,t.shadowOffsetY=o.textShadowOffsetY;var b=s.split("\n");o.textRotation&&(v&&t.translate(v[4],v[5]),t.rotate(o.textRotation),v&&t.translate(-v[4],-v[5]));for(var w=0;w=o||b<0)break;if(n(M)){if(x){b+=a;continue}break}if(b===i)t[a>0?"moveTo":"lineTo"](M[0],M[1]),c(f,M);else if(v>0){var S=b+a,T=e[S];if(x)for(;T&&n(e[S]);)S+=a,T=e[S];var A=.5,I=e[_],T=e[S];if(!T||n(T))c(p,M);else{n(T)&&!x&&(T=M),s.sub(d,T,I);var C,k;if("x"===y||"y"===y){var L="x"===y?0:1;C=Math.abs(M[L]-I[L]),k=Math.abs(M[L]-T[L])}else C=s.dist(M,I),k=s.dist(M,T);A=k/(k+C),u(p,M,d,-v*(1-A))}l(f,f,m),h(f,f,g),l(p,p,m),h(p,p,g),t.bezierCurveTo(f[0],f[1],p[0],p[1],M[0],M[1]),u(f,M,d,v*A)}else t.lineTo(M[0],M[1]);_=b,b+=a}return w}function o(t,e){var i=[1/0,1/0],n=[-(1/0),-(1/0)];if(e)for(var r=0;rn[0]&&(n[0]=o[0]),o[1]>n[1]&&(n[1]=o[1])}return{min:e?i:n,max:e?n:i}}var a=i(7),s=i(5),l=s.min,h=s.max,u=s.scaleAndAdd,c=s.copy,d=[],f=[],p=[];t.exports={Polyline:a.extend({type:"ec-polyline",shape:{points:[],smooth:0,smoothConstraint:!0,smoothMonotone:null,connectNulls:!1},style:{fill:null,stroke:"#000"},buildPath:function(t,e){var i=e.points,a=0,s=i.length,l=o(i,e.smoothConstraint);if(e.connectNulls){for(;s>0&&n(i[s-1]);s--);for(;a0&&n(i[l-1]);l--);for(;s0?1.1:1/1.1;l.call(this,t,e,t.offsetX,t.offsetY)}function s(t){if(!f.isTaken(this._zr,"globalPan")){var e=t.pinchScale>1?1.1:1/1.1;l.call(this,t,e,t.pinchX,t.pinchY)}}function l(t,e,i,n){if(this.containsPoint&&this.containsPoint(i,n)){d.stop(t.event);var r=this.target,o=this.zoomLimit;if(r){var a=r.position,s=r.scale,l=this.zoom=this.zoom||1;if(l*=e,o){var h=o.min||0,u=o.max||1/0;l=Math.max(Math.min(u,l),h)}var c=l/this.zoom;this.zoom=l,a[0]-=(i-a[0])*(c-1),a[1]-=(n-a[1])*(c-1),s[0]*=c,s[1]*=c,r.dirty()}this.trigger("zoom",e,i,n)}}function h(t,e){this.target=e,this.containsPoint,this.zoomLimit,this.zoom,this._zr=t;var i=c.bind,l=i(n,this),h=i(r,this),d=i(o,this),f=i(a,this),p=i(s,this);u.call(this),this.setContainsPoint=function(t){this.containsPoint=t},this.enable=function(e){this.disable(),null==e&&(e=!0),e!==!0&&"move"!==e&&"pan"!==e||(t.on("mousedown",l),t.on("mousemove",h),t.on("mouseup",d)),e!==!0&&"scale"!==e&&"zoom"!==e||(t.on("mousewheel",f),t.on("pinch",p))},this.disable=function(){t.off("mousedown",l),t.off("mousemove",h),t.off("mouseup",d),t.off("mousewheel",f),t.off("pinch",p)},this.dispose=this.disable,this.isDragging=function(){return this._dragging},this.isPinching=function(){return this._pinching}}var u=i(21),c=i(1),d=i(25),f=i(117);c.mixin(h,u),t.exports=h},function(t,e){t.exports=function(t,e,i,n,r){function o(t,e,i){var n=e.length?e.slice():[e,e];return e[0]>e[1]&&n.reverse(),t<0&&n[0]+t0&&n[1]+t>i[1]&&(t=i[1]-n[1]),t}return t?("rigid"===n?(t=o(t,e,i),e[0]+=t,e[1]+=t):(t=o(t,e[r],i),e[r]+=t,"push"===n&&e[0]>e[1]&&(e[1-r]=e[r])),e):e}},function(t,e,i){var n=i(1),r={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisLine:{show:!0,onZero:!0,lineStyle:{color:"#333",width:1,type:"solid"}},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,margin:8,textStyle:{fontSize:12}},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},o=n.merge({boundaryGap:!0,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},r),a=n.merge({boundaryGap:[0,0],splitNumber:5},r),s=n.defaults({scale:!0,min:"dataMin",max:"dataMax"},a),l=n.defaults({logBase:10},a);l.scale=!0,t.exports={categoryAxis:o,valueAxis:a,timeAxis:s,logAxis:l}},function(t,e,i){"use strict";function n(t){return t.get("stack")||"__ec_stack_"+t.seriesIndex}function r(t){return t.dim+t.index}function o(t,e){var i={};s.each(t,function(t,e){var o=t.getData(),a=t.coordinateSystem,s=a.getBaseAxis(),l=s.getExtent(),u="category"===s.type?s.getBandWidth():Math.abs(l[1]-l[0])/o.count(),c=i[r(s)]||{bandWidth:u,remainedWidth:u,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},d=c.stacks;i[r(s)]=c;var f=n(t);d[f]||c.autoWidthCount++,d[f]=d[f]||{width:0,maxWidth:0};var p=h(t.get("barWidth"),u),g=h(t.get("barMaxWidth"),u),m=t.get("barGap"),v=t.get("barCategoryGap");p&&!d[f].width&&(p=Math.min(c.remainedWidth,p),d[f].width=p,c.remainedWidth-=p),g&&(d[f].maxWidth=g),null!=m&&(c.gap=m),null!=v&&(c.categoryGap=v)});var o={};return s.each(i,function(t,e){o[e]={};var i=t.stacks,n=t.bandWidth,r=h(t.categoryGap,n),a=h(t.gap,1),l=t.remainedWidth,u=t.autoWidthCount,c=(l-r)/(u+(u-1)*a);c=Math.max(c,0),s.each(i,function(t,e){var i=t.maxWidth;!t.width&&i&&i=0?"p":"n",v=m[i],y=l[s][i][u],x=h[s][i][u];f.isHorizontal()?(n=y,r=v[1]+c,o=v[0]-x,a=d,h[s][i][u]+=o,Math.abs(o)e+s&&a>n+s||at+s&&o>i+s||oe+u&&h>r+u&&h>a+u||ht+u&&l>i+u&&l>o+u||le&&o>n||or?a:0}},function(t,e,i){"use strict";var n=i(1),r=i(37),o=function(t,e,i,n,o,a){this.x=null==t?0:t,this.y=null==e?0:e,this.x2=null==i?1:i,this.y2=null==n?0:n,this.type="linear",this.global=a||!1,r.call(this,o)};o.prototype={constructor:o},n.inherits(o,r),t.exports=o},function(t,e,i){"use strict";function n(t){return t>s||t<-s}var r=i(20),o=i(5),a=r.identity,s=5e-5,l=function(t){t=t||{},t.position||(this.position=[0,0]),null==t.rotation&&(this.rotation=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},h=l.prototype;h.transform=null,h.needLocalTransform=function(){return n(this.rotation)||n(this.position[0])||n(this.position[1])||n(this.scale[0]-1)||n(this.scale[1]-1)},h.updateTransform=function(){var t=this.parent,e=t&&t.transform,i=this.needLocalTransform(),n=this.transform;return i||e?(n=n||r.create(),i?this.getLocalTransform(n):a(n),e&&(i?r.mul(n,t.transform,n):r.copy(n,t.transform)),this.transform=n,this.invTransform=this.invTransform||r.create(),void r.invert(this.invTransform,n)):void(n&&a(n))},h.getLocalTransform=function(t){t=t||[],a(t);var e=this.origin,i=this.scale,n=this.rotation,o=this.position;return e&&(t[4]-=e[0],t[5]-=e[1]),r.scale(t,t,i),n&&r.rotate(t,t,n),e&&(t[4]+=e[0],t[5]+=e[1]),t[4]+=o[0],t[5]+=o[1],t},h.setTransform=function(t){var e=this.transform,i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},h.restoreTransform=function(t){var e=(this.transform,t.dpr||1);t.setTransform(e,0,0,e,0,0)};var u=[];h.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(r.mul(u,t.invTransform,e),e=u);var i=e[0]*e[0]+e[1]*e[1],o=e[2]*e[2]+e[3]*e[3],a=this.position,s=this.scale;n(i-1)&&(i=Math.sqrt(i)),n(o-1)&&(o=Math.sqrt(o)),e[0]<0&&(i=-i),e[3]<0&&(o=-o),a[0]=e[4],a[1]=e[5],s[0]=i,s[1]=o,this.rotation=Math.atan2(-e[1]/o,e[0]/i)}},h.getGlobalScale=function(){var t=this.transform;if(!t)return[1,1];var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]),i=Math.sqrt(t[2]*t[2]+t[3]*t[3]);return t[0]<0&&(e=-e),t[3]<0&&(i=-i),[e,i]},h.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&o.applyTransform(i,i,n),i},h.transformCoordToGlobal=function(t,e){var i=[t,e],n=this.transform;return n&&o.applyTransform(i,i,n),i},t.exports=l},function(t,e,i){"use strict";function n(t){r.each(o,function(e){this[e]=r.bind(t[e],t)},this)}var r=i(1),o=["getDom","getZr","getWidth","getHeight","dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL","getModel","getOption"];t.exports=n},function(t,e,i){var n=i(1);i(53),i(95),i(96);var r=i(87),o=i(2);o.registerLayout(n.curry(r,"bar")),o.registerVisual(function(t){t.eachSeriesByType("bar",function(t){var e=t.getData();e.setVisual("legendSymbol","roundRect")})}),i(31)},function(t,e,i){t.exports=i(80).extend({type:"series.bar",dependencies:["grid","polar"],brushSelector:"rect"})},function(t,e,i){"use strict";function n(t,e,i,n,r,o,a){var s=new h.Rect({shape:l.extend({},n)});if(o){var u=s.shape,c=r?"height":"width",d={};u[c]=0,d[c]=n[c],h[a?"updateProps":"initProps"](s,{shape:d},o,e)}return s}function r(t,e,i){i.style.text="",h.updateProps(i,{shape:{width:0}},e,t,function(){i.parent&&i.parent.remove(i)})}function o(t,e,i){var n=t.getItemLayout(e),r=s(i,n),o=n.width>0?1:-1,a=n.height>0?1:-1;return{x:n.x+o*r/2,y:n.y+a*r/2,width:n.width-o*r,height:n.height-a*r}}function a(t,e,i,n,r,o,a){var s=e.getItemVisual(i,"color"),c=e.getItemVisual(i,"opacity"),d=n.getModel("itemStyle.normal"),f=n.getModel("itemStyle.emphasis").getBarItemStyle();t.setShape("r",d.get("barBorderRadius")||0),t.useStyle(l.defaults({fill:s,opacity:c},d.getBarItemStyle()));var p=a?r.height>0?"bottom":"top":r.width>0?"left":"right";u.setLabel(t.style,f,n,s,o,i,p),h.setHoverStyle(t,f)}function s(t,e){var i=t.get(c)||0;return Math.min(i,Math.abs(e.width),Math.abs(e.height))}var l=i(1),h=i(3),u=i(81),c=["itemStyle","normal","barBorderWidth"];l.extend(i(11).prototype,i(97));var d=i(2).extendChartView({type:"bar",render:function(t,e,i){var n=t.get("coordinateSystem");return"cartesian2d"===n&&this._renderOnCartesian(t,e,i),this.group},dispose:l.noop,_renderOnCartesian:function(t,e,i){var s=this.group,l=t.getData(),u=this._data,c=t.coordinateSystem,d=c.getBaseAxis(),f=d.isHorizontal(),p=t.isAnimationEnabled()?t:null;l.diff(u).add(function(e){if(l.hasValue(e)){var i=l.getItemModel(e),r=o(l,e,i),h=n(l,e,i,r,f,p);l.setItemGraphicEl(e,h),s.add(h),a(h,l,e,i,r,t,f)}}).update(function(e,i){var r=u.getItemGraphicEl(i);if(!l.hasValue(e))return void s.remove(r);var c=l.getItemModel(e),d=o(l,e,c);r?h.updateProps(r,{shape:d},p,e):r=n(l,e,c,d,f,p,!0),l.setItemGraphicEl(e,r),s.add(r),a(r,l,e,c,d,t,f)}).remove(function(t){var e=u.getItemGraphicEl(t);e&&r(t,p,e)}).execute(),this._data=l},remove:function(t,e){var i=this.group,n=this._data;t.get("animation")?n&&n.eachItemGraphicEl(function(e){r(e.dataIndex,t,e)}):i.removeAll()}});t.exports=d},function(t,e,i){var n=i(30)([["fill","color"],["stroke","borderColor"],["lineWidth","borderWidth"],["stroke","barBorderColor"],["lineWidth","barBorderWidth"],["opacity"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]);t.exports={getBarItemStyle:function(t){var e=n.call(this,t);if(this.getBorderLineDash){var i=this.getBorderLineDash();i&&(e.lineDash=i)}return e}}},function(t,e,i){function n(t){return"_"+t+"Type"}function r(t,e,i){var n=e.getItemVisual(i,"color"),r=e.getItemVisual(i,t),o=e.getItemVisual(i,t+"Size");if(r&&"none"!==r){f.isArray(o)||(o=[o,o]);var a=h.createSymbol(r,-o[0]/2,-o[1]/2,o[0],o[1],n);return a.name=t,a}}function o(t){var e=new c({name:"line"});return a(e.shape,t),e}function a(t,e){var i=e[0],n=e[1],r=e[2];t.x1=i[0],t.y1=i[1],t.x2=n[0],t.y2=n[1],t.percent=1,r?(t.cpx1=r[0],t.cpy1=r[1]):(t.cpx1=NaN,t.cpy1=NaN)}function s(){var t=this,e=t.childOfName("fromSymbol"),i=t.childOfName("toSymbol"),n=t.childOfName("label");if(e||i||!n.ignore){for(var r=1,o=this.parent;o;)o.scale&&(r/=o.scale[0]),o=o.parent;var a=t.childOfName("line");if(this.__dirty||a.__dirty){var s=a.shape.percent,l=a.pointAt(0),h=a.pointAt(s),c=u.sub([],h,l);if(u.normalize(c,c),e){e.attr("position",l);var d=a.tangentAt(0);e.attr("rotation",Math.PI/2-Math.atan2(d[1],d[0])),e.attr("scale",[r*s,r*s])}if(i){i.attr("position",h);var d=a.tangentAt(1);i.attr("rotation",-Math.PI/2-Math.atan2(d[1],d[0])),i.attr("scale",[r*s,r*s])}if(!n.ignore){n.attr("position",h);var f,p,g,m=5*r;if("end"===n.__position)f=[c[0]*m+h[0],c[1]*m+h[1]],p=c[0]>.8?"left":c[0]<-.8?"right":"center",g=c[1]>.8?"top":c[1]<-.8?"bottom":"middle";else if("middle"===n.__position){var v=s/2,d=a.tangentAt(v),y=[d[1],-d[0]],x=a.pointAt(v);y[1]>0&&(y[0]=-y[0],y[1]=-y[1]),f=[x[0]+y[0]*m,x[1]+y[1]*m],p="center",g="bottom";var _=-Math.atan2(d[1],d[0]);h[0].8?"right":c[0]<-.8?"left":"center",g=c[1]>.8?"bottom":c[1]<-.8?"top":"middle";n.attr({style:{textVerticalAlign:n.__verticalAlign||g,textAlign:n.__textAlign||p},position:f,scale:[r,r]})}}}}function l(t,e,i){d.Group.call(this),this._createLine(t,e,i)}var h=i(24),u=i(5),c=i(177),d=i(3),f=i(1),p=i(4),g=["fromSymbol","toSymbol"],m=l.prototype;m.beforeUpdate=s,m._createLine=function(t,e,i){var a=t.hostModel,s=t.getItemLayout(e),l=o(s);l.shape.percent=0,d.initProps(l,{shape:{percent:1}},a,e),this.add(l);var h=new d.Text({name:"label"});this.add(h),f.each(g,function(i){var o=r(i,t,e);this.add(o),this[n(i)]=t.getItemVisual(e,i)},this),this._updateCommonStl(t,e,i)},m.updateData=function(t,e,i){var o=t.hostModel,s=this.childOfName("line"),l=t.getItemLayout(e),h={shape:{}};a(h.shape,l),d.updateProps(s,h,o,e),f.each(g,function(i){var o=t.getItemVisual(e,i),a=n(i);if(this[a]!==o){this.remove(this.childOfName(i));var s=r(i,t,e);this.add(s)}this[a]=o},this),this._updateCommonStl(t,e,i)},m._updateCommonStl=function(t,e,i){var n=t.hostModel,r=this.childOfName("line"),o=i&&i.lineStyle,a=i&&i.hoverLineStyle,s=i&&i.labelModel,l=i&&i.hoverLabelModel;if(!i||t.hasItemOption){var h=t.getItemModel(e);o=h.getModel("lineStyle.normal").getLineStyle(),a=h.getModel("lineStyle.emphasis").getLineStyle(),s=h.getModel("label.normal"),l=h.getModel("label.emphasis")}var u=t.getItemVisual(e,"color"),c=f.retrieve(t.getItemVisual(e,"opacity"),o.opacity,1);r.useStyle(f.defaults({strokeNoScale:!0,fill:"none",stroke:u,opacity:c},o)),r.hoverStyle=a,f.each(g,function(t){var e=this.childOfName(t);e&&(e.setColor(u),e.setStyle({opacity:c}))},this);var m,v,y=s.getShallow("show"),x=l.getShallow("show"),_=this.childOfName("label");if(y||x){var b=n.getRawValue(e);v=null==b?v=t.getName(e):isFinite(b)?p.round(b):b,m=u||"#000"}if(y){var w=s.getModel("textStyle");_.setStyle({text:f.retrieve(n.getFormattedLabel(e,"normal",t.dataType),v),textFont:w.getFont(),fill:w.getTextColor()||m}),_.__textAlign=w.get("align"),_.__verticalAlign=w.get("baseline"),_.__position=s.get("position")}else _.setStyle("text","");if(x){var M=l.getModel("textStyle");_.hoverStyle={text:f.retrieve(n.getFormattedLabel(e,"emphasis",t.dataType),v),textFont:M.getFont(),fill:M.getTextColor()||m}}else _.hoverStyle={text:""};_.ignore=!y&&!x,d.setHoverStyle(this)},m.updateLayout=function(t,e){this.setLinePoints(t.getItemLayout(e))},m.setLinePoints=function(t){var e=this.childOfName("line");a(e.shape,t),e.dirty()},f.inherits(l,d.Group),t.exports=l},function(t,e,i){function n(t){return isNaN(t[0])||isNaN(t[1])}function r(t){return!n(t[0])&&!n(t[1])}function o(t){this._ctor=t||s,this.group=new a.Group}var a=i(3),s=i(98),l=o.prototype;l.updateData=function(t){var e=this._lineData,i=this.group,n=this._ctor,o=t.hostModel,a={lineStyle:o.getModel("lineStyle.normal").getLineStyle(),hoverLineStyle:o.getModel("lineStyle.emphasis").getLineStyle(),labelModel:o.getModel("label.normal"),hoverLabelModel:o.getModel("label.emphasis")};t.diff(e).add(function(e){if(r(t.getItemLayout(e))){var o=new n(t,e,a);t.setItemGraphicEl(e,o),i.add(o)}}).update(function(o,s){var l=e.getItemGraphicEl(s);return r(t.getItemLayout(o))?(l?l.updateData(t,o,a):l=new n(t,o,a),t.setItemGraphicEl(o,l),void i.add(l)):void i.remove(l)}).remove(function(t){i.remove(e.getItemGraphicEl(t))}).execute(),this._lineData=t},l.updateLayout=function(){var t=this._lineData;t.eachItemGraphicEl(function(e,i){e.updateLayout(t,i)},this)},l.remove=function(){this.group.removeAll()},t.exports=o},function(t,e,i){var n=i(1),r=i(2),o=r.PRIORITY;i(101),i(102),r.registerVisual(n.curry(i(45),"line","circle","line")),r.registerLayout(n.curry(i(56),"line")),r.registerProcessor(o.PROCESSOR.STATISTIC,n.curry(i(135),"line")),i(31)},function(t,e,i){"use strict";var n=i(35),r=i(16);t.exports=r.extend({type:"series.line",dependencies:["grid","polar"],getInitialData:function(t,e){return n(t.data,this,e)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clipOverflow:!0,label:{normal:{position:"top"}},lineStyle:{normal:{width:2,type:"solid"}},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:!1,connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}})},function(t,e,i){"use strict";function n(t,e){if(t.length===e.length){for(var i=0;ie[0]?1:-1;e[0]+=n*i,e[1]-=n*i}return e}function a(t){return t>=0?1:-1}function s(t,e){var i=t.getBaseAxis(),n=t.getOtherAxis(i),r=i.onZero?0:n.scale.getExtent()[0],o=n.dim,s="x"===o||"radius"===o?1:0;return e.mapArray([o],function(n,l){for(var h,u=e.stackedOn;u&&a(u.get(o,l))===a(n);){h=u;break}var c=[];return c[s]=e.get(i.dim,l),c[1-s]=h?h.get(o,l,!0):r,t.dataToPoint(c)},!0)}function l(t,e,i){var n=o(t.getAxis("x")),r=o(t.getAxis("y")),a=t.getBaseAxis().isHorizontal(),s=Math.min(n[0],n[1]),l=Math.min(r[0],r[1]),h=Math.max(n[0],n[1])-s,u=Math.max(r[0],r[1])-l,c=i.get("lineStyle.normal.width")||2,d=i.get("clipOverflow")?c/2:Math.max(h,u);a?(l-=d,u+=2*d):(s-=d,h+=2*d);var f=new v.Rect({shape:{x:s,y:l,width:h,height:u}});return e&&(f.shape[a?"width":"height"]=0,v.initProps(f,{shape:{width:h,height:u}},i)),f}function h(t,e,i){var n=t.getAngleAxis(),r=t.getRadiusAxis(),o=r.getExtent(),a=n.getExtent(),s=Math.PI/180,l=new v.Sector({shape:{cx:t.cx,cy:t.cy,r0:o[0],r:o[1],startAngle:-a[0]*s,endAngle:-a[1]*s,clockwise:n.inverse}});return e&&(l.shape.endAngle=-a[0]*s,v.initProps(l,{shape:{endAngle:-a[1]*s}},i)),l}function u(t,e,i){return"polar"===t.type?h(t,e,i):l(t,e,i)}function c(t,e,i){for(var n=e.getBaseAxis(),r="x"===n.dim||"radius"===n.dim?0:1,o=[],a=0;a=0;r--)if(i[r].dimension<2){n=i[r];break}if(n&&"cartesian2d"===e.type){var o=n.dimension,a=t.dimensions[o],s=e.getAxis(a),l=f.map(n.stops,function(t){return{coord:s.toGlobalCoord(s.dataToCoord(t.value)),color:t.color}}),h=l.length,u=n.outerColors.slice();h&&l[0].coord>l[h-1].coord&&(l.reverse(),u.reverse());var c=10,d=l[0].coord-c,p=l[h-1].coord+c,g=p-d;if(g<.001)return"transparent";f.each(l,function(t){t.offset=(t.coord-d)/g}),l.push({offset:h?l[h-1].offset:.5,color:u[1]||"transparent"}),l.unshift({offset:h?l[0].offset:.5,color:u[0]||"transparent"});var m=new v.LinearGradient(0,0,0,0,l,(!0));return m[a]=d,m[a+"2"]=p,m}}}var f=i(1),p=i(39),g=i(50),m=i(103),v=i(3),y=i(6),x=i(82),_=i(28);t.exports=_.extend({type:"line",init:function(){var t=new v.Group,e=new p;this.group.add(e.group),this._symbolDraw=e,this._lineGroup=t},render:function(t,e,i){var o=t.coordinateSystem,a=this.group,l=t.getData(),h=t.getModel("lineStyle.normal"),p=t.getModel("areaStyle.normal"),g=l.mapArray(l.getItemLayout,!0),m="polar"===o.type,v=this._coordSys,y=this._symbolDraw,x=this._polyline,_=this._polygon,b=this._lineGroup,w=t.get("animation"),M=!p.isEmpty(),S=s(o,l),T=t.get("showSymbol"),A=T&&!m&&!t.get("showAllSymbol")&&this._getSymbolIgnoreFunc(l,o),I=this._data;I&&I.eachItemGraphicEl(function(t,e){t.__temp&&(a.remove(t),I.setItemGraphicEl(e,null))}),T||y.remove(),a.add(b);var C=!m&&t.get("step");x&&v.type===o.type&&C===this._step?(M&&!_?_=this._newPolygon(g,S,o,w):_&&!M&&(b.remove(_),_=this._polygon=null),b.setClipPath(u(o,!1,t)),T&&y.updateData(l,A),l.eachItemGraphicEl(function(t){t.stopAnimation(!0)}),n(this._stackedOnPoints,S)&&n(this._points,g)||(w?this._updateAnimation(l,S,o,i,C):(C&&(g=c(g,o,C),S=c(S,o,C)),x.setShape({points:g}),_&&_.setShape({points:g,stackedOnPoints:S})))):(T&&y.updateData(l,A),C&&(g=c(g,o,C),S=c(S,o,C)),x=this._newPolyline(g,o,w),M&&(_=this._newPolygon(g,S,o,w)),b.setClipPath(u(o,!0,t)));var k=d(l,o)||l.getVisual("color");x.useStyle(f.defaults(h.getLineStyle(),{fill:"none",stroke:k,lineJoin:"bevel"}));var L=t.get("smooth");if(L=r(t.get("smooth")),x.setShape({smooth:L,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")}),_){var P=l.stackedOn,D=0;if(_.useStyle(f.defaults(p.getAreaStyle(),{fill:k,opacity:.7,lineJoin:"bevel"})),P){var O=P.hostModel;D=r(O.get("smooth"))}_.setShape({smooth:L,stackedOnSmooth:D,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")})}this._data=l,this._coordSys=o,this._stackedOnPoints=S,this._points=g,this._step=C},dispose:function(){},highlight:function(t,e,i,n){var r=t.getData(),o=y.queryDataIndex(r,n);if(!(o instanceof Array)&&null!=o&&o>=0){var a=r.getItemGraphicEl(o);if(!a){var s=r.getItemLayout(o);if(!s)return;a=new g(r,o),a.position=s,a.setZ(t.get("zlevel"),t.get("z")),a.ignore=isNaN(s[0])||isNaN(s[1]),a.__temp=!0,r.setItemGraphicEl(o,a),a.stopSymbolAnimation(!0),this.group.add(a)}a.highlight()}else _.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var r=t.getData(),o=y.queryDataIndex(r,n);if(null!=o&&o>=0){var a=r.getItemGraphicEl(o);a&&(a.__temp?(r.setItemGraphicEl(o,null),this.group.remove(a)):a.downplay())}else _.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new x.Polyline({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new x.Polygon({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_getSymbolIgnoreFunc:function(t,e){var i=e.getAxesByScale("ordinal")[0];if(i&&i.isLabelIgnored)return f.bind(i.isLabelIgnored,i)},_updateAnimation:function(t,e,i,n,r){var o=this._polyline,a=this._polygon,s=t.hostModel,l=m(this._data,t,this._stackedOnPoints,e,this._coordSys,i),h=l.current,u=l.stackedOnCurrent,d=l.next,f=l.stackedOnNext;r&&(h=c(l.current,i,r),u=c(l.stackedOnCurrent,i,r),d=c(l.next,i,r),f=c(l.stackedOnNext,i,r)),o.shape.__points=l.current,o.shape.points=h,v.updateProps(o,{shape:{points:d}},s),a&&(a.setShape({points:h,stackedOnPoints:u}),v.updateProps(a,{shape:{points:d,stackedOnPoints:f}},s));for(var p=[],g=l.status,y=0;y=0?1:-1}function n(t,e,n){for(var r,o=t.getBaseAxis(),a=t.getOtherAxis(o),s=o.onZero?0:a.scale.getExtent()[0],l=a.dim,h="x"===l||"radius"===l?1:0,u=e.stackedOn,c=e.get(l,n);u&&i(u.get(l,n))===i(c);){r=u;break}var d=[];return d[h]=e.get(o.dim,n),d[1-h]=r?r.get(l,n,!0):s,t.dataToPoint(d)}function r(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}t.exports=function(t,e,i,o,a,s){for(var l=r(t,e),h=[],u=[],c=[],d=[],f=[],p=[],g=[],m=s.dimensions,v=0;v0&&"scale"!==d){var g=a.getItemLayout(0),m=Math.max(i.getWidth(),i.getHeight())/2,v=l.bind(h.removeClipPath,h);h.setClipPath(this._createClipPath(g.cx,g.cy,m,g.startAngle,g.clockwise,v,t))}this._data=a}},dispose:function(){},_createClipPath:function(t,e,i,n,r,o,a){var l=new s.Sector({shape:{cx:t,cy:e,r0:0,r:i,startAngle:n,endAngle:n,clockwise:r}});return s.initProps(l,{shape:{endAngle:n+(r?1:-1)*Math.PI*2}},a,o),l},containPoint:function(t,e){var i=e.getData(),n=i.getItemLayout(0);if(n){var r=t[0]-n.cx,o=t[1]-n.cy,a=Math.sqrt(r*r+o*o);return a<=n.r&&a>=n.r0}}});t.exports=u},function(t,e,i){"use strict";function n(t,e,i,n,r,o,a){function s(e,i,n,r){for(var o=e;oe&&o+1t[o].y+t[o].height)return void l(o,n/2);l(i-1,n/2)}function l(e,i){for(var n=e;n>=0&&(t[n].y-=i,!(n>0&&t[n].y>t[n-1].y+t[n-1].height));n--);}function h(t,e,i,n,r,o){for(var a=o>0?e?Number.MAX_VALUE:0:e?Number.MAX_VALUE:0,s=0,l=t.length;s=a&&(d=a-10),!e&&d<=a&&(d=a+10),t[s].x=i+d*o,a=d}}t.sort(function(t,e){return t.y-e.y});for(var u,c=0,d=t.length,f=[],p=[],g=0;g=i?p.push(t[g]):f.push(t[g]);h(f,!1,e,i,n,r),h(p,!0,e,i,n,r)}function r(t,e,i,r,o,a){for(var s=[],l=[],h=0;h0?"left":"right"}var L=g.getModel("textStyle").getFont(),P=g.get("rotate")?b<0?-_+Math.PI:-_:0,D=t.getFormattedLabel(i,"normal")||l.getName(i),O=o.getBoundingRect(D,L,d,"top");u=!!P,f.label={x:n,y:r,position:m,height:O.height,len:y,len2:x,linePoints:c,textAlign:d,verticalAlign:"middle",font:L,rotation:P},M||h.push(f.label)}),!u&&t.get("avoidLabelOverlap")&&r(h,a,s,e,i,n)}},function(t,e,i){var n=i(4),r=n.parsePercent,o=i(107),a=i(1),s=2*Math.PI,l=Math.PI/180;t.exports=function(t,e,i,h){e.eachSeriesByType(t,function(t){var e=t.get("center"),h=t.get("radius");a.isArray(h)||(h=[0,h]),a.isArray(e)||(e=[e,e]);var u=i.getWidth(),c=i.getHeight(),d=Math.min(u,c),f=r(e[0],u),p=r(e[1],c),g=r(h[0],d/2),m=r(h[1],d/2),v=t.getData(),y=-t.get("startAngle")*l,x=t.get("minAngle")*l,_=v.getSum("value"),b=Math.PI/(_||v.count())*2,w=t.get("clockwise"),M=t.get("roseType"),S=t.get("stillShowZeroSum"),T=v.getDataExtent("value");T[0]=0;var A=s,I=0,C=y,k=w?1:-1;if(v.each("value",function(t,e){var i;if(isNaN(t))return void v.setItemLayout(e,{angle:NaN,startAngle:NaN,endAngle:NaN,clockwise:w,cx:f,cy:p,r0:g,r:M?NaN:m});i="area"!==M?0===_&&S?b:t*b:s/(v.count()||1),i=0;r--){var o=i[r];if(o[n])break}if(r<0){var a=t.queryComponents({mainType:"dataZoom",subType:"select",id:n})[0];if(a){var s=a.getPercentRange();i[0][n]={dataZoomId:n,start:s[0],end:s[1]}}}}),i.push(e)},pop:function(t){var e=n(t),i=e[e.length-1];e.length>1&&e.pop();var r={};return o(i,function(t,i){for(var n=e.length-1;n>=0;n--){var t=e[n][i];if(t){r[i]=t;break}}}),r},clear:function(t){t[a]=null},count:function(t){return n(t).length}};t.exports=s},function(t,e,i){i(13).registerSubTypeDefaulter("dataZoom",function(t){return"slider"})},function(t,e,i){function n(t){R.call(this),this._zr=t,this.group=new F.Group,this._brushType,this._brushOption,this._panels,this._track=[],this._dragging,this._covers=[],this._creatingCover,this._creatingPanel,this._enableGlobalPan,this._uid="brushController_"+it++,this._handlers={},Z(nt,function(t,e){this._handlers[e]=B.bind(t,this)},this)}function r(t,e){var i=t._zr;t._enableGlobalPan||G.take(i,K,t._uid),Z(t._handlers,function(t,e){i.on(e,t)}),t._brushType=e.brushType,t._brushOption=B.merge(B.clone(et),e,!0)}function o(t){var e=t._zr;G.release(e,K,t._uid),Z(t._handlers,function(t,i){e.off(i,t)}),t._brushType=t._brushOption=null}function a(t,e){var i=rt[e.brushType].createCover(t,e);return h(i),i.__brushOption=e,t.group.add(i),i}function s(t,e){var i=c(e);return i.endCreating&&(i.endCreating(t,e),h(e)),e}function l(t,e){var i=e.__brushOption;c(e).updateCoverShape(t,e,i.range,i)}function h(t){t.traverse(function(t){t.z=Y,t.z2=Y})}function u(t,e){c(e).updateCommon(t,e),l(t,e)}function c(t){return rt[t.__brushOption.brushType]}function d(t,e,i){var n=t._panels;if(!n)return!0;var r;return Z(n,function(t){t.contain(e,i)&&(r=t)}),r}function f(t,e){var i=t._panels;if(!i)return!0;var n=e.__brushOption.panelId;return null==n||i[n]}function p(t){var e=t._covers,i=e.length;return Z(e,function(e){t.group.remove(e)},t),e.length=0,!!i}function g(t,e){var i=q(t._covers,function(t){var e=t.__brushOption,i=B.clone(e.range);return{brushType:e.brushType,panelId:e.panelId,range:i}});t.trigger("brush",i,{isEnd:!!e.isEnd,removeOnClick:!!e.removeOnClick})}function m(t){var e=t._track;if(!e.length)return!1;var i=e[e.length-1],n=e[0],r=i[0]-n[0],o=i[1]-n[1],a=X(r*r+o*o,.5);return a>$}function v(t){var e=t.length-1;return e<0&&(e=0),[t[0],t[e]]}function y(t,e,i,n){var r=new F.Group;return r.add(new F.Rect({name:"main",style:w(i),silent:!0,draggable:!0,cursor:"move",drift:W(t,e,r,"nswe"),ondragend:W(g,e,{isEnd:!0})})),Z(n,function(i){r.add(new F.Rect({name:i,style:{opacity:0},draggable:!0,silent:!0,invisible:!0,drift:W(t,e,r,i),ondragend:W(g,e,{isEnd:!0})}))}),r}function x(t,e,i,n){var r=n.brushStyle.lineWidth||0,o=U(r,Q),a=i[0][0],s=i[1][0],l=a-r/2,h=s-r/2,u=i[0][1],c=i[1][1],d=u-o+r/2,f=c-o+r/2,p=u-a,g=c-s,m=p+r,v=g+r;b(t,e,"main",a,s,p,g),n.transformable&&(b(t,e,"w",l,h,o,v),b(t,e,"e",d,h,o,v),b(t,e,"n",l,h,m,o),b(t,e,"s",l,f,m,o),b(t,e,"nw",l,h,o,o),b(t,e,"ne",d,h,o,o),b(t,e,"sw",l,f,o,o),b(t,e,"se",d,f,o,o))}function _(t,e){var i=e.__brushOption,n=i.transformable,r=e.childAt(0);r.useStyle(w(i)),r.attr({silent:!n,cursor:n?"move":"default"}),Z(["w","e","n","s","se","sw","ne","nw"],function(i){var r=e.childOfName(i),o=T(t,i);r&&r.attr({silent:!n,invisible:!n,cursor:n?tt[o]+"-resize":null})})}function b(t,e,i,n,r,o,a){var s=e.childOfName(i);s&&s.setShape(L(k(t,e,[[n,r],[n+o,r+a]])))}function w(t){return B.defaults({strokeNoScale:!0},t.brushStyle)}function M(t,e,i,n){var r=[j(t,i),j(e,n)],o=[U(t,i),U(e,n)];return[[r[0],o[0]],[r[1],o[1]]]}function S(t){return F.getTransform(t.group)}function T(t,e){if(e.length>1){e=e.split("");var i=[T(t,e[0]),T(t,e[1])];return("e"===i[0]||"w"===i[0])&&i.reverse(),i.join("")}var n={w:"left",e:"right",n:"top",s:"bottom"},r={left:"w",right:"e",top:"n",bottom:"s"},i=F.transformDirection(n[e],S(t));return r[i]}function A(t,e,i,n,r,o,a,s){var l=n.__brushOption,h=t(l.range),c=C(i,o,a);Z(r.split(""),function(t){var e=J[t];h[e[0]][e[1]]+=c[e[0]]}),l.range=e(M(h[0][0],h[1][0],h[0][1],h[1][1])),u(i,n),g(i,{isEnd:!1})}function I(t,e,i,n,r){var o=e.__brushOption.range,a=C(t,i,n);Z(o,function(t){t[0]+=a[0],t[1]+=a[1]}),u(t,e),g(t,{isEnd:!1})}function C(t,e,i){var n=t.group,r=n.transformCoordToLocal(e,i),o=n.transformCoordToLocal(0,0);return[r[0]-o[0],r[1]-o[1]]}function k(t,e,i){var n=f(t,e);if(n===!0)return B.clone(i);var r=n.getBoundingRect();return B.map(i,function(t){var e=t[0];e=U(e,r.x),e=j(e,r.x+r.width);var i=t[1];return i=U(i,r.y),i=j(i,r.y+r.height),[e,i]})}function L(t){var e=j(t[0][0],t[1][0]),i=j(t[0][1],t[1][1]),n=U(t[0][0],t[1][0]),r=U(t[0][1],t[1][1]);return{x:e,y:i,width:n-e,height:r-i}}function P(t,e){var i=e.offsetX,n=e.offsetY,r=t._zr;if(t._brushType){for(var o,a=t._panels,s=t._covers,l=0;lt[1]&&t.reverse(),t}function r(t,e){for(var i=!0,n=0;n=0){i=!1;for(var o=0;o=0?(i=n.getBoundingRect().clone(),i.applyTransform(s.getTransform(n))):i=n.grid.getRect().clone(),e.push({panelId:t.panelId,rect:i})}),e},h.makeCoordInfoList=function(t,e){var i=[];return l(u,function(n){var r=t[n+"Index"];null!=r&&"none"!==r&&("all"===r||a.isArray(r)||(r=[r]),e.eachComponent({mainType:n},function(t,e){if(!("all"!==r&&a.indexOf(r,e)<0)){var o,s;"xAxis"===n||"yAxis"===n?o=t.axis.grid:s=t.coordinateSystem;for(var l,h=0,u=i.length;h=0;n--)c.isIdInner(e[n])&&e.splice(n,1);t[i]=e}}),delete t[b],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap[t];if(i)return i[e||0]},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,r=t.name,o=this._componentsMap[e];if(!o||!o.length)return[];var a;if(null!=i)m(i)||(i=[i]),a=p(g(i,function(t){ +return o[t]}),function(t){return!!t});else if(null!=n){var s=m(n);a=p(o,function(t){return s&&v(n,t.id)>=0||!s&&t.id===n})}else if(null!=r){var h=m(r);a=p(o,function(t){return h&&v(r,t.name)>=0||!h&&t.name===r})}else a=o;return l(a,t)},findComponents:function(t){function e(t){var e=r+"Index",i=r+"Id",n=r+"Name";return!t||null==t[e]&&null==t[i]&&null==t[n]?null:{mainType:r,index:t[e],id:t[i],name:t[n]}}function i(e){return t.filter?p(e,t.filter):e}var n=t.query,r=t.mainType,o=e(n),a=o?this.queryComponents(o):this._componentsMap[r];return i(l(a,t))},eachComponent:function(t,e,i){var n=this._componentsMap;if("function"==typeof t)i=e,e=t,f(n,function(t,n){f(t,function(t,r){e.call(i,n,t,r)})});else if(u.isString(t))f(n[t],e,i);else if(y(t)){var r=this.findComponents(t);f(r,e,i)}},getSeriesByName:function(t){var e=this._componentsMap.series;return p(e,function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap.series[t]},getSeriesByType:function(t){var e=this._componentsMap.series;return p(e,function(e){return e.subType===t})},getSeries:function(){return this._componentsMap.series.slice()},eachSeries:function(t,e){h(this),f(this._seriesIndices,function(i){var n=this._componentsMap.series[i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){f(this._componentsMap.series,t,e)},eachSeriesByType:function(t,e,i){h(this),f(this._seriesIndices,function(n){var r=this._componentsMap.series[n];r.subType===t&&e.call(i,r,n)},this)},eachRawSeriesByType:function(t,e,i){return f(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return h(this),u.indexOf(this._seriesIndices,t.componentIndex)<0},filterSeries:function(t,e){h(this);var i=p(this._componentsMap.series,t,e);this._seriesIndices=s(i)},restoreData:function(){var t=this._componentsMap;this._seriesIndices=s(t.series);var e=[];f(t,function(t,i){e.push(i)}),x.topologicalTravel(e,x.getAllClassMainTypes(),function(e,i){f(t[e],function(t){t.restoreData()})})}});u.mixin(w,i(57)),t.exports=w},function(t,e,i){function n(t){this._api=t,this._timelineOptions=[],this._mediaList=[],this._mediaDefault,this._currentMediaIndices=[],this._optionBackup,this._newBaseOption}function r(t,e,i){var n,r,o=[],a=[],s=t.timeline;if(t.baseOption&&(r=t.baseOption),(s||t.options)&&(r=r||{},o=(t.options||[]).slice()),t.media){r=r||{};var l=t.media;d(l,function(t){t&&t.option&&(t.query?a.push(t):n||(n=t))})}return r||(r=t),r.timeline||(r.timeline=s),d([r].concat(o).concat(h.map(a,function(t){return t.option})),function(t){d(e,function(e){e(t,i)})}),{baseOption:r,timelineOptions:o,mediaDefault:n,mediaList:a}}function o(t,e,i){var n={width:e,height:i,aspectratio:e/i},r=!0;return h.each(t,function(t,e){var i=e.match(m);if(i&&i[1]&&i[2]){var o=i[1],s=i[2].toLowerCase();a(n[s],t,o)||(r=!1)}}),r}function a(t,e,i){return"min"===i?t>=e:"max"===i?t<=e:t===e}function s(t,e){return t.join(",")===e.join(",")}function l(t,e){e=e||{},d(e,function(e,i){if(null!=e){var n=t[i];if(c.hasClass(i)){e=u.normalizeToArray(e),n=u.normalizeToArray(n);var r=u.mappingToExists(n,e);t[i]=p(r,function(t){return t.option&&t.exist?g(t.exist,t.option,!0):t.exist||t.option})}else t[i]=g(n,e,!0)}})}var h=i(1),u=i(6),c=i(13),d=h.each,f=h.clone,p=h.map,g=h.merge,m=/^(min|max)?(.+)$/;n.prototype={constructor:n,setOption:function(t,e){t=f(t,!0);var i=this._optionBackup,n=r.call(this,t,e,!i);this._newBaseOption=n.baseOption,i?(l(i.baseOption,n.baseOption),n.timelineOptions.length&&(i.timelineOptions=n.timelineOptions),n.mediaList.length&&(i.mediaList=n.mediaList),n.mediaDefault&&(i.mediaDefault=n.mediaDefault)):this._optionBackup=n},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=p(e.timelineOptions,f),this._mediaList=p(e.mediaList,f),this._mediaDefault=f(e.mediaDefault),this._currentMediaIndices=[],f(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i.length){var n=t.getComponent("timeline");n&&(e=f(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(t){var e=this._api.getWidth(),i=this._api.getHeight(),n=this._mediaList,r=this._mediaDefault,a=[],l=[];if(!n.length&&!r)return l;for(var h=0,u=n.length;he&&(e=t[i]);return e},min:function(t){for(var e=1/0,i=0;i1){var c;"string"==typeof r?c=i[r]:"function"==typeof r&&(c=r),c&&(e=e.downSample(s.dim,1/u,c,n),t.setData(e))}}},this)}},function(t,e,i){function n(t,e){return c(t,u(e))}var r=i(1),o=i(32),a=i(4),s=i(38),l=o.prototype,h=s.prototype,u=a.getPrecisionSafe,c=a.round,d=Math.floor,f=Math.ceil,p=Math.pow,g=Math.log,m=o.extend({type:"log",base:10,$constructor:function(){o.apply(this,arguments),this._originalScale=new s},getTicks:function(){var t=this._originalScale,e=this._extent,i=t.getExtent();return r.map(h.getTicks.call(this),function(r){var o=a.round(p(this.base,r));return o=r===e[0]&&t.__fixMin?n(o,i[0]):o,o=r===e[1]&&t.__fixMax?n(o,i[1]):o},this)},getLabel:h.getLabel,scale:function(t){return t=l.scale.call(this,t),p(this.base,t)},setExtent:function(t,e){var i=this.base;t=g(t)/g(i),e=g(e)/g(i),h.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,e=l.getExtent.call(this);e[0]=p(t,e[0]),e[1]=p(t,e[1]);var i=this._originalScale,r=i.getExtent();return i.__fixMin&&(e[0]=n(e[0],r[0])),i.__fixMax&&(e[1]=n(e[1],r[1])),e},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=g(t[0])/g(e),t[1]=g(t[1])/g(e),l.unionExtent.call(this,t)},unionExtentFromData:function(t,e){this.unionExtent(t.getDataExtent(e,!0,function(t){return t>0}))},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(i===1/0||i<=0)){var n=a.quantity(i),r=t/i*n;for(r<=.5&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var o=[a.round(f(e[0]/n)*n),a.round(d(e[1]/n)*n)];this._interval=n,this._niceExtent=o}},niceExtent:function(t,e,i){h.niceExtent.call(this,t,e,i);var n=this._originalScale;n.__fixMin=e,n.__fixMax=i}});r.each(["contain","normalize"],function(t){m.prototype[t]=function(e){return e=g(e)/g(this.base),l[t].call(this,e)}}),m.create=function(){return new m},t.exports=m},function(t,e,i){var n=i(1),r=i(32),o=r.prototype,a=r.extend({type:"ordinal",init:function(t,e){this._data=t,this._extent=e||[0,t.length-1]},parse:function(t){return"string"==typeof t?n.indexOf(this._data,t):Math.round(t)},contain:function(t){return t=this.parse(t),o.contain.call(this,t)&&null!=this._data[t]},normalize:function(t){return o.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(o.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){return this._data[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getDataExtent(e,!1))},niceTicks:n.noop,niceExtent:n.noop});a.create=function(){return new a},t.exports=a},function(t,e,i){var n=i(1),r=i(4),o=i(8),a=i(38),s=a.prototype,l=Math.ceil,h=Math.floor,u=1e3,c=60*u,d=60*c,f=24*d,p=function(t,e,i,n){for(;i>>1;t[r][2]=0;r--)if(!n[r].silent&&n[r]!==i&&!n[r].ignore&&o(n[r],t,e))return n[r]}},a.each(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){u.prototype[t]=function(e){var i=this.findHover(e.zrX,e.zrY,null);if("mousedown"===t)this._downel=i,this._upel=i;else if("mosueup"===t)this._upel=i;else if("click"===t&&this._downel!==this._upel)return;this.dispatchToElement(i,t,e)}}),a.mixin(u,l),a.mixin(u,s),t.exports=u},function(t,e,i){function n(){return!1}function r(t,e,i,n){var r=document.createElement(e),o=i.getWidth(),a=i.getHeight(),s=r.style;return s.position="absolute",s.left=0,s.top=0,s.width=o+"px",s.height=a+"px",r.width=o*n,r.height=a*n,r.setAttribute("data-zr-dom-id",t),r}var o=i(1),a=i(33),s=i(66),l=i(65),h=function(t,e,i){var s;i=i||a.devicePixelRatio,"string"==typeof t?s=r(t,"canvas",e,i):o.isObject(t)&&(s=t,t=s.id),this.id=t,this.dom=s;var l=s.style;l&&(s.onselectstart=n,l["-webkit-user-select"]="none",l["user-select"]="none",l["-webkit-touch-callout"]="none",l["-webkit-tap-highlight-color"]="rgba(0,0,0,0)",l.padding=0,l.margin=0,l["border-width"]=0),this.domBack=null,this.ctxBack=null,this.painter=e,this.config=null,this.clearColor=0,this.motionBlur=!1,this.lastFrameAlpha=.7,this.dpr=i};h.prototype={constructor:h,elCount:0,__dirty:!0,initContext:function(){this.ctx=this.dom.getContext("2d"),this.ctx.dpr=this.dpr},createBackBuffer:function(){var t=this.dpr;this.domBack=r("back-"+this.id,"canvas",this.painter,t),this.ctxBack=this.domBack.getContext("2d"),1!=t&&this.ctxBack.scale(t,t)},resize:function(t,e){var i=this.dpr,n=this.dom,r=n.style,o=this.domBack;r.width=t+"px",r.height=e+"px",n.width=t*i,n.height=e*i,o&&(o.width=t*i,o.height=e*i,1!=i&&this.ctxBack.scale(i,i))},clear:function(t){var e=this.dom,i=this.ctx,n=e.width,r=e.height,o=this.clearColor,a=this.motionBlur&&!t,h=this.lastFrameAlpha,u=this.dpr;if(a&&(this.domBack||this.createBackBuffer(),this.ctxBack.globalCompositeOperation="copy",this.ctxBack.drawImage(e,0,0,n/u,r/u)),i.clearRect(0,0,n,r),o){var c;o.colorStops?(c=o.__canvasGradient||s.getGradient(i,o,{x:0,y:0,width:n,height:r}),o.__canvasGradient=c):o.image&&(c=l.prototype.getCanvasPattern.call(o,i)),i.save(),i.fillStyle=c||o,i.fillRect(0,0,n,r),i.restore()}if(a){var d=this.domBack;i.save(),i.globalAlpha=h,i.drawImage(d,0,0,n,r),i.restore()}}},t.exports=h},function(t,e,i){"use strict";function n(t){return parseInt(t,10)}function r(t){return!!t&&(!!t.isBuildin||"function"==typeof t.resize&&"function"==typeof t.refresh)}function o(t){t.__unusedCount++}function a(t){1==t.__unusedCount&&t.clear()}function s(t,e,i){return x.copy(t.getBoundingRect()),t.transform&&x.applyTransform(t.transform),_.width=e,_.height=i,!x.intersect(_)}function l(t,e){if(t==e)return!1;if(!t||!e||t.length!==e.length)return!0;for(var i=0;i=0&&i.splice(n,1),t.__hoverMir=null},clearHover:function(t){for(var e=this._hoverElements,i=0;i=0){if(!s){if(s=this._progressiveLayers[Math.min(h++,y-1)],s.ctx.save(),s.renderScope={},s&&s.__progress>s.__maxProgress){g=s.__nextIdxNotProg-1;continue}l=s.__progress,s.__dirty||(p=l),s.__progress=p+1}_===p&&this._doPaintEl(v,s,!0,s.renderScope)}else this._doPaintEl(v,n,e,a);v.__dirty=!1}}s&&i(s),o&&o.restore(),this._furtherProgressive=!1,d.each(this._progressiveLayers,function(t){t.__maxProgress>=t.__progress&&(this._furtherProgressive=!0)},this)},_doPaintEl:function(t,e,i,n){var r=e.ctx,o=t.transform;if((e.__dirty||i)&&!t.invisible&&0!==t.style.opacity&&(!o||o[0]||o[3])&&(!t.culling||!s(t,this._width,this._height))){var a=t.__clipPaths;(n.prevClipLayer!==e||l(a,n.prevElClipPaths))&&(n.prevElClipPaths&&(n.prevClipLayer.ctx.restore(),n.prevClipLayer=n.prevElClipPaths=null,n.prevEl=null),a&&(r.save(),h(a,r),n.prevClipLayer=e,n.prevElClipPaths=a)),t.beforeBrush&&t.beforeBrush(r),t.brush(r,n.prevEl||null),n.prevEl=t,t.afterBrush&&t.afterBrush(r)}},getLayer:function(t){if(this._singleCanvas)return this._layers[0];var e=this._layers[t];return e||(e=new m("zr_"+t,this,this.dpr),e.isBuildin=!0,this._layerConfig[t]&&d.merge(e,this._layerConfig[t],!0),this.insertLayer(t,e),e.initContext()),e},insertLayer:function(t,e){var i=this._layers,n=this._zlevelList,o=n.length,a=null,s=-1,l=this._domRoot;if(i[t])return void f("ZLevel "+t+" has been used already");if(!r(e))return void f("Layer of zlevel "+t+" is not valid");if(o>0&&t>n[0]){for(s=0;st);s++);a=i[n[s]]}if(n.splice(s+1,0,t),a){var h=a.dom;h.nextSibling?l.insertBefore(e.dom,h.nextSibling):l.appendChild(e.dom)}else l.firstChild?l.insertBefore(e.dom,l.firstChild):l.appendChild(e.dom);i[t]=e},eachLayer:function(t,e){var i,n,r=this._zlevelList;for(n=0;n=0){a!==g&&(a=g,l++);var v=c.__frame=l-1;if(!o){var x=Math.min(s,y-1);o=i[x],o||(o=i[x]=new m("progressive",this,this.dpr),o.initContext()),o.__maxProgress=0}o.__dirty=o.__dirty||c.__dirty,o.elCount++,o.__maxProgress=Math.max(o.__maxProgress,v),o.__maxProgress>=o.__progress&&(p.__dirty=!0)}else c.__frame=-1,o&&(o.__nextIdxNotProg=h,s++,o=null)}o&&(s++,o.__nextIdxNotProg=h),this.eachBuildinLayer(function(t,e){n[e]!==t.elCount&&(t.__dirty=!0)}),i.length=Math.min(s,y),d.each(i,function(t,e){r[e]!==t.elCount&&(c.__dirty=!0),t.__dirty&&(t.__progress=0)})},clear:function(){return this.eachBuildinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?d.merge(i[t],e,!0):i[t]=e;var n=this._layers[t];n&&d.merge(n,i[t],!0)}},delLayer:function(t){var e=this._layers,i=this._zlevelList,n=e[t];n&&(n.dom.parentNode.removeChild(n.dom),delete e[t],i.splice(d.indexOf(i,t),1))},resize:function(t,e){var i=this._domRoot;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n.height=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!=t||e!=this._height){i.style.width=t+"px",i.style.height=e+"px";for(var r in this._layers)this._layers.hasOwnProperty(r)&&this._layers[r].resize(t,e);d.each(this._progressiveLayers,function(i){i.resize(t,e)}),this.refresh(!0)}return this._width=t,this._height=e,this},clearLayer:function(t){var e=this._layers[t];e&&e.clear()},dispose:function(){this.root.innerHTML="",this.root=this.storage=this._domRoot=this._layers=null},getRenderedCanvas:function(t){if(t=t||{},this._singleCanvas)return this._layers[0].dom;var e=new m("image",this,t.pixelRatio||this.dpr);e.initContext(),e.clearColor=t.backgroundColor,e.clear();for(var i=this.storage.getDisplayList(!0),n={},r=0;r=0&&(this.delFromMap(o.id),this._roots.splice(s,1),o instanceof a&&o.delChildrenFromStorage(this))}},addToMap:function(t){return t instanceof a&&(t.__storage=this),t.dirty(!1),this._elements[t.id]=t,this},get:function(t){return this._elements[t]},delFromMap:function(t){var e=this._elements,i=e[t];return i&&(delete e[t],i instanceof a&&(i.__storage=null)),this},dispose:function(){this._elements=this._renderList=this._roots=null},displayableSortFunc:n},t.exports=l},function(t,e,i){"use strict";var n=i(1),r=i(25).Dispatcher,o=i(62),a=i(61),s=function(t){t=t||{},this.stage=t.stage||{},this.onframe=t.onframe||function(){},this._clips=[],this._running=!1,this._time,this._pausedTime,this._pauseStart,this._paused=!1,r.call(this)};s.prototype={constructor:s,addClip:function(t){this._clips.push(t)},addAnimator:function(t){t.animation=this;for(var e=t.getClips(),i=0;i=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;ii||d+ca&&(a+=r);var p=Math.atan2(u,h);return p<0&&(p+=r),p>=o&&p<=a||p+r>=o&&p+r<=a}}},function(t,e,i){var n=i(18);t.exports={containStroke:function(t,e,i,r,o,a,s,l,h,u,c){if(0===h)return!1;var d=h;if(c>e+d&&c>r+d&&c>a+d&&c>l+d||ct+d&&u>i+d&&u>o+d&&u>s+d||ue&&u>n&&u>a&&u>l||u1&&r(),d=g.cubicAt(e,n,a,l,b[0]),m>1&&(f=g.cubicAt(e,n,a,l,b[1]))),p+=2==m?ye&&s>n&&s>o||s=0&&h<=1){for(var u=0,c=g.quadraticAt(e,n,o,h),d=0;di||s<-i)return 0;var l=Math.sqrt(i*i-s*s);_[0]=-l,_[1]=l;var h=Math.abs(n-r);if(h<1e-4)return 0;if(h%y<1e-4){n=0,r=y;var u=o?1:-1;return a>=_[0]+t&&a<=_[1]+t?u:0}if(o){var l=n;n=p(r),r=p(l)}else n=p(n),r=p(r);n>r&&(r+=y);for(var c=0,d=0;d<2;d++){var f=_[d];if(f+t>a){var g=Math.atan2(s,f),u=o?1:-1;g<0&&(g=y+g),(g>=n&&g<=r||g+y>=n&&g+y<=r)&&(g>Math.PI/2&&g<1.5*Math.PI&&(u=-u),c+=u)}}return c}function l(t,e,i,r,l){for(var u=0,p=0,g=0,y=0,x=0,_=0;_1&&(i||(u+=m(p,g,y,x,r,l))),1==_&&(p=t[_],g=t[_+1],y=p,x=g),b){case h.M:y=t[_++],x=t[_++],p=y,g=x;break;case h.L:if(i){if(v(p,g,t[_],t[_+1],e,r,l))return!0}else u+=m(p,g,t[_],t[_+1],r,l)||0;p=t[_++],g=t[_++];break;case h.C:if(i){if(c.containStroke(p,g,t[_++],t[_++],t[_++],t[_++],t[_],t[_+1],e,r,l))return!0}else u+=o(p,g,t[_++],t[_++],t[_++],t[_++],t[_],t[_+1],r,l)||0;p=t[_++],g=t[_++];break;case h.Q:if(i){if(d.containStroke(p,g,t[_++],t[_++],t[_],t[_+1],e,r,l))return!0}else u+=a(p,g,t[_++],t[_++],t[_],t[_+1],r,l)||0;p=t[_++],g=t[_++];break;case h.A:var w=t[_++],M=t[_++],S=t[_++],T=t[_++],A=t[_++],I=t[_++],C=(t[_++],1-t[_++]),k=Math.cos(A)*S+w,L=Math.sin(A)*T+M;_>1?u+=m(p,g,k,L,r,l):(y=k,x=L);var P=(r-w)*T/S+w;if(i){if(f.containStroke(w,M,T,A,A+I,C,e,P,l))return!0}else u+=s(w,M,T,A,A+I,C,P,l);p=Math.cos(A+I)*S+w,g=Math.sin(A+I)*T+M;break;case h.R:y=p=t[_++],x=g=t[_++];var D=t[_++],O=t[_++],k=y+D,L=x+O;if(i){if(v(y,x,k,x,e,r,l)||v(k,x,k,L,e,r,l)||v(k,L,y,L,e,r,l)||v(y,L,y,x,e,r,l))return!0}else u+=m(k,x,k,L,r,l),u+=m(y,L,y,x,r,l);break;case h.Z:if(i){if(v(p,g,y,x,e,r,l))return!0}else u+=m(p,g,y,x,r,l);p=y,g=x}}return i||n(g,x)||(u+=m(p,g,y,x,r,l)||0),0!==u}var h=i(29).CMD,u=i(88),c=i(148),d=i(89),f=i(147),p=i(63).normalizeRadian,g=i(18),m=i(90),v=u.containStroke,y=2*Math.PI,x=1e-4,_=[-1,-1,-1],b=[-1,-1];t.exports={contain:function(t,e,i){return l(t,0,!1,e,i)},containStroke:function(t,e,i,n){return l(t,e,!0,i,n)}}},function(t,e,i){"use strict";function n(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function r(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}var o=i(25),a=function(){this._track=[]};a.prototype={constructor:a,recognize:function(t,e,i){return this._doTrack(t,e,i),this._recognize(t)},clear:function(){return this._track.length=0,this},_doTrack:function(t,e,i){var n=t.touches;if(n){for(var r={points:[],touches:[],target:e,event:t},a=0,s=n.length;a1&&o&&o.length>1){var s=n(o)/n(a);!isFinite(s)&&(s=1),e.pinchScale=s;var l=r(o);return e.pinchX=l[0],e.pinchY=l[1],{type:"pinch",target:t[0].target,event:e}}}}};t.exports=a},function(t,e){var i=function(){this.head=null,this.tail=null,this._len=0},n=i.prototype;n.insert=function(t){var e=new r(t);return this.insertEntry(e),e},n.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,this.tail=t):this.head=this.tail=t,this._len++},n.remove=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},n.len=function(){return this._len};var r=function(t){this.value=t,this.next,this.prev},o=function(t){this._list=new i,this._map={},this._maxSize=t||10},a=o.prototype;a.put=function(t,e){var i=this._list,n=this._map;if(null==n[t]){var r=i.len();if(r>=this._maxSize&&r>0){var o=i.head;i.remove(o),delete n[o.key]}var a=i.insert(e);a.key=t,n[t]=a}},a.get=function(t){var e=this._map[t],i=this._list;if(null!=e)return e!==i.tail&&(i.remove(e),i.insertEntry(e)),e.value},a.clear=function(){this._list.clear(),this._map={}},t.exports=o},function(t,e,i){function n(t){return"mousewheel"===t&&d.browser.firefox?"DOMMouseScroll":t}function r(t,e,i){var n=t._gestureMgr;"start"===i&&n.clear();var r=n.recognize(e,t.handler.findHover(e.zrX,e.zrY,null),t.dom);if("end"===i&&n.clear(),r){var o=r.type;e.gestureEvent=o,t.handler.dispatchToElement(r.target,o,r.event)}}function o(t){t._touching=!0,clearTimeout(t._touchTimer),t._touchTimer=setTimeout(function(){t._touching=!1},700)}function a(t){var e=t.pointerType;return"pen"===e||"touch"===e}function s(t){function e(t,e){return function(){if(!e._touching)return t.apply(e,arguments)}}u.each(x,function(e){t._handlers[e]=u.bind(w[e],t)}),u.each(b,function(e){t._handlers[e]=u.bind(w[e],t)}),u.each(y,function(i){t._handlers[i]=e(w[i],t)})}function l(t){function e(e,i){u.each(e,function(e){p(t,n(e),i._handlers[e])},i)}c.call(this),this.dom=t,this._touching=!1,this._touchTimer,this._gestureMgr=new f,this._handlers={},s(this),d.pointerEventsSupported?e(b,this):(d.touchEventsSupported&&e(x,this),e(y,this))}var h=i(25),u=i(1),c=i(21),d=i(10),f=i(150),p=h.addEventListener,g=h.removeEventListener,m=h.normalizeEvent,v=300,y=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],x=["touchstart","touchend","touchmove"],_={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},b=u.map(y,function(t){var e=t.replace("mouse","pointer");return _[e]?e:t}),w={mousemove:function(t){t=m(this.dom,t),this.trigger("mousemove",t)},mouseout:function(t){t=m(this.dom,t);var e=t.toElement||t.relatedTarget;if(e!=this.dom)for(;e&&9!=e.nodeType;){if(e===this.dom)return;e=e.parentNode}this.trigger("mouseout",t)},touchstart:function(t){t=m(this.dom,t),t.zrByTouch=!0,this._lastTouchMoment=new Date,r(this,t,"start"),w.mousemove.call(this,t),w.mousedown.call(this,t),o(this)},touchmove:function(t){t=m(this.dom,t),t.zrByTouch=!0,r(this,t,"change"),w.mousemove.call(this,t),o(this)},touchend:function(t){t=m(this.dom,t),t.zrByTouch=!0,r(this,t,"end"),w.mouseup.call(this,t),+new Date-this._lastTouchMomentl&&(c=i+n,i*=l/c,n*=l/c),r+o>l&&(c=r+o,r*=l/c,o*=l/c),n+r>h&&(c=n+r,n*=h/c,r*=h/c),i+o>h&&(c=i+o,i*=h/c,o*=h/c),t.moveTo(a+i,s),t.lineTo(a+l-n,s),0!==n&&t.quadraticCurveTo(a+l,s,a+l,s+n),t.lineTo(a+l,s+h-r),0!==r&&t.quadraticCurveTo(a+l,s+h,a+l-r,s+h),t.lineTo(a+o,s+h),0!==o&&t.quadraticCurveTo(a,s+h,a,s+h-o),t.lineTo(a,s+i),0!==i&&t.quadraticCurveTo(a,s,a+i,s)}}},function(t,e,i){var n=i(5),r=n.min,o=n.max,a=n.scale,s=n.distance,l=n.add;t.exports=function(t,e,i,h){var u,c,d,f,p=[],g=[],m=[],v=[];if(h){d=[1/0,1/0],f=[-(1/0),-(1/0)];for(var y=0,x=t.length;yi-2?i-1:f+1],c=t[f>i-3?i-1:f+2]);var m=p*p,v=p*m;o.push([n(h[0],g[0],u[0],c[0],p,m,v),n(h[1],g[1],u[1],c[1],p,m,v)])}return o}},function(t,e,i){t.exports=i(7).extend({type:"arc",shape:{cx:0,cy:0,r:0,startAngle:0,endAngle:2*Math.PI,clockwise:!0},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.cx,n=e.cy,r=Math.max(e.r,0),o=e.startAngle,a=e.endAngle,s=e.clockwise,l=Math.cos(o),h=Math.sin(o);t.moveTo(l*r+i,h*r+n),t.arc(i,n,r,o,a,!s)}})},function(t,e,i){"use strict";function n(t,e,i){var n=t.cpx2,r=t.cpy2;return null===n||null===r?[(i?c:h)(t.x1,t.cpx1,t.cpx2,t.x2,e),(i?c:h)(t.y1,t.cpy1,t.cpy2,t.y2,e)]:[(i?u:l)(t.x1,t.cpx1,t.x2,e),(i?u:l)(t.y1,t.cpy1,t.y2,e)]}var r=i(18),o=i(5),a=r.quadraticSubdivide,s=r.cubicSubdivide,l=r.quadraticAt,h=r.cubicAt,u=r.quadraticDerivativeAt,c=r.cubicDerivativeAt,d=[];t.exports=i(7).extend({type:"bezier-curve",shape:{x1:0,y1:0,x2:0,y2:0,cpx1:0,cpy1:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.x1,n=e.y1,r=e.x2,o=e.y2,l=e.cpx1,h=e.cpy1,u=e.cpx2,c=e.cpy2,f=e.percent;0!==f&&(t.moveTo(i,n),null==u||null==c?(f<1&&(a(i,l,r,f,d),l=d[1],r=d[2],a(n,h,o,f,d),h=d[1],o=d[2]),t.quadraticCurveTo(l,h,r,o)):(f<1&&(s(i,l,u,r,f,d),l=d[1],u=d[2],r=d[3],s(n,h,c,o,f,d),h=d[1],c=d[2],o=d[3]),t.bezierCurveTo(l,h,u,c,r,o)))},pointAt:function(t){return n(this.shape,t,!1)},tangentAt:function(t){var e=n(this.shape,t,!0);return o.normalize(e,e)}})},function(t,e,i){"use strict";t.exports=i(7).extend({type:"circle",shape:{cx:0,cy:0,r:0},buildPath:function(t,e,i){i&&t.moveTo(e.cx+e.r,e.cy),t.arc(e.cx,e.cy,e.r,0,2*Math.PI,!0)}})},function(t,e,i){t.exports=i(7).extend({type:"line",shape:{x1:0,y1:0,x2:0,y2:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.x1,n=e.y1,r=e.x2,o=e.y2,a=e.percent;0!==a&&(t.moveTo(i,n),a<1&&(r=i*(1-a)+r*a,o=n*(1-a)+o*a),t.lineTo(r,o))},pointAt:function(t){var e=this.shape;return[e.x1*(1-t)+e.x2*t,e.y1*(1-t)+e.y2*t]}})},function(t,e,i){var n=i(67);t.exports=i(7).extend({type:"polygon",shape:{points:null,smooth:!1,smoothConstraint:null},buildPath:function(t,e){n.buildPath(t,e,!0)}})},function(t,e,i){var n=i(67);t.exports=i(7).extend({type:"polyline",shape:{points:null,smooth:!1,smoothConstraint:null},style:{stroke:"#000",fill:null},buildPath:function(t,e){n.buildPath(t,e,!1)}})},function(t,e,i){var n=i(155);t.exports=i(7).extend({type:"rect",shape:{r:0,x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,r=e.y,o=e.width,a=e.height;e.r?n.buildPath(t,e):t.rect(i,r,o,a),t.closePath()}})},function(t,e,i){t.exports=i(7).extend({type:"ring",shape:{cx:0,cy:0,r:0,r0:0},buildPath:function(t,e){var i=e.cx,n=e.cy,r=2*Math.PI;t.moveTo(i+e.r,n),t.arc(i,n,e.r,0,r,!1),t.moveTo(i+e.r0,n),t.arc(i,n,e.r0,0,r,!0)}})},function(t,e,i){var n=i(10),r=i(7),o=[["shadowBlur",0],["shadowColor","#000"],["shadowOffsetX",0],["shadowOffsetY",0]];t.exports=r.extend({type:"sector",shape:{cx:0,cy:0,r0:0,r:0,startAngle:0,endAngle:2*Math.PI,clockwise:!0},brush:n.browser.ie&&n.browser.version>=11?function(){var t,e=this.__clipPaths,i=this.style;if(e)for(var n=0;n0&&this.animate(t,!1).when(null==n?500:n,a).delay(o||0),this}},t.exports=h},function(t,e){function i(){this.on("mousedown",this._dragStart,this),this.on("mousemove",this._drag,this),this.on("mouseup",this._dragEnd,this),this.on("globalout",this._dragEnd,this)}i.prototype={constructor:i,_dragStart:function(t){var e=t.target;e&&e.draggable&&(this._draggingTarget=e,e.dragging=!0,this._x=t.offsetX,this._y=t.offsetY,this.dispatchToElement(e,"dragstart",t.event))},_drag:function(t){var e=this._draggingTarget;if(e){var i=t.offsetX,n=t.offsetY,r=i-this._x,o=n-this._y;this._x=i,this._y=n,e.drift(r,o,t),this.dispatchToElement(e,"drag",t.event);var a=this.findHover(i,n,e),s=this._dropTarget;this._dropTarget=a,e!==a&&(s&&a!==s&&this.dispatchToElement(s,"dragleave",t.event),a&&a!==s&&this.dispatchToElement(a,"dragenter",t.event))}},_dragEnd:function(t){var e=this._draggingTarget;e&&(e.dragging=!1),this.dispatchToElement(e,"dragend",t.event),this._dropTarget&&this.dispatchToElement(this._dropTarget,"drop",t.event),this._draggingTarget=null,this._dropTarget=null}},t.exports=i},function(t,e,i){function n(t,e,i,n,r,o,a,s,l,h,u){var g=l*(p/180),y=f(g)*(t-i)/2+d(g)*(e-n)/2,x=-1*d(g)*(t-i)/2+f(g)*(e-n)/2,_=y*y/(a*a)+x*x/(s*s);_>1&&(a*=c(_),s*=c(_));var b=(r===o?-1:1)*c((a*a*(s*s)-a*a*(x*x)-s*s*(y*y))/(a*a*(x*x)+s*s*(y*y)))||0,w=b*a*x/s,M=b*-s*y/a,S=(t+i)/2+f(g)*w-d(g)*M,T=(e+n)/2+d(g)*w+f(g)*M,A=v([1,0],[(y-w)/a,(x-M)/s]),I=[(y-w)/a,(x-M)/s],C=[(-1*y-w)/a,(-1*x-M)/s],k=v(I,C);m(I,C)<=-1&&(k=p),m(I,C)>=1&&(k=0),0===o&&k>0&&(k-=2*p),1===o&&k<0&&(k+=2*p),u.addData(h,S,T,a,s,A,k,g,o)}function r(t){if(!t)return[];var e,i=t.replace(/-/g," -").replace(/ /g," ").replace(/ /g,",").replace(/,,/g,",");for(e=0;e0&&""===m[0]&&m.shift();for(var v=0;v')}}catch(l){n=function(t){return a.createElement("<"+t+' xmlns="'+r+'" class="zrvml">')}}var h=function(){if(!s){s=!0;var t=a.styleSheets;t.length<31?a.createStyleSheet().addRule(".zrvml","behavior:url(#default#VML)"):t[0].addRule(".zrvml","behavior:url(#default#VML)")}};t.exports={doc:a,initVML:h,createNode:n}}},,,,function(t,e){function i(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function r(t){if(u===setTimeout)return setTimeout(t,0);if((u===i||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function o(t){if(c===clearTimeout)return clearTimeout(t);if((c===n||!c)&&clearTimeout)return c=clearTimeout,clearTimeout(t);try{return c(t)}catch(e){try{return c.call(null,t)}catch(e){return c.call(this,t)}}}function a(){g&&f&&(g=!1,f.length?p=f.concat(p):m=-1,p.length&&s())}function s(){if(!g){var t=r(a);g=!0;for(var e=p.length;e;){for(f=p,p=[];++m1)for(var i=1;i=0;o--){var a=n[o],s=r[o],l=a[0]-s[0]/2,h=a[1]-s[1]/2;if(t>=l&&e>=h&&t<=l+s[0]&&e<=h+s[1])return o}return-1}}),s=n.prototype;s.updateData=function(t){this.group.removeAll();var e=this._symbolEl,i=t.hostModel;e.setShape({points:t.mapArray(t.getItemLayout),sizes:t.mapArray(function(e){var i=t.getItemVisual(e,"symbolSize");return i instanceof Array||(i=[i,i]),i})}),e.symbolProxy=o.createSymbol(t.getVisual("symbol"),0,0,0,0),e.setColor=e.symbolProxy.setColor,e.useStyle(i.getModel("itemStyle.normal").getItemStyle(["color"]));var n=t.getVisual("color");n&&e.setColor(n),e.seriesIndex=i.seriesIndex,e.on("mousemove",function(t){e.dataIndex=null;var i=e.findDataIndex(t.offsetX,t.offsetY);i>0&&(e.dataIndex=i)}),this.group.add(e)},s.updateLayout=function(t){var e=t.getData();this._symbolEl.setShape({points:e.mapArray(e.getItemLayout)})},s.remove=function(){this.group.removeAll()},t.exports=n},function(t,e,i){function n(t){return isNaN(+t.cpx1)||isNaN(+t.cpy1)}var r=i(3),o=i(5),a=r.Line.prototype,s=r.BezierCurve.prototype;t.exports=r.extendShape({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){(n(e)?a:s).buildPath(t,e)},pointAt:function(t){return n(this.shape)?a.pointAt.call(this,t):s.pointAt.call(this,t)},tangentAt:function(t){var e=this.shape,i=n(e)?[e.x2-e.x1,e.y2-e.y1]:s.tangentAt.call(this,t);return o.normalize(i,i)}})},function(t,e,i){var n=i(1),r=i(2);i(179),i(180),r.registerVisual(n.curry(i(45),"scatter","circle",null)),r.registerLayout(n.curry(i(56),"scatter")),i(31)},function(t,e,i){"use strict";var n=i(35),r=i(16);t.exports=r.extend({type:"series.scatter",dependencies:["grid","polar"],getInitialData:function(t,e){var i=n(t.data,this,e);return i},brushSelector:"point",defaultOption:{coordinateSystem:"cartesian2d",zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,symbolSize:10,large:!1,largeThreshold:2e3,itemStyle:{normal:{opacity:.8}}}})},function(t,e,i){var n=i(39),r=i(176);i(2).extendChartView({type:"scatter",init:function(){this._normalSymbolDraw=new n,this._largeSymbolDraw=new r},render:function(t,e,i){var n=t.getData(),r=this._largeSymbolDraw,o=this._normalSymbolDraw,a=this.group,s=t.get("large")&&n.count()>t.get("largeThreshold")?r:o;this._symbolDraw=s,s.updateData(n),a.add(s.group),a.remove(s===r?o.group:r.group)},updateLayout:function(t){this._symbolDraw.updateLayout(t)},remove:function(t,e){this._symbolDraw&&this._symbolDraw.remove(e,!0)},dispose:function(){}})},function(t,e,i){i(114),i(40),i(41),i(187),i(188),i(183),i(184),i(112),i(111)},function(t,e,i){function n(t,e){var i=[1/0,-(1/0)];return h(e,function(e){var n=e.getData();n&&h(e.coordDimToDataDim(t),function(t){var e=n.getDataExtent(t);e[0]i[1]&&(i[1]=e[1])})},this),i[1]0&&(t[0]=0),t[1]<0&&(t[1]=0)),t}function o(t,e){var i=t.getAxisModel(),n=t._percentWindow,r=t._valueWindow;if(n){var o=s.getPixelPrecision(r,[0,500]),a=e||0===n[0]&&100===n[1];i.setRange(a?null:+r[0].toFixed(o),a?null:+r[1].toFixed(o))}}var a=i(1),s=i(4),l=i(68),h=a.each,u=s.asc,c=function(t,e,i,n){this._dimName=t,this._axisIndex=e,this._valueWindow,this._percentWindow,this._dataExtent,this.ecModel=n,this._dataZoomModel=i};c.prototype={constructor:c,hostedBy:function(t){return this._dataZoomModel===t},getDataValueWindow:function(){return this._valueWindow.slice()},getDataPercentWindow:function(){return this._percentWindow.slice()},getTargetSeriesModels:function(){var t=[],e=this.ecModel;return e.eachSeries(function(i){if(l.isCoordSupported(i.get("coordinateSystem"))){var n=this._dimName,r=e.queryComponents({mainType:n+"Axis",index:i.get(n+"AxisIndex"),id:i.get(n+"AxisId")})[0];this._axisIndex===(r&&r.componentIndex)&&t.push(i)}},this),t},getAxisModel:function(){return this.ecModel.getComponent(this._dimName+"Axis",this._axisIndex)},getOtherAxisModel:function(){var t,e,i=this._dimName,n=this.ecModel,r=this.getAxisModel(),o="x"===i||"y"===i;o?(e="gridIndex",t="x"===i?"y":"x"):(e="polarIndex",t="angle"===i?"radius":"angle");var a;return n.eachComponent(t+"Axis",function(t){(t.get(e)||0)===(r.get(e)||0)&&(a=t)}),a},calculateDataWindow:function(t){var e=this._dataExtent,i=this.getAxisModel(),n=i.axis.scale,o=[0,100],a=[t.start,t.end],l=[];return e=e.slice(),r(e,i),h(["startValue","endValue"],function(e){l.push(null!=t[e]?n.parse(t[e]):null)}),h([0,1],function(t){var i=l[t],r=a[t];null!=r||null==i?(null==r&&(r=o[t]),i=n.parse(s.linearMap(r,o,e,!0))):r=s.linearMap(i,e,o,!0),l[t]=i,a[t]=r}),{valueWindow:u(l),percentWindow:u(a)}},reset:function(t){if(t===this._dataZoomModel){this._dataExtent=n(this._dimName,this.getTargetSeriesModels());var e=this.calculateDataWindow(t.option);this._valueWindow=e.valueWindow,this._percentWindow=e.percentWindow,o(this)}},restore:function(t){t===this._dataZoomModel&&(this._valueWindow=this._percentWindow=null,o(this,!0))},filterData:function(t){function e(t){return t>=o[0]&&t<=o[1]}if(t===this._dataZoomModel){var i=this._dimName,n=this.getTargetSeriesModels(),r=t.get("filterMode"),o=this._valueWindow,a=this.getOtherAxisModel();t.get("$fromToolbox")&&a&&"category"===a.get("type")&&(r="empty"),h(n,function(t){var n=t.getData();n&&h(t.coordDimToDataDim(i),function(i){"empty"===r?t.setData(n.map(i,function(t){return e(t)?t:NaN})):n.filterSelf(i,e)})})}}},t.exports=c},function(t,e,i){t.exports=i(40).extend({type:"dataZoom.inside",defaultOption:{disabled:!1,zoomLock:!1}})},function(t,e,i){function n(t){var e=[0,100];return!(t[0]<=e[1])&&(t[0]=e[1]),!(t[1]<=e[1])&&(t[1]=e[1]),!(t[0]>=e[0])&&(t[0]=e[0]),!(t[1]>=e[0])&&(t[1]=e[0]), +t}var r=i(41),o=i(1),a=i(85),s=i(189),l=o.bind,h=r.extend({type:"dataZoom.inside",init:function(t,e){this._range},render:function(t,e,i,n){h.superApply(this,"render",arguments),s.shouldRecordRange(n,t.id)&&(this._range=t.getPercentRange()),o.each(this.getTargetCoordInfo(),function(e,n){var r=o.map(e,function(t){return s.generateCoordId(t.model)});o.each(e,function(e){var o=e.model;s.register(i,{coordId:s.generateCoordId(o),allCoordIds:r,containsPoint:function(t,e){return o.coordinateSystem.containPoint([t,e])},dataZoomId:t.id,throttleRate:t.get("throttle",!0),panGetRange:l(this._onPan,this,e,n),zoomGetRange:l(this._onZoom,this,e,n)})},this)},this)},dispose:function(){s.unregister(this.api,this.dataZoomModel.id),h.superApply(this,"dispose",arguments),this._range=null},_onPan:function(t,e,i,n,r,o,s,l,h){if(this.dataZoomModel.option.disabled)return this._range;var c=this._range.slice(),d=t.axisModels[0];if(d){var f=u[e]([o,s],[l,h],d,i,t),p=f.signal*(c[1]-c[0])*f.pixel/f.pixelLength;return a(p,c,[0,100],"rigid"),this._range=c}},_onZoom:function(t,e,i,r,o,a){var s=this.dataZoomModel.option;if(s.disabled||s.zoomLock)return this._range;var l=this._range.slice(),h=t.axisModels[0];if(h){var c=u[e](null,[o,a],h,i,t),d=(c.pixel-c.pixelStart)/c.pixelLength*(l[1]-l[0])+l[0];return r=Math.max(1/r,0),l[0]=(l[0]-d)*r+d,l[1]=(l[1]-d)*r+d,this._range=n(l)}}}),u={grid:function(t,e,i,n,r){var o=i.axis,a={},s=r.model.coordinateSystem.getRect();return t=t||[0,0],"x"===o.dim?(a.pixel=e[0]-t[0],a.pixelLength=s.width,a.pixelStart=s.x,a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=s.height,a.pixelStart=s.y,a.signal=o.inverse?-1:1),a},polar:function(t,e,i,n,r){var o=i.axis,a={},s=r.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),h=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===i.mainType?(a.pixel=e[0]-t[0],a.pixelLength=l[1]-l[0],a.pixelStart=l[0],a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=h[1]-h[0],a.pixelStart=h[0],a.signal=o.inverse?-1:1),a},singleAxis:function(t,e,i,n,r){var o=i.axis,a=r.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===o.orient?(s.pixel=e[0]-t[0],s.pixelLength=a.width,s.pixelStart=a.x,s.signal=o.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=a.height,s.pixelStart=a.y,s.signal=o.inverse?-1:1),s}};t.exports=h},function(t,e,i){var n=i(40);t.exports=n.extend({type:"dataZoom.select"})},function(t,e,i){t.exports=i(41).extend({type:"dataZoom.select"})},function(t,e,i){var n=i(40),r=n.extend({type:"dataZoom.slider",layoutMode:"box",defaultOption:{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,backgroundColor:"rgba(47,69,84,0)",dataBackground:{lineStyle:{color:"#2f4554",width:.5,opacity:.3},areaStyle:{color:"rgba(47,69,84,0.3)",opacity:.3}},borderColor:"#ddd",fillerColor:"rgba(167,183,204,0.4)",handleIcon:"M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z",handleSize:"100%",handleStyle:{color:"#a7b7cc"},labelPrecision:null,labelFormatter:null,showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:"#333"}}});t.exports=r},function(t,e,i){function n(t){var e={x:"y",y:"x",radius:"angle",angle:"radius"};return e[t]}var r=i(1),o=i(3),a=i(47),s=i(41),l=o.Rect,h=i(4),u=h.linearMap,c=i(12),d=i(85),f=h.asc,p=r.bind,g=r.each,m=7,v=1,y=30,x="horizontal",_="vertical",b=5,w=["line","bar","candlestick","scatter"],M=s.extend({type:"dataZoom.slider",init:function(t,e){this._displayables={},this._orient,this._range,this._handleEnds,this._size,this._handleWidth,this._handleHeight,this._location,this._dragging,this._dataShadowInfo,this.api=e},render:function(t,e,i,n){return M.superApply(this,"render",arguments),a.createOrUpdate(this,"_dispatchZoomAction",this.dataZoomModel.get("throttle"),"fixRate"),this._orient=t.get("orient"),this.dataZoomModel.get("show")===!1?void this.group.removeAll():(n&&"dataZoom"===n.type&&n.from===this.uid||this._buildView(),void this._updateView())},remove:function(){M.superApply(this,"remove",arguments),a.clear(this,"_dispatchZoomAction")},dispose:function(){M.superApply(this,"dispose",arguments),a.clear(this,"_dispatchZoomAction")},_buildView:function(){var t=this.group;t.removeAll(),this._resetLocation(),this._resetInterval();var e=this._displayables.barGroup=new o.Group;this._renderBackground(),this._renderHandle(),this._renderDataShadow(),t.add(e),this._positionGroup()},_resetLocation:function(){var t=this.dataZoomModel,e=this.api,i=this._findCoordRect(),n={width:e.getWidth(),height:e.getHeight()},o=this._orient===x?{right:n.width-i.x-i.width,top:n.height-y-m,width:i.width,height:y}:{right:m,top:i.y,width:y,height:i.height},a=c.getLayoutParams(t.option);r.each(["right","top","width","height"],function(t){"ph"===a[t]&&(a[t]=o[t])});var s=c.getLayoutRect(a,n,t.padding);this._location={x:s.x,y:s.y},this._size=[s.width,s.height],this._orient===_&&this._size.reverse()},_positionGroup:function(){var t=this.group,e=this._location,i=this._orient,n=this.dataZoomModel.getFirstTargetAxisModel(),r=n&&n.get("inverse"),o=this._displayables.barGroup,a=(this._dataShadowInfo||{}).otherAxisInverse;o.attr(i!==x||r?i===x&&r?{scale:a?[-1,1]:[-1,-1]}:i!==_||r?{scale:a?[-1,-1]:[-1,1],rotation:Math.PI/2}:{scale:a?[1,-1]:[1,1],rotation:Math.PI/2}:{scale:a?[1,1]:[1,-1]});var s=t.getBoundingRect([o]);t.attr("position",[e.x-s.x,e.y-s.y])},_getViewExtent:function(){return[0,this._size[0]]},_renderBackground:function(){var t=this.dataZoomModel,e=this._size;this._displayables.barGroup.add(new l({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40}))},_renderDataShadow:function(){var t=this._dataShadowInfo=this._prepareDataShadowInfo();if(t){var e=this._size,i=t.series,n=i.getRawData(),a=i.getShadowDim?i.getShadowDim():t.otherDim;if(null!=a){var s=n.getDataExtent(a),l=.3*(s[1]-s[0]);s=[s[0]-l,s[1]+l];var h,c=[0,e[1]],d=[0,e[0]],f=[[e[0],0],[0,0]],p=[],g=d[1]/(n.count()-1),m=0,v=Math.round(n.count()/e[0]);n.each([a],function(t,e){if(v>0&&e%v)return void(m+=g);var i=null==t||isNaN(t)||""===t,n=i?0:u(t,s,c,!0);i&&!h&&e?(f.push([f[f.length-1][0],0]),p.push([p[p.length-1][0],0])):!i&&h&&(f.push([m,0]),p.push([m,0])),f.push([m,n]),p.push([m,n]),m+=g,h=i});var y=this.dataZoomModel;this._displayables.barGroup.add(new o.Polygon({shape:{points:f},style:r.defaults({fill:y.get("dataBackgroundColor")},y.getModel("dataBackground.areaStyle").getAreaStyle()),silent:!0,z2:-20})),this._displayables.barGroup.add(new o.Polyline({shape:{points:p},style:y.getModel("dataBackground.lineStyle").getLineStyle(),silent:!0,z2:-19}))}}},_prepareDataShadowInfo:function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(e!==!1){var i,o=this.ecModel;return t.eachTargetAxis(function(a,s){var l=t.getAxisProxy(a.name,s).getTargetSeriesModels();r.each(l,function(t){if(!(i||e!==!0&&r.indexOf(w,t.get("type"))<0)){var l,h=o.getComponent(a.axis,s).axis,u=n(a.name),c=t.coordinateSystem;null!=u&&c.getOtherAxis&&(l=c.getOtherAxis(h).inverse),i={thisAxis:h,series:t,thisDim:a.name,otherDim:u,otherAxisInverse:l}}},this)},this),i}},_renderHandle:function(){var t=this._displayables,e=t.handles=[],i=t.handleLabels=[],n=this._displayables.barGroup,r=this._size,a=this.dataZoomModel;n.add(t.filler=new l({draggable:!0,cursor:"move",drift:p(this._onDragMove,this,"all"),ondragstart:p(this._showDataInfo,this,!0),ondragend:p(this._onDragEnd,this),onmouseover:p(this._showDataInfo,this,!0),onmouseout:p(this._showDataInfo,this,!1),style:{fill:a.get("fillerColor"),textPosition:"inside"}})),n.add(new l(o.subPixelOptimizeRect({silent:!0,shape:{x:0,y:0,width:r[0],height:r[1]},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:v,fill:"rgba(0,0,0,0)"}})));var s=a.get("handleIcon");g([0,1],function(t){var r=o.makePath(s,{style:{strokeNoScale:!0},rectHover:!0,cursor:"vertical"===this._orient?"ns-resize":"ew-resize",draggable:!0,drift:p(this._onDragMove,this,t),ondragend:p(this._onDragEnd,this),onmouseover:p(this._showDataInfo,this,!0),onmouseout:p(this._showDataInfo,this,!1)},{x:-.5,y:0,width:1,height:1},"center"),l=r.getBoundingRect();this._handleHeight=h.parsePercent(a.get("handleSize"),this._size[1]),this._handleWidth=l.width/l.height*this._handleHeight,r.setStyle(a.getModel("handleStyle").getItemStyle());var u=a.get("handleColor");null!=u&&(r.style.fill=u),n.add(e[t]=r);var c=a.textStyleModel;this.group.add(i[t]=new o.Text({silent:!0,invisible:!0,style:{x:0,y:0,text:"",textVerticalAlign:"middle",textAlign:"center",fill:c.getTextColor(),textFont:c.getFont()},z2:10}))},this)},_resetInterval:function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[u(t[0],[0,100],e,!0),u(t[1],[0,100],e,!0)]},_updateInterval:function(t,e){var i=this._handleEnds,n=this._getViewExtent();d(e,i,n,"all"===t||this.dataZoomModel.get("zoomLock")?"rigid":"cross",t),this._range=f([u(i[0],n,[0,100],!0),u(i[1],n,[0,100],!0)])},_updateView:function(t){var e=this._displayables,i=this._handleEnds,n=f(i.slice()),r=this._size;g([0,1],function(t){var n=e.handles[t],o=this._handleHeight;n.attr({scale:[o,o],position:[i[t],r[1]/2-o/2]})},this),e.filler.setShape({x:n[0],y:0,width:n[1]-n[0],height:r[1]}),this._updateDataInfo(t)},_updateDataInfo:function(t){function e(t){var e=o.getTransform(n.handles[t].parent,this.group),i=o.transformDirection(0===t?"right":"left",e),l=this._handleWidth/2+b,h=o.applyTransform([d[t]+(0===t?-l:l),this._size[1]/2],e);r[t].setStyle({x:h[0],y:h[1],textVerticalAlign:a===x?"middle":i,textAlign:a===x?i:"center",text:s[t]})}var i=this.dataZoomModel,n=this._displayables,r=n.handleLabels,a=this._orient,s=["",""];if(i.get("showDetail")){var l=i.findRepresentativeAxisProxy();if(l){var h=l.getAxisModel().axis,u=this._range,c=t?l.calculateDataWindow({start:u[0],end:u[1]}).valueWindow:l.getDataValueWindow();s=[this._formatLabel(c[0],h),this._formatLabel(c[1],h)]}}var d=f(this._handleEnds.slice());e.call(this,0),e.call(this,1)},_formatLabel:function(t,e){var i=this.dataZoomModel,n=i.get("labelFormatter"),o=i.get("labelPrecision");null!=o&&"auto"!==o||(o=e.getPixelPrecision());var a=null==t||isNaN(t)?"":"category"===e.type||"time"===e.type?e.scale.getLabel(Math.round(t)):t.toFixed(Math.min(o,20));return r.isFunction(n)?n(t,a):r.isString(n)?n.replace("{value}",a):a},_showDataInfo:function(t){t=this._dragging||t;var e=this._displayables.handleLabels;e[0].attr("invisible",!t),e[1].attr("invisible",!t)},_onDragMove:function(t,e,i){this._dragging=!0;var n=this._applyBarTransform([e,i],!0);this._updateInterval(t,n[0]);var r=this.dataZoomModel.get("realtime");this._updateView(!r),r&&r&&this._dispatchZoomAction()},_onDragEnd:function(){this._dragging=!1,this._showDataInfo(!1),this._dispatchZoomAction()},_dispatchZoomAction:function(){var t=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,start:t[0],end:t[1]})},_applyBarTransform:function(t,e){var i=this._displayables.barGroup.getLocalTransform();return o.applyTransform(t,i,e)},_findCoordRect:function(){var t;if(g(this.getTargetCoordInfo(),function(e){if(!t&&e.length){var i=e[0].model.coordinateSystem;t=i.getRect&&i.getRect()}}),!t){var e=this.api.getWidth(),i=this.api.getHeight();t={x:.2*e,y:.2*i,width:.6*e,height:.6*i}}return t}});t.exports=M},function(t,e,i){function n(t){var e=t.getZr();return e[p]||(e[p]={})}function r(t,e,i){var n=new c(t.getZr());return n.enable(),n.on("pan",f(a,i)),n.on("zoom",f(s,i)),n}function o(t){u.each(t,function(e,i){e.count||(e.controller.dispose(),delete t[i])})}function a(t,e,i,n,r,o,a){l(t,function(s){return s.panGetRange(t.controller,e,i,n,r,o,a)})}function s(t,e,i,n){l(t,function(r){return r.zoomGetRange(t.controller,e,i,n)})}function l(t,e){var i=[];u.each(t.dataZoomInfos,function(t){var n=e(t);n&&i.push({dataZoomId:t.dataZoomId,start:n[0],end:n[1]})}),t.dispatchAction(i)}function h(t,e){t.dispatchAction({type:"dataZoom",batch:e})}var u=i(1),c=i(84),d=i(47),f=u.curry,p="\0_ec_dataZoom_roams",g={register:function(t,e){var i=n(t),a=e.dataZoomId,s=e.coordId;u.each(i,function(t,i){var n=t.dataZoomInfos;n[a]&&u.indexOf(e.allCoordIds,s)<0&&(delete n[a],t.count--)}),o(i);var l=i[s];l||(l=i[s]={coordId:s,dataZoomInfos:{},count:0},l.controller=r(t,e,l),l.dispatchAction=u.curry(h,t)),l.controller.setContainsPoint(e.containsPoint),d.createOrUpdate(l,"dispatchAction",e.throttleRate,"fixRate"),!l.dataZoomInfos[a]&&l.count++,l.dataZoomInfos[a]=e},unregister:function(t,e){var i=n(t);u.each(i,function(t){t.controller.dispose();var i=t.dataZoomInfos;i[e]&&(delete i[e],t.count--)}),o(i)},shouldRecordRange:function(t,e){if(t&&"dataZoom"===t.type&&t.batch)for(var i=0,n=t.batch.length;i=0;d--)null==r[d]?r.splice(d,1):delete r[d].$action},_flatten:function(t,e,i){l.each(t,function(t){if(t){i&&(t.parentOption=i),e.push(t);var n=t.children;"group"===t.type&&n&&this._flatten(n,e,t),delete t.children}},this)},useElOptionsToUpdate:function(){var t=this._elOptionsToUpdate;return this._elOptionsToUpdate=null,t}});s.extendComponentView({type:"graphic",init:function(t,e){this._elMap={},this._lastGraphicModel},render:function(t,e,i){t!==this._lastGraphicModel&&this._clear(),this._lastGraphicModel=t,this._updateElements(t,i),this._relocate(t,i)},_updateElements:function(t,e){var i=t.useElOptionsToUpdate();if(i){var a=this._elMap,s=this.group;l.each(i,function(t){var e=t.$action,i=t.id,h=a[i],u=t.parentId,c=null!=u?a[u]:s;t.hv&&t.hv[1]&&"text"===t.type&&(t.style=l.defaults({textBaseline:"middle"},t.style),t.style.textVerticalAlign=null);var d=o(t);e&&"merge"!==e?"replace"===e?(r(h,a),n(i,c,d,a)):"remove"===e&&r(h,a):h?h.attr(d):n(i,c,d,a),a[i]&&(a[i].__ecGraphicWidth=t.width,a[i].__ecGraphicHeight=t.height)})}},_relocate:function(t,e){for(var i=t.option.elements,n=this.group,r=this._elMap,o=i.length-1;o>=0;o--){var a=i[o],s=r[a.id];if(s){var l=s.parent,h=l===n?{width:e.getWidth(),height:e.getHeight()}:{width:l.__ecGraphicWidth||0,height:l.__ecGraphicHeight||0};c.positionElement(s,a,h,null,{hv:a.hv,boundingMode:a.bounding})}}},_clear:function(){var t=this._elMap;l.each(t,function(e){r(e,t)}),this._elMap={}},dispose:function(){this._clear()}})},function(t,e,i){i(193),i(195),i(194);var n=i(2);n.registerProcessor(i(196))},function(t,e,i){"use strict";var n=i(1),r=i(11),o=i(2).extendComponentModel({type:"legend",dependencies:["series"],layoutMode:{type:"box",ignoreSize:!0},init:function(t,e,i){this.mergeDefaultAndTheme(t,i),t.selected=t.selected||{}},mergeOption:function(t){o.superCall(this,"mergeOption",t)},optionUpdated:function(){this._updateData(this.ecModel);var t=this._data;if(t[0]&&"single"===this.get("selectedMode")){for(var e=!1,i=0;i=0},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:"top",align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",textStyle:{color:"#333"},selectedMode:!0,tooltip:{show:!1}}});t.exports=o},function(t,e,i){function n(t,e){e.dispatchAction({type:"legendToggleSelect",name:t})}function r(t,e,i){var n=i.getZr().storage.getDisplayList()[0];n&&n.useHoverLayer||t.get("legendHoverLink")&&i.dispatchAction({type:"highlight",seriesName:t.name,name:e})}function o(t,e,i){var n=i.getZr().storage.getDisplayList()[0];n&&n.useHoverLayer||t.get("legendHoverLink")&&i.dispatchAction({type:"downplay",seriesName:t.name,name:e})}var a=i(1),s=i(24),l=i(3),h=i(118),u=a.curry;t.exports=i(2).extendComponentView({type:"legend",init:function(){this._symbolTypeStore={}},render:function(t,e,i){var s=this.group;if(s.removeAll(),t.get("show")){var c=t.get("selectedMode"),d=t.get("align");"auto"===d&&(d="right"===t.get("left")&&"vertical"===t.get("orient")?"right":"left");var f={};a.each(t.getData(),function(a){var h=a.get("name");if(""===h||"\n"===h)return void s.add(new l.Group({newline:!0}));var p=e.getSeriesByName(h)[0];if(!f[h])if(p){var g=p.getData(),m=g.getVisual("color");"function"==typeof m&&(m=m(p.getDataParams(0)));var v=g.getVisual("legendSymbol")||"roundRect",y=g.getVisual("symbol"),x=this._createItem(h,a,t,v,y,d,m,c);x.on("click",u(n,h,i)).on("mouseover",u(r,p,null,i)).on("mouseout",u(o,p,null,i)),f[h]=!0}else e.eachRawSeries(function(e){if(!f[h]&&e.legendDataProvider){var s=e.legendDataProvider(),l=s.indexOfName(h);if(l<0)return;var p=s.getItemVisual(l,"color"),g="roundRect",m=this._createItem(h,a,t,g,null,d,p,c);m.on("click",u(n,h,i)).on("mouseover",u(r,e,h,i)).on("mouseout",u(o,e,h,i)),f[h]=!0}},this)},this),h.layout(s,t,i),h.addBackground(s,t)}},_createItem:function(t,e,i,n,r,o,h,u){var c=i.get("itemWidth"),d=i.get("itemHeight"),f=i.get("inactiveColor"),p=i.isSelected(t),g=new l.Group,m=e.getModel("textStyle"),v=e.get("icon"),y=e.getModel("tooltip"),x=y.parentModel;if(n=v||n,g.add(s.createSymbol(n,0,0,c,d,p?h:f)),!v&&r&&(r!==n||"none"==r)){var _=.8*d;"none"===r&&(r="circle"),g.add(s.createSymbol(r,(c-_)/2,(d-_)/2,_,_,p?h:f))}var b="left"===o?c+5:-5,w=o,M=i.get("formatter"),S=t;"string"==typeof M&&M?S=M.replace("{name}",null!=t?t:""):"function"==typeof M&&(S=M(t));var T=new l.Text({style:{text:S,x:b,y:d/2,fill:p?m.getTextColor():f,textFont:m.getFont(),textAlign:w,textVerticalAlign:"middle"}});g.add(T);var A=new l.Rect({shape:g.getBoundingRect(),invisible:!0,tooltip:y.get("show")?a.extend({content:t,formatter:x.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:i.componentIndex,name:t,$vars:["name"]}},y.option):null});return g.add(A),g.eachChild(function(t){t.silent=!0}),A.silent=!u,this.group.add(g),l.setHoverStyle(g),g}})},function(t,e,i){function n(t,e,i){var n,r={},a="toggleSelected"===t;return i.eachComponent("legend",function(i){a&&null!=n?i[n?"select":"unSelect"](e.name):(i[t](e.name),n=i.isSelected(e.name));var s=i.getData();o.each(s,function(t){var e=t.get("name");if("\n"!==e&&""!==e){var n=i.isSelected(e);e in r?r[e]=r[e]&&n:r[e]=n}})}),{name:e.name,selected:r}}var r=i(2),o=i(1);r.registerAction("legendToggleSelect","legendselectchanged",o.curry(n,"toggleSelected")),r.registerAction("legendSelect","legendselected",o.curry(n,"select")),r.registerAction("legendUnSelect","legendunselected",o.curry(n,"unSelect"))},function(t,e){t.exports=function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var i=0;i=0&&"number"==typeof h&&(h=+h.toFixed(m)),p.coord[d]=g.coord[d]=h,n=[p,g,{type:o,valueIndex:n.valueIndex,value:h}]}return n=[c.dataTransform(t,n[0]),c.dataTransform(t,n[1]),l.extend({},n[2])],n[2].type=n[2].type||"",l.merge(n[2],n[0]),l.merge(n[2],n[1]),n};i(71).extend({type:"markLine",updateLayout:function(t,e,i){e.eachSeries(function(t){var e=t.markLineModel;if(e){var n=e.getData(),r=e.__from,o=e.__to;r.each(function(e){a(r,e,!0,t,i),a(o,e,!1,t,i)}),n.each(function(t){n.setItemLayout(t,[r.getItemLayout(t),o.getItemLayout(t)])}),this.markerGroupMap[t.name].updateLayout()}},this)},renderSeries:function(t,e,i,n){function r(e,i,r){var o=e.getItemModel(i);a(e,i,r,t,n),e.setItemVisual(i,{symbolSize:o.get("symbolSize")||x[r?0:1],symbol:o.get("symbol",!0)||y[r?0:1],color:o.get("itemStyle.normal.color")||u.getVisual("color")})}var o=t.coordinateSystem,h=t.name,u=t.getData(),c=this.markerGroupMap,f=c[h];f||(f=c[h]=new d),this.group.add(f.group);var p=s(o,t,e),g=p.from,m=p.to,v=p.line;e.__from=g,e.__to=m,e.setData(v);var y=e.get("symbol"),x=e.get("symbolSize");l.isArray(y)||(y=[y,y]),"number"==typeof x&&(x=[x,x]),p.from.each(function(t){r(g,t,!0),r(m,t,!1)}),v.each(function(t){var e=v.getItemModel(t).get("lineStyle.normal.color");v.setItemVisual(t,{color:e||g.getItemVisual(t,"color")}),v.setItemLayout(t,[g.getItemLayout(t),m.getItemLayout(t)]),v.setItemVisual(t,{fromSymbolSize:g.getItemVisual(t,"symbolSize"),fromSymbol:g.getItemVisual(t,"symbol"),toSymbolSize:m.getItemVisual(t,"symbolSize"),toSymbol:m.getItemVisual(t,"symbol")})}),f.updateData(v),p.line.eachItemGraphicEl(function(t,i){t.traverse(function(t){t.dataModel=e})}),f.__keep=!0,f.group.silent=e.get("silent")||t.get("silent")}})},function(t,e,i){t.exports=i(70).extend({type:"markPoint",defaultOption:{zlevel:0,z:5,symbol:"pin",symbolSize:50,tooltip:{trigger:"item"},label:{normal:{show:!0,position:"inside"},emphasis:{show:!0}},itemStyle:{normal:{borderWidth:2}}}})},function(t,e,i){function n(t,e,i){var n=e.coordinateSystem;t.each(function(r){var o,a=t.getItemModel(r),l=s.parsePercent(a.get("x"),i.getWidth()),h=s.parsePercent(a.get("y"),i.getHeight());if(isNaN(l)||isNaN(h)){if(e.getMarkerPosition)o=e.getMarkerPosition(t.getValues(t.dimensions,r));else if(n){var u=t.get(n.dimensions[0],r),c=t.get(n.dimensions[1],r);o=n.dataToPoint([u,c])}}else o=[l,h];isNaN(l)||(o[0]=l),isNaN(h)||(o[1]=h),t.setItemLayout(r,o)})}function r(t,e,i){var n;n=t?a.map(t&&t.dimensions,function(t){var i=e.getData().getDimensionInfo(e.coordDimToDataDim(t)[0])||{};return i.name=t,i}):[{name:"value",type:"float"}];var r=new l(n,i),o=a.map(i.get("data"),a.curry(h.dataTransform,e));return t&&(o=a.filter(o,a.curry(h.dataFilter,t))),r.initData(o,null,t?h.dimValueGetter:function(t){return t.value}),r}var o=i(39),a=i(1),s=i(4),l=i(14),h=i(72);i(71).extend({type:"markPoint",updateLayout:function(t,e,i){e.eachSeries(function(t){var e=t.markPointModel;e&&(n(e.getData(),t,i),this.markerGroupMap[t.name].updateLayout(e))},this)},renderSeries:function(t,e,i,a){var s=t.coordinateSystem,l=t.name,h=t.getData(),u=this.markerGroupMap,c=u[l];c||(c=u[l]=new o);var d=r(s,t,e);e.setData(d),n(e.getData(),t,a),d.each(function(t){var i=d.getItemModel(t),n=i.getShallow("symbolSize");"function"==typeof n&&(n=n(e.getRawValue(t),e.getDataParams(t))),d.setItemVisual(t,{symbolSize:n,color:i.get("itemStyle.normal.color")||h.getVisual("color"),symbol:i.getShallow("symbol")})}),c.updateData(d),this.group.add(c.group),d.eachItemGraphicEl(function(t){t.traverse(function(t){t.dataModel=e})}),c.__keep=!0,c.group.silent=e.get("silent")||t.get("silent")}})},function(t,e,i){"use strict";var n=i(2),r=i(3),o=i(12);n.extendComponentModel({type:"title",layoutMode:{type:"box",ignoreSize:!0},defaultOption:{zlevel:0,z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bolder",color:"#333"},subtextStyle:{color:"#aaa"}}}),n.extendComponentView({type:"title",render:function(t,e,i){if(this.group.removeAll(),t.get("show")){var n=this.group,a=t.getModel("textStyle"),s=t.getModel("subtextStyle"),l=t.get("textAlign"),h=t.get("textBaseline"),u=new r.Text({ +style:{text:t.get("text"),textFont:a.getFont(),fill:a.getTextColor()},z2:10}),c=u.getBoundingRect(),d=t.get("subtext"),f=new r.Text({style:{text:d,textFont:s.getFont(),fill:s.getTextColor(),y:c.height+t.get("itemGap"),textBaseline:"top"},z2:10}),p=t.get("link"),g=t.get("sublink");u.silent=!p,f.silent=!g,p&&u.on("click",function(){window.open(p,"_"+t.get("target"))}),g&&f.on("click",function(){window.open(g,"_"+t.get("subtarget"))}),n.add(u),d&&n.add(f);var m=n.getBoundingRect(),v=t.getBoxLayoutParams();v.width=m.width,v.height=m.height;var y=o.getLayoutRect(v,{width:i.getWidth(),height:i.getHeight()},t.get("padding"));l||(l=t.get("left")||t.get("right"),"middle"===l&&(l="center"),"right"===l?y.x+=y.width:"center"===l&&(y.x+=y.width/2)),h||(h=t.get("top")||t.get("bottom"),"center"===h&&(h="middle"),"bottom"===h?y.y+=y.height:"middle"===h&&(y.y+=y.height/2),h=h||"top"),n.attr("position",[y.x,y.y]);var x={textAlign:l,textVerticalAlign:h};u.setStyle(x),f.setStyle(x),m=n.getBoundingRect();var _=y.margin,b=t.getItemStyle(["color","opacity"]);b.fill=t.get("backgroundColor");var w=new r.Rect({shape:{x:m.x-_[3],y:m.y-_[0],width:m.width+_[1]+_[3],height:m.height+_[0]+_[2]},style:b,silent:!0});r.subPixelOptimizeRect(w),n.add(w)}}})},function(t,e,i){i(208),i(209),i(214),i(212),i(210),i(211),i(213)},function(t,e,i){var n=i(26),r=i(1),o=i(2).extendComponentModel({type:"toolbox",layoutMode:{type:"box",ignoreSize:!0},mergeDefaultAndTheme:function(t){o.superApply(this,"mergeDefaultAndTheme",arguments),r.each(this.option.feature,function(t,e){var i=n.get(e);i&&r.merge(t,i.defaultOption)})},defaultOption:{show:!0,z:6,zlevel:0,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:"#ccc",borderWidth:0,padding:5,itemSize:15,itemGap:8,showTitle:!0,iconStyle:{normal:{borderColor:"#666",color:"none"},emphasis:{borderColor:"#3E98C5"}}}});t.exports=o},function(t,e,i){(function(e){function n(t){return 0===t.indexOf("my")}var r=i(26),o=i(1),a=i(3),s=i(11),l=i(43),h=i(118),u=i(17);t.exports=i(2).extendComponentView({type:"toolbox",render:function(t,e,i,c){function d(o,a){var l,h=y[o],u=y[a],d=m[h],p=new s(d,t,t.ecModel);if(h&&!u){if(n(h))l={model:p,onclick:p.option.onclick,featureName:h};else{var g=r.get(h);if(!g)return;l=new g(p,e,i)}v[h]=l}else{if(l=v[u],!l)return;l.model=p,l.ecModel=e,l.api=i}return!h&&u?void(l.dispose&&l.dispose(e,i)):!p.get("show")||l.unusable?void(l.remove&&l.remove(e,i)):(f(p,l,h),p.setIconStatus=function(t,e){var i=this.option,n=this.iconPaths;i.iconStatus=i.iconStatus||{},i.iconStatus[t]=e,n[t]&&n[t].trigger(e)},void(l.render&&l.render(p,e,i,c)))}function f(n,r,s){var l=n.getModel("iconStyle"),h=r.getIcons?r.getIcons():n.get("icon"),u=n.get("title")||{};if("string"==typeof h){var c=h,d=u;h={},u={},h[s]=c,u[s]=d}var f=n.iconPaths={};o.each(h,function(s,h){var c=l.getModel("normal").getItemStyle(),d=l.getModel("emphasis").getItemStyle(),m={x:-g/2,y:-g/2,width:g,height:g},v=0===s.indexOf("image://")?(m.image=s.slice(8),new a.Image({style:m})):a.makePath(s.replace("path://",""),{style:c,hoverStyle:d,rectHover:!0},m,"center");a.setHoverStyle(v),t.get("showTitle")&&(v.__title=u[h],v.on("mouseover",function(){var t=l.getModel("emphasis").getItemStyle();v.setStyle({text:u[h],textPosition:t.textPosition||"bottom",textFill:t.fill||t.stroke||"#000",textAlign:t.textAlign||"center"})}).on("mouseout",function(){v.setStyle({textFill:null})})),v.trigger(n.get("iconStatus."+h)||"normal"),p.add(v),v.on("click",o.bind(r.onclick,r,e,i,h)),f[h]=v})}var p=this.group;if(p.removeAll(),t.get("show")){var g=+t.get("itemSize"),m=t.get("feature")||{},v=this._features||(this._features={}),y=[];o.each(m,function(t,e){y.push(e)}),new l(this._featureNames||[],y).add(d).update(d).remove(o.curry(d,null)).execute(),this._featureNames=y,h.layout(p,t,i),h.addBackground(p,t),p.eachChild(function(t){var e=t.__title,n=t.hoverStyle;if(n&&e){var r=u.getBoundingRect(e,n.font),o=t.position[0]+p.position[0],a=t.position[1]+p.position[1]+g,s=!1;a+r.height>i.getHeight()&&(n.textPosition="top",s=!0);var l=s?-5-r.height:g+8;o+r.width/2>i.getWidth()?(n.textPosition=["100%",l],n.textAlign="right"):o-r.width/2<0&&(n.textPosition=[0,l],n.textAlign="left")}})}},updateView:function(t,e,i,n){o.each(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,n)})},updateLayout:function(t,e,i,n){o.each(this._features,function(t){t.updateLayout&&t.updateLayout(t.model,e,i,n)})},remove:function(t,e){o.each(this._features,function(i){i.remove&&i.remove(t,e)}),this.group.removeAll()},dispose:function(t,e){o.each(this._features,function(i){i.dispose&&i.dispose(t,e)})}})}).call(e,i(175))},function(t,e,i){function n(t){var e={},i=[],n=[];return t.eachRawSeries(function(t){var r=t.coordinateSystem;if(!r||"cartesian2d"!==r.type&&"polar"!==r.type)i.push(t);else{var o=r.getBaseAxis();if("category"===o.type){var a=o.dim+"_"+o.index;e[a]||(e[a]={categoryAxis:o,valueAxis:r.getOtherAxis(o),series:[]},n.push({axisDim:o.dim,axisIndex:o.index})),e[a].series.push(t)}else i.push(t)}}),{seriesGroupByCategoryAxis:e,other:i,meta:n}}function r(t){var e=[];return p.each(t,function(t,i){var n=t.categoryAxis,r=t.valueAxis,o=r.dim,a=[" "].concat(p.map(t.series,function(t){return t.name})),s=[n.model.getCategories()];p.each(t.series,function(t){s.push(t.getRawData().mapArray(o,function(t){return t}))});for(var l=[a.join(v)],h=0;h=0)return!0}function h(t){for(var e=t.split(/\n+/g),i=s(e.shift()).split(y),n=[],r=p.map(i,function(t){return{name:t,data:[]}}),o=0;o1?"emphasis":"normal")}function a(t,e,i,n){var o=i._isZoomActive;n&&"takeGlobalCursor"===n.type&&(o="dataZoomSelect"===n.key&&n.dataZoomSelectActive),i._isZoomActive=o,t.setIconStatus("zoom",o?"emphasis":"normal");var a=h.makeCoordInfoList(r(t.option),e),s=a.xAxisHas&&!a.yAxisHas?"lineX":!a.xAxisHas&&a.yAxisHas?"lineY":"rect";i._brushController.setPanels(h.makePanelOpts(a)).enableBrush(!!o&&{brushType:s,brushStyle:{lineWidth:0,fill:"rgba(0,0,0,0.2)"}})}var s=i(1),l=i(115),h=i(116),u=i(113),c=s.each;i(190);var d="\0_ec_\0toolbox-dataZoom_";n.defaultOption={show:!0,icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:{zoom:"区域缩放",back:"区域缩放还原"}};var f=n.prototype;f.render=function(t,e,i,n){this.model=t,this.ecModel=e,this.api=i,a(t,e,this,n),o(t,e)},f.onclick=function(t,e,i){p[i].call(this)},f.remove=function(t,e){this._brushController.unmount()},f.dispose=function(t,e){this._brushController.dispose()};var p={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(u.pop(this.ecModel))}};f._onBrush=function(t,e){function i(t,e,i){var r=n(t,i[t],a);r&&(o[r.id]={dataZoomId:r.id,startValue:e[0],endValue:e[1]})}function n(t,e,i){var n;return i.eachComponent({mainType:"dataZoom",subType:"select"},function(r,o){var a=r.get(t+"Index");null!=a&&i.getComponent(t,a)===e&&(n=r)}),n}if(e.isEnd&&t.length){var o={},a=this.ecModel;this._brushController.updateCovers([]);var s=h.makeCoordInfoList(r(this.model.option),a),l=[];h.parseOutputRanges(t,s,a,l);var c=t[0],d=l[0],f=c.coordRange,p=c.brushType;if(d&&f)if("rect"===p)i("xAxis",f[0],d),i("yAxis",f[1],d);else{var g={lineX:"xAxis",lineY:"yAxis"};i(g[p],f,d)}u.push(a,o),this._dispatchZoomAction(o)}},f._dispatchZoomAction=function(t){var e=[];c(t,function(t,i){e.push(s.clone(t))}),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},i(26).register("dataZoom",n),i(2).registerPreprocessor(function(t){function e(t,e){if(e){var r=t+"Index",o=e[r];null==o||"all"==o||s.isArray(o)||(o=o===!1||"none"===o?[]:[o]),i(t,function(e,i){if(null==o||"all"==o||s.indexOf(o,i)!==-1){var a={type:"select",$fromToolbox:!0,id:d+t+i};a[r]=i,n.push(a)}})}}function i(e,i){var n=t[e];s.isArray(n)||(n=n?[n]:[]),c(n,i)}if(t){var n=t.dataZoom||(t.dataZoom=[]);s.isArray(n)||(t.dataZoom=n=[n]);var r=t.toolbox;if(r&&(s.isArray(r)&&(r=r[0]),r&&r.feature)){var o=r.feature.dataZoom;e("xAxis",o),e("yAxis",o)}}}),t.exports=n},function(t,e,i){"use strict";function n(t){this.model=t}var r=i(1);n.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z",tiled:"M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z"},title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"},option:{},seriesIndex:{}};var o=n.prototype;o.getIcons=function(){var t=this.model,e=t.get("icon"),i={};return r.each(t.get("type"),function(t){e[t]&&(i[t]=e[t])}),i};var a={line:function(t,e,i,n){if("bar"===t)return r.merge({id:e,type:"line",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},n.get("option.line")||{},!0)},bar:function(t,e,i,n){if("line"===t)return r.merge({id:e,type:"bar",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},n.get("option.bar")||{},!0)},stack:function(t,e,i,n){if("line"===t||"bar"===t)return r.merge({id:e,stack:"__ec_magicType_stack__"},n.get("option.stack")||{},!0)},tiled:function(t,e,i,n){if("line"===t||"bar"===t)return r.merge({id:e,stack:""},n.get("option.tiled")||{},!0)}},s=[["line","bar"],["stack","tiled"]];o.onclick=function(t,e,i){var n=this.model,o=n.get("seriesIndex."+i);if(a[i]){var l={series:[]},h=function(e){var o=e.subType,s=e.id,h=a[i](o,s,e,n);h&&(r.defaults(h,e.option),l.series.push(h));var u=e.coordinateSystem;if(u&&"cartesian2d"===u.type&&("line"===i||"bar"===i)){var c=u.getAxesByScale("ordinal")[0];if(c){var d=c.dim,f=d+"Axis",p=t.queryComponents({mainType:f,index:e.get(name+"Index"),id:e.get(name+"Id")})[0],g=p.componentIndex;l[f]=l[f]||[];for(var m=0;m<=g;m++)l[f][g]=l[f][g]||{};l[f][g].boundaryGap="bar"===i}}};r.each(s,function(t){r.indexOf(t,i)>=0&&r.each(t,function(t){n.setIconStatus(t,"normal")})}),n.setIconStatus(i,"emphasis"),t.eachComponent({mainType:"series",query:null==o?null:{seriesIndex:o}},h),e.dispatchAction({type:"changeMagicType",currentType:i,newOption:l})}};var l=i(2);l.registerAction({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),i(26).register("magicType",n),t.exports=n},function(t,e,i){"use strict";function n(t){this.model=t}var r=i(113);n.defaultOption={show:!0,icon:"M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5",title:"还原"};var o=n.prototype;o.onclick=function(t,e,i){r.clear(t),e.dispatchAction({type:"restore",from:this.uid})},i(26).register("restore",n),i(2).registerAction({type:"restore",event:"restore",update:"prepareAndUpdate"},function(t,e){e.resetOption("recreate")}),t.exports=n},function(t,e,i){function n(t){this.model=t}var r=i(10);n.defaultOption={show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:"保存为图片",type:"png",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:["右键另存为图片"]},n.prototype.unusable=!r.canvasSupported;var o=n.prototype;o.onclick=function(t,e){var i=this.model,n=i.get("name")||t.get("title.0.text")||"echarts",o=document.createElement("a"),a=i.get("type",!0)||"png";o.download=n+"."+a,o.target="_blank";var s=e.getConnectedDataURL({type:a,backgroundColor:i.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",excludeComponents:i.get("excludeComponents"),pixelRatio:i.get("pixelRatio")});if(o.href=s,"function"!=typeof MouseEvent||r.browser.ie||r.browser.edge){var l=i.get("lang"),h='',u=window.open();u.document.write(h)}else{var c=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1});o.dispatchEvent(c)}},i(26).register("saveAsImage",n),t.exports=n},function(t,e,i){i(217),i(218),i(2).registerAction({type:"showTip",event:"showTip",update:"tooltip:manuallyShowTip"},function(){}),i(2).registerAction({type:"hideTip",event:"hideTip",update:"tooltip:manuallyHideTip"},function(){})},function(t,e,i){function n(t){var e="cubic-bezier(0.23, 1, 0.32, 1)",i="left "+t+"s "+e+",top "+t+"s "+e;return s.map(p,function(t){return t+"transition:"+i}).join(";")}function r(t){var e=[],i=t.get("fontSize"),n=t.getTextColor();return n&&e.push("color:"+n),e.push("font:"+t.getFont()),i&&e.push("line-height:"+Math.round(3*i/2)+"px"),c(["decoration","align"],function(i){var n=t.get(i);n&&e.push("text-"+i+":"+n)}),e.join(";")}function o(t){t=t;var e=[],i=t.get("transitionDuration"),o=t.get("backgroundColor"),a=t.getModel("textStyle"),s=t.get("padding");return i&&e.push(n(i)),o&&(f.canvasSupported?e.push("background-Color:"+o):(e.push("background-Color:#"+l.toHex(o)),e.push("filter:alpha(opacity=70)"))),c(["width","color","radius"],function(i){var n="border-"+i,r=d(n),o=t.get(r);null!=o&&e.push(n+":"+o+("color"===i?"":"px"))}),e.push(r(a)),null!=s&&e.push("padding:"+u.normalizeCssArray(s).join("px ")+"px"),e.join(";")+";"}function a(t,e){var i=document.createElement("div"),n=e.getZr();this.el=i,this._x=e.getWidth()/2,this._y=e.getHeight()/2,t.appendChild(i),this._container=t,this._show=!1,this._hideTimeout;var r=this;i.onmouseenter=function(){r.enterable&&(clearTimeout(r._hideTimeout),r._show=!0),r._inContent=!0},i.onmousemove=function(e){if(e=e||window.event,!r.enterable){var i=n.handler;h.normalizeEvent(t,e,!0),i.dispatch("mousemove",e)}},i.onmouseleave=function(){r.enterable&&r._show&&r.hideLater(r._hideDelay),r._inContent=!1}}var s=i(1),l=i(19),h=i(25),u=i(8),c=s.each,d=u.toCamelCase,f=i(10),p=["","-webkit-","-moz-","-o-"],g="position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;";a.prototype={constructor:a,enterable:!0,update:function(){var t=this._container,e=t.currentStyle||document.defaultView.getComputedStyle(t),i=t.style;"absolute"!==i.position&&"absolute"!==e.position&&(i.position="relative")},show:function(t){clearTimeout(this._hideTimeout);var e=this.el;e.style.cssText=g+o(t)+";left:"+this._x+"px;top:"+this._y+"px;"+(t.get("extraCssText")||""),e.style.display=e.innerHTML?"block":"none",this._show=!0},setContent:function(t){var e=this.el;e.innerHTML=t,e.style.display=t?"block":"none"},moveTo:function(t,e){var i=this.el.style;i.left=t+"px",i.top=e+"px",this._x=t,this._y=e},hide:function(){this.el.style.display="none",this._show=!1},hideLater:function(t){!this._show||this._inContent&&this.enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(s.bind(this.hide,this),t)):this.hide())},isShow:function(){return this._show}},t.exports=a},function(t,e,i){i(2).extendComponentModel({type:"tooltip",defaultOption:{zlevel:0,z:8,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove",alwaysShowContent:!1,confine:!1,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"rgba(50,50,50,0.7)",borderColor:"#333",borderRadius:4,borderWidth:0,padding:5,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:!0,animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",lineStyle:{color:"#555",width:1,type:"solid"},crossStyle:{color:"#555",width:1,type:"dashed",textStyle:{}},shadowStyle:{color:"rgba(150,150,150,0.3)"}},textStyle:{color:"#fff",fontSize:14}}})},function(t,e,i){function n(t,e){if(!t||!e)return!1;var i=m.round;return i(t[0])===i(e[0])&&i(t[1])===i(e[1])}function r(t,e,i,n){return{x1:t,y1:e,x2:i,y2:n}}function o(t,e,i,n){return{x:t,y:e,width:i,height:n}}function a(t,e,i,n,r,o){return{cx:t,cy:e,r0:i,r:n,startAngle:r,endAngle:o,clockwise:!0}}function s(t,e,i,n,r){var o=i.clientWidth,a=i.clientHeight,s=20;return t+o+s>n?t-=o+s:t+=s,e+a+s>r?e-=a+s:e+=s,[t,e]}function l(t,e,i,n,r){var o=i.clientWidth,a=i.clientHeight;return t=Math.min(t+o,n)-o,e=Math.min(e+a,r)-a,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function h(t,e,i){var n=i.clientWidth,r=i.clientHeight,o=5,a=0,s=0,l=e.width,h=e.height;switch(t){case"inside":a=e.x+l/2-n/2,s=e.y+h/2-r/2;break;case"top":a=e.x+l/2-n/2,s=e.y-r-o;break;case"bottom":a=e.x+l/2-n/2,s=e.y+h+o;break;case"left":a=e.x-n-o,s=e.y+h/2-r/2;break;case"right":a=e.x+l+o,s=e.y+h/2-r/2}return[a,s]}function u(t,e,i,n,r,o,a,u){var c=u.getWidth(),d=u.getHeight(),f=a&&a.getBoundingRect().clone();if(a&&f.applyTransform(a.transform),"function"==typeof t&&(t=t([e,i],o,r.el,f)),p.isArray(t))e=y(t[0],c),i=y(t[1],d);else if("string"==typeof t&&a){var g=h(t,f,r.el);e=g[0],i=g[1]}else{var g=s(e,i,r.el,c,d);e=g[0],i=g[1]}if(n){var g=l(e,i,r.el,c,d);e=g[0],i=g[1]}r.moveTo(e,i)}function c(t){var e=t.coordinateSystem,i=t.get("tooltip.trigger",!0);return!(!e||"cartesian2d"!==e.type&&"polar"!==e.type&&"singleAxis"!==e.type||"item"===i)}var d=i(216),f=i(3),p=i(1),g=i(8),m=i(4),v=i(6),y=m.parsePercent,x=i(10),_=i(11);i(2).extendComponentView({type:"tooltip",_axisPointers:{},init:function(t,e){if(!x.node){var i=new d(e.getDom(),e);this._tooltipContent=i}},render:function(t,e,i){if(!x.node){this.group.removeAll(),this._axisPointers={},this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastHover={};var n=this._tooltipContent;n.update(),n.enterable=t.get("enterable"),this._alwaysShowContent=t.get("alwaysShowContent"),this._seriesGroupByAxis=this._prepareAxisTriggerData(t,e);var r=this._crossText;r&&this.group.add(r);var o=t.get("triggerOn");if(null!=this._lastX&&null!=this._lastY&&"none"!==o){var a=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){a.manuallyShowTip(t,e,i,{x:a._lastX,y:a._lastY})})}var s=this._api.getZr();s.off("click",this._tryShow),s.off("mousemove",this._mousemove),s.off("mouseout",this._hide),s.off("globalout",this._hide),"click"===o?s.on("click",this._tryShow,this):"mousemove"===o&&(s.on("mousemove",this._mousemove,this),s.on("mouseout",this._hide,this),s.on("globalout",this._hide,this))}},_mousemove:function(t){var e=this._tooltipModel.get("showDelay"),i=this;clearTimeout(this._showTimeout),e>0?this._showTimeout=setTimeout(function(){i._tryShow(t)},e):this._tryShow(t)},manuallyShowTip:function(t,e,i,n){function r(t){var e=t.getData(),i=v.queryDataIndex(e,n);if(null!=i&&!p.isArray(i)&&e.hasValue(i))return!0}if(n.from!==this.uid){var e=this._ecModel,o=n.seriesIndex,a=e.getSeriesByIndex(o),i=this._api,s="axis"===this._tooltipModel.get("trigger");if(null==n.x||null==n.y){if(s?(a&&!r(a)&&(a=null),a||e.eachSeries(function(t){c(t)&&!a&&r(t)&&(a=t)})):a=a||e.getSeriesByIndex(0),a){var l=a.getData(),h=v.queryDataIndex(l,n);if(null==h||p.isArray(h))return;var u,d,f=l.getItemGraphicEl(h),g=a.coordinateSystem;if(a.getTooltipPosition){var m=a.getTooltipPosition(h)||[];u=m[0],d=m[1]}else if(g&&g.dataToPoint){var m=g.dataToPoint(l.getValues(p.map(g.dimensions,function(t){return a.coordDimToDataDim(t)[0]}),h,!0));u=m&&m[0],d=m&&m[1]}else if(f){var y=f.getBoundingRect().clone();y.applyTransform(f.transform),u=y.x+y.width/2,d=y.y+y.height/2}null!=u&&null!=d&&this._tryShow({offsetX:u,offsetY:d,position:n.position,target:f,event:{}})}}else{var f=i.getZr().handler.findHover(n.x,n.y);this._tryShow({offsetX:n.x,offsetY:n.y,position:n.position,target:f,event:{}})}}},manuallyHideTip:function(t,e,i,n){n.from!==this.uid&&this._hide()},_prepareAxisTriggerData:function(t,e){var i={};return e.eachSeries(function(t){if(c(t)){var e,n,r=t.coordinateSystem;"cartesian2d"===r.type?(e=r.getBaseAxis(),n=e.dim+e.index):"singleAxis"===r.type?(e=r.getAxis(),n=e.dim+e.type):(e=r.getBaseAxis(),n=e.dim+r.name),i[n]=i[n]||{coordSys:[],series:[]},i[n].coordSys.push(r),i[n].series.push(t)}},this),i},_tryShow:function(t){var e=t.target,i=this._tooltipModel,n=i.get("trigger"),r=this._ecModel,o=this._api;if(i)if(this._lastX=t.offsetX,this._lastY=t.offsetY,e&&null!=e.dataIndex){var a=e.dataModel||r.getSeriesByIndex(e.seriesIndex),s=e.dataIndex,l=a.getData(),h=l.getItemModel(s);"axis"===(h.get("tooltip.trigger")||n)?this._showAxisTooltip(i,r,t):(this._ticket="",this._hideAxisPointer(),this._resetLastHover(),this._showItemTooltipContent(a,s,e.dataType,t)),o.dispatchAction({type:"showTip",from:this.uid,dataIndexInside:s,dataIndex:l.getRawIndex(s),seriesIndex:e.seriesIndex})}else if(e&&e.tooltip){var u=e.tooltip;if("string"==typeof u){var c=u;u={content:c,formatter:c}}var d=new _(u,i),f=d.get("content"),p=Math.random();this._showTooltipContent(d,f,d.get("formatterParams")||{},p,t.offsetX,t.offsetY,t.position,e,o)}else"item"===n?this._hide():this._showAxisTooltip(i,r,t),"cross"===i.get("axisPointer.type")&&o.dispatchAction({type:"showTip",from:this.uid,x:t.offsetX,y:t.offsetY})},_showAxisTooltip:function(t,e,i){var r=t.getModel("axisPointer"),o=r.get("type");if("cross"===o){var a=i.target;if(a&&null!=a.dataIndex){var s=e.getSeriesByIndex(a.seriesIndex),l=a.dataIndex;this._showItemTooltipContent(s,l,a.dataType,i)}}this._showAxisPointer();var h=!0;p.each(this._seriesGroupByAxis,function(e){var a=e.coordSys,s=a[0],l=[i.offsetX,i.offsetY];if(!s.containPoint(l))return void this._hideAxisPointer(s.name);h=!1;var u=s.dimensions,c=s.pointToData(l,!0);l=s.dataToPoint(c);var d=s.getBaseAxis(),f=r.get("axis");if("auto"===f&&(f=d.dim),d.isBlank()||p.eqNaN(l[0])||p.eqNaN(l[1]))return void this._hideAxisPointer(s.name);var g=!1,m=this._lastHover;if("cross"===o)n(m.data,c)&&(g=!0),m.data=c;else{var v=p.indexOf(u,f);m.data===c[v]&&(g=!0),m.data=c[v]}var y=t.get("animation");"cartesian2d"!==s.type||g?"polar"!==s.type||g?"singleAxis"!==s.type||g||this._showSinglePointer(r,s,f,l,y):this._showPolarPointer(r,s,f,l,y):this._showCartesianPointer(r,s,f,l,y),"cross"!==o&&this._dispatchAndShowSeriesTooltipContent(s,e.series,l,c,g,i.position)},this),this._tooltipModel.get("show")||this._hideAxisPointer(),h&&this._hide()},_showCartesianPointer:function(t,e,i,n,a){function s(i,n,o){var a="x"===i?r(n[0],o[0],n[0],o[1]):r(o[0],n[1],o[1],n[1]),s=h._getPointerElement(e,t,i,a);f.subPixelOptimizeLine({shape:a,style:s.style}),d?f.updateProps(s,{shape:a},t):s.attr({shape:a})}function l(i,n,r){var a=e.getAxis(i),s=a.getBandWidth(),l=r[1]-r[0],u="x"===i?o(n[0]-s/2,r[0],s,l):o(r[0],n[1]-s/2,l,s),c=h._getPointerElement(e,t,i,u);d?f.updateProps(c,{shape:u},t):c.attr({shape:u})}var h=this,u=t.get("type"),c=e.getBaseAxis(),d=a&&"cross"!==u&&"category"===c.type&&c.getBandWidth()>20;if("cross"===u)s("x",n,e.getAxis("y").getGlobalExtent()),s("y",n,e.getAxis("x").getGlobalExtent()),this._updateCrossText(e,n,t);else{var p=e.getAxis("x"===i?"y":"x"),g=p.getGlobalExtent();"cartesian2d"===e.type&&("line"===u?s:l)(i,n,g)}},_showSinglePointer:function(t,e,i,n,o){function a(i,n,o){var a=e.getAxis(),l=a.orient,u="horizontal"===l?r(n[0],o[0],n[0],o[1]):r(o[0],n[1],o[1],n[1]),c=s._getPointerElement(e,t,i,u);h?f.updateProps(c,{shape:u},t):c.attr({shape:u})}var s=this,l=t.get("type"),h=o&&"cross"!==l&&"category"===e.getBaseAxis().type,u=e.getRect(),c=[u.y,u.y+u.height];a(i,n,c)},_showPolarPointer:function(t,e,i,n,o){function s(i,n,o){var a,s=e.pointToCoord(n);if("angle"===i){var l=e.coordToPoint([o[0],s[1]]),u=e.coordToPoint([o[1],s[1]]);a=r(l[0],l[1],u[0],u[1])}else a={cx:e.cx,cy:e.cy,r:s[0]};var c=h._getPointerElement(e,t,i,a);p?f.updateProps(c,{shape:a},t):c.attr({shape:a})}function l(i,n,r){var o,s=e.getAxis(i),l=s.getBandWidth(),u=e.pointToCoord(n),c=Math.PI/180;o="angle"===i?a(e.cx,e.cy,r[0],r[1],(-u[1]-l/2)*c,(-u[1]+l/2)*c):a(e.cx,e.cy,u[0]-l/2,u[0]+l/2,0,2*Math.PI);var d=h._getPointerElement(e,t,i,o);p?f.updateProps(d,{shape:o},t):d.attr({shape:o})}var h=this,u=t.get("type"),c=e.getAngleAxis(),d=e.getRadiusAxis(),p=o&&"cross"!==u&&"category"===e.getBaseAxis().type;if("cross"===u)s("angle",n,d.getExtent()),s("radius",n,c.getExtent()),this._updateCrossText(e,n,t);else{var g=e.getAxis("radius"===i?"angle":"radius"),m=g.getExtent();("line"===u?s:l)(i,n,m)}},_updateCrossText:function(t,e,i){var n=i.getModel("crossStyle"),r=n.getModel("textStyle"),o=this._tooltipModel,a=this._crossText;a||(a=this._crossText=new f.Text({style:{textAlign:"left",textVerticalAlign:"bottom"}}),this.group.add(a));var s=t.pointToData(e),l=t.dimensions;s=p.map(s,function(e,i){var n=t.getAxis(l[i]);return e="category"===n.type||"time"===n.type?n.scale.getLabel(e):g.addCommas(e.toFixed(n.getPixelPrecision()))}),a.setStyle({fill:r.getTextColor()||n.get("color"),textFont:r.getFont(),text:s.join(", "),x:e[0]+5,y:e[1]-5}),a.z=o.get("z"),a.zlevel=o.get("zlevel")},_getPointerElement:function(t,e,i,n){var r=this._tooltipModel,o=r.get("z"),a=r.get("zlevel"),s=this._axisPointers,l=t.name;if(s[l]=s[l]||{},s[l][i])return s[l][i];var h=e.get("type"),u=e.getModel(h+"Style"),c="shadow"===h,d=u[c?"getAreaStyle":"getLineStyle"](),p="polar"===t.type?c?"Sector":"radius"===i?"Circle":"Line":c?"Rect":"Line";c?d.stroke=null:d.fill=null;var g=s[l][i]=new f[p]({style:d,z:o,zlevel:a,silent:!0,shape:n});return this.group.add(g),g},_dispatchAndShowSeriesTooltipContent:function(t,e,i,n,r,o){var a=this._tooltipModel,s=t.getBaseAxis(),l={x:1,radius:1,single:1}[s.dim]?0:1;if(e.length){var h,c=p.map(e,function(t){return{seriesIndex:t.seriesIndex,dataIndexInside:t.getAxisTooltipDataIndex?t.getAxisTooltipDataIndex(t.coordDimToDataDim(s.dim),n,s):t.getData().indexOfNearest(t.coordDimToDataDim(s.dim)[0],n[l],!1,"category"===s.type?.5:null)}});p.each(c,function(t,i){e[i].getData().hasValue(t.dataIndexInside)&&(h=i)}),h=h||0;var d=this._lastHover,f=this._api;d.payloadBatch&&!r&&f.dispatchAction({type:"downplay",batch:d.payloadBatch}),r||(f.dispatchAction({type:"highlight",batch:c}),d.payloadBatch=c);var m=c[h].dataIndexInside;if(f.dispatchAction({type:"showTip",dataIndexInside:m,dataIndex:e[h].getData().getRawIndex(m),seriesIndex:c[h].seriesIndex,from:this.uid}),s&&a.get("showContent")&&a.get("show")){var v=p.map(e,function(t,e){return t.getDataParams(c[e].dataIndexInside)});if(r)u(o||a.get("position"),i[0],i[1],a.get("confine"),this._tooltipContent,v,null,f);else{var y=c[h].dataIndexInside,x="time"===s.type?s.scale.getLabel(n[l]):e[h].getData().getName(y),_=(x?g.encodeHTML(x)+"
    ":"")+p.map(e,function(t,e){return t.formatTooltip(c[e].dataIndexInside,!0)}).join("
    "),b="axis_"+t.name+"_"+y;this._showTooltipContent(a,_,v,b,i[0],i[1],o,null,f)}}}},_showItemTooltipContent:function(t,e,i,n){var r=this._api,o=t.getData(i),a=o.getItemModel(e),s=a.get("tooltip",!0);if("string"==typeof s){var l=s;s={formatter:l}}var h=this._tooltipModel,u=t.getModel("tooltip",h),c=new _(s,u,u.ecModel),d=t.getDataParams(e,i),f=t.formatTooltip(e,!1,i),p="item_"+t.name+"_"+e; +this._showTooltipContent(c,f,d,p,n.offsetX,n.offsetY,n.position,n.target,r)},_showTooltipContent:function(t,e,i,n,r,o,a,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var h=this._tooltipContent,c=t.get("confine"),d=t.get("formatter");a=a||t.get("position");var f=e;if(d)if("string"==typeof d)f=g.formatTpl(d,i,!0);else if("function"==typeof d){var p=this,m=n,v=function(t,e){t===p._ticket&&(h.setContent(e),u(a,r,o,c,h,i,s,l))};p._ticket=m,f=d(i,m,v)}h.show(t),h.setContent(f),u(a,r,o,c,h,i,s,l)}},_showAxisPointer:function(t){if(t){var e=this._axisPointers[t];e&&p.each(e,function(t){t.show()})}else this.group.eachChild(function(t){t.show()}),this.group.show()},_resetLastHover:function(){var t=this._lastHover;t.payloadBatch&&this._api.dispatchAction({type:"downplay",batch:t.payloadBatch}),this._lastHover={}},_hideAxisPointer:function(t){if(t){var e=this._axisPointers[t];e&&p.each(e,function(t){t.hide()})}else this.group.children().length&&this.group.hide()},_hide:function(){clearTimeout(this._showTimeout),this._hideAxisPointer(),this._resetLastHover(),this._alwaysShowContent||this._tooltipContent.hideLater(this._tooltipModel.get("hideDelay")),this._api.dispatchAction({type:"hideTip",from:this.uid}),this._lastX=this._lastY=null},dispose:function(t,e){if(!x.node){var i=e.getZr();this._tooltipContent.hide(),i.off("click",this._tryShow),i.off("mousemove",this._mousemove),i.off("mouseout",this._hide),i.off("globalout",this._hide)}}})},,function(t,e,i){function n(t){return parseInt(t,10)}function r(t,e){s.initVML(),this.root=t,this.storage=e;var i=document.createElement("div"),n=document.createElement("div");i.style.cssText="display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;",n.style.cssText="position:absolute;left:0;top:0;",t.appendChild(i),this._vmlRoot=n,this._vmlViewport=i,this.resize();var r=e.delFromMap,o=e.addToMap;e.delFromMap=function(t){var i=e.get(t);r.call(e,t),i&&i.onRemove&&i.onRemove(n)},e.addToMap=function(t){t.onAdd&&t.onAdd(n),o.call(e,t)},this._firstPaint=!0}function o(t){return function(){a('In IE8.0 VML mode painter not support method "'+t+'"')}}var a=i(48),s=i(171);r.prototype={constructor:r,getViewportRoot:function(){return this._vmlViewport},refresh:function(){var t=this.storage.getDisplayList(!0,!0);this._paintList(t)},_paintList:function(t){for(var e=this._vmlRoot,i=0;i=0?parseFloat(t)/100*e:parseFloat(t):t},E=function(t,e,i){var n=a.parse(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=L(n[0],n[1],n[2]),t.opacity=i*n[3])},N=function(t){var e=a.parse(t);return[L(e[0],e[1],e[2]),e[3]]},R=function(t,e,i){var n=e.fill;if(null!=n)if(n instanceof f){var r,o=0,a=[0,0],s=0,l=1,h=i.getBoundingRect(),u=h.width,c=h.height;if("linear"===n.type){r="gradient";var d=i.transform,p=[n.x*u,n.y*c],g=[n.x2*u,n.y2*c];d&&(b(p,p,d),b(g,g,d));var m=g[0]-p[0],v=g[1]-p[1];o=180*Math.atan2(m,v)/Math.PI,o<0&&(o+=360),o<1e-6&&(o=0)}else{r="gradientradial";var p=[n.x*u,n.y*c],d=i.transform,y=i.scale,x=u,w=c;a=[(p[0]-h.x)/x,(p[1]-h.y)/w],d&&b(p,p,d),x/=y[0]*S,w/=y[1]*S;var M=_(x,w);s=0/M,l=2*n.r/M-s}var T=n.colorStops.slice();T.sort(function(t,e){return t.offset-e.offset});for(var A=T.length,I=[],C=[],k=0;k=2){var D=I[0][0],O=I[1][0],z=I[0][1]*e.opacity,R=I[1][1]*e.opacity;t.type=r,t.method="none",t.focus="100%",t.angle=o,t.color=D,t.color2=O,t.colors=C.join(","),t.opacity=R,t.opacity2=z}"radial"===r&&(t.focusposition=a.join(","))}else E(t,n,e.opacity)},B=function(t,e){null!=e.lineDash&&(t.dashstyle=e.lineDash.join(" ")),null==e.stroke||e.stroke instanceof f||E(t,e.stroke,e.opacity)},V=function(t,e,i,n){var r="fill"==e,o=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(r||!r&&i.lineWidth)?(t[r?"filled":"stroked"]="true",i[e]instanceof f&&D(t,o),o||(o=p.createNode(e)),r?R(o,i,n):B(o,i),P(t,o)):(t[r?"filled":"stroked"]="false",D(t,o))},F=[[],[],[]],G=function(t,e){var i,n,r,a,s,l,h=o.M,u=o.C,c=o.L,d=o.A,f=o.Q,p=[];for(a=0;a.01?G&&(H+=270/S):Math.abs(W-E)<1e-4?G&&Hz?A-=270/S:A+=270/S:G&&WE?M+=270/S:M-=270/S),p.push(Z,g(((z-N)*P+k)*S-T),w,g(((E-R)*D+L)*S-T),w,g(((z+N)*P+k)*S-T),w,g(((E+R)*D+L)*S-T),w,g((H*P+k)*S-T),w,g((W*D+L)*S-T),w,g((M*P+k)*S-T),w,g((A*D+L)*S-T)),s=M,l=A;break;case o.R:var q=F[0],j=F[1];q[0]=t[a++],q[1]=t[a++],j[0]=q[0]+t[a++],j[1]=q[1]+t[a++],e&&(b(q,q,e),b(j,j,e)),q[0]=g(q[0]*S-T),j[0]=g(j[0]*S-T),q[1]=g(q[1]*S-T),j[1]=g(j[1]*S-T),p.push(" m ",q[0],w,q[1]," l ",j[0],w,q[1]," l ",j[0],w,j[1]," l ",q[0],w,j[1]);break;case o.Z:p.push(" x ")}if(i>0){p.push(n);for(var U=0;UU&&(j=0,q={});var i,n=X.style;try{n.font=t,i=n.fontFamily.split(",")[0]}catch(r){}e={style:n.fontStyle||Z,variant:n.fontVariant||Z,weight:n.fontWeight||Z,size:0|parseFloat(n.fontSize||12),family:i||"Microsoft YaHei"},q[t]=e,j++}return e};s.measureText=function(t,e){var i=p.doc;W||(W=i.createElement("div"),W.style.cssText="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;",p.doc.body.appendChild(W));try{W.style.font=e}catch(n){}return W.innerHTML="",W.appendChild(i.createTextNode(t)),{width:W.offsetWidth}};for(var $=new r,Q=function(t,e,i,n){var r=this.style,o=r.text;if(null!=o&&(o+=""),o){var a,l,h=r.textAlign,u=Y(r.textFont),c=u.style+" "+u.variant+" "+u.weight+" "+u.size+'px "'+u.family+'"',d=r.textBaseline,f=r.textVerticalAlign;i=i||s.getBoundingRect(o,c,h,d);var m=this.transform;if(m&&!n&&($.copy(e),$.applyTransform(m),e=$),n)a=e.x,l=e.y;else{var v=r.textPosition,y=r.textDistance;if(v instanceof Array)a=e.x+z(v[0],e.width),l=e.y+z(v[1],e.height),h=h||"left",d=d||"top";else{var x=s.adjustTextPositionOnRect(v,e,i,y);a=x.x,l=x.y,h=h||x.textAlign,d=d||x.textBaseline}}if(f){switch(f){case"middle":l-=i.height/2;break;case"bottom":l-=i.height}d="top"}var _=u.size;switch(d){case"hanging":case"top":l+=_/1.75;break;case"middle":break;default:l-=_/2.25}switch(h){case"left":break;case"center":a-=i.width/2;break;case"right":a-=i.width}var M,S,T,A=p.createNode,I=this._textVmlEl;I?(T=I.firstChild,M=T.nextSibling,S=M.nextSibling):(I=A("line"),M=A("path"),S=A("textpath"),T=A("skew"),S.style["v-text-align"]="left",C(I),M.textpathok=!0,S.on=!0,I.from="0 0",I.to="1000 0.05",P(I,T),P(I,M),P(I,S),this._textVmlEl=I);var L=[a,l],D=I.style;m&&n?(b(L,L,m),T.on=!0,T.matrix=m[0].toFixed(3)+w+m[2].toFixed(3)+w+m[1].toFixed(3)+w+m[3].toFixed(3)+",0,0",T.offset=(g(L[0])||0)+","+(g(L[1])||0),T.origin="0 0",D.left="0px",D.top="0px"):(T.on=!1,D.left=g(a)+"px",D.top=g(l)+"px"),S.string=k(o);try{S.style.font=c}catch(E){}V(I,"fill",{fill:n?r.fill:r.textFill,opacity:r.opacity},this),V(I,"stroke",{stroke:n?r.stroke:r.textStroke,opacity:r.opacity,lineDash:r.lineDash},this),I.style.zIndex=O(this.zlevel,this.z,this.z2),P(t,I)}},K=function(t){D(t,this._textVmlEl),this._textVmlEl=null},J=function(t){P(t,this._textVmlEl)},tt=[l,h,u,d,c],et=0;etli{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/FontAwesome.otf b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/FontAwesome.otf similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/FontAwesome.otf rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/FontAwesome.otf diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.eot b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.eot similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.eot rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.eot diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.svg b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.svg similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.svg rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.svg diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.ttf b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.ttf similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.ttf rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.ttf diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.woff b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.woff rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.woff2 b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff2 similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/fonts/fontawesome-webfont.woff2 rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/fonts/fontawesome-webfont.woff2 diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/animated.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/animated.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/animated.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/animated.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/bordered-pulled.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/bordered-pulled.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/bordered-pulled.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/bordered-pulled.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/core.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/core.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/core.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/core.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/fixed-width.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/fixed-width.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/fixed-width.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/fixed-width.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/font-awesome.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/font-awesome.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/font-awesome.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/font-awesome.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/icons.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/icons.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/icons.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/icons.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/larger.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/larger.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/larger.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/larger.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/list.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/list.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/list.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/list.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/mixins.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/mixins.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/mixins.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/mixins.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/path.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/path.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/path.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/path.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/rotated-flipped.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/rotated-flipped.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/rotated-flipped.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/rotated-flipped.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/stacked.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/stacked.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/stacked.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/stacked.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/variables.less b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/variables.less similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/less/variables.less rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/less/variables.less diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_animated.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_animated.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_animated.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_animated.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_bordered-pulled.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_bordered-pulled.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_bordered-pulled.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_bordered-pulled.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_core.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_core.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_core.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_core.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_fixed-width.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_fixed-width.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_fixed-width.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_fixed-width.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_icons.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_icons.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_icons.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_icons.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_larger.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_larger.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_larger.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_larger.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_list.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_list.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_list.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_list.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_mixins.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_mixins.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_mixins.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_mixins.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_path.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_path.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_path.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_path.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_rotated-flipped.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_rotated-flipped.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_rotated-flipped.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_rotated-flipped.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_stacked.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_stacked.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_stacked.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_stacked.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_variables.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_variables.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/_variables.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/_variables.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/font-awesome.scss b/apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/font-awesome.scss similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/fontAwesome/scss/font-awesome.scss rename to apiroute/apiroute-service/src/main/resources/iui-route/js/fontAwesome/scss/font-awesome.scss diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.contentWindow.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.contentWindow.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.contentWindow.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.contentWindow.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/iframeResizer/iframeResizer.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js similarity index 98% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js index 5288bf3..7491439 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.js @@ -1,20 +1,10 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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 +/*! + * jQuery Validation Plugin v1.13.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. + * http://jqueryvalidation.org/ * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn + * Copyright (c) 2014 Jörn Zaefferer + * Released under the MIT license */ (function( factory ) { if ( typeof define === "function" && define.amd ) { diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/additional-methods.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/jquery.validate.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js index 09715fe..e609dbb 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.js @@ -1,4 +1,3 @@ - (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ar.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js similarity index 71% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js index e631723..fea21cf 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_bg.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js similarity index 66% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js index 347cfba..0b308e1 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ca.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js index 2fd84c6..6c27e2b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_cs.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js similarity index 58% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js index 387ff01..e862aba 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_da.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js similarity index 63% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js index 9379fa9..7f5bc8f 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_de.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js similarity index 74% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js index aa72674..5758f56 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_el.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js similarity index 68% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js index 715b484..bf37c17 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js similarity index 69% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js index fcee4fd..c7279e4 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_es_AR.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js index 5e51364..0dd93cd 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_et.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js index 24578b2..a9b0777 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_eu.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js similarity index 71% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js index 0fb97a3..eb7d336 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fa.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js similarity index 66% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js index e49c4f9..1486128 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fi.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js similarity index 81% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js index 0f35785..d465538 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_fr.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js similarity index 69% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js index d3e6bd6..a36f609 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_gl.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js index 27a4742..b50beb0 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_he.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js similarity index 63% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js index 7e8f665..792ac44 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hr.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js similarity index 62% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js index d71dbdf..735bc3b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_hu.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js index d2f0391..48f7b9a 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_id.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js similarity index 61% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js index fc1ce55..00948d4 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_is.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js index 8194d9d..7fbee3b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_it.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js similarity index 68% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js index 281de3c..3eed43d 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ja.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js similarity index 77% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js index 8d61fb9..494ec91 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ka.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js similarity index 73% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js index 8ec07ab..17c8b83 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_kk.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js index 23efa22..f6b5355 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ko.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js similarity index 66% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js index 051a44c..df17a1e 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lt.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js index f7d0e8a..ade1b88 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_lv.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js index 4f18499..9de974a 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_my.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js similarity index 71% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js index 8232517..cdba381 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_nl.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js similarity index 62% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js index a9700b2..308b715 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_no.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js index 841a1cf..453ba77 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pl.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js similarity index 71% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js index b4594ec..71b1ef8 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_BR.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js similarity index 71% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js index 25b2398..4c2a782 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_pt_PT.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js index bde95ad..be77eab 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ro.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js similarity index 74% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js index 747c2a6..896827b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_ru.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js similarity index 64% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js index ac37c75..8e04a9d 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_si.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js similarity index 59% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js index 5ab253a..cf3680e 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sk.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js similarity index 65% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js index c5a3c69..6eb9e0b 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sl.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js similarity index 69% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js index c360e43..e268be8 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js similarity index 63% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js index edfe3ce..3c14afc 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sr_lat.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js similarity index 62% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js index cddf20d..758c8a7 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_sv.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js similarity index 74% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js index 73e3f9e..e354e50 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_th.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js similarity index 73% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js index db2a3dd..67e1e2c 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tj.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js similarity index 67% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js index b873bc3..1d4c55e 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_tr.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js similarity index 73% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js index 678fe80..ecb855c 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_uk.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js similarity index 61% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js index 2c62ad0..f37b00e 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_vi.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js similarity index 61% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js index 45f7b25..a4e121c 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js similarity index 62% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js index 35b37d6..fc86be3 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.js @@ -1,21 +1,3 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "../jquery.validate"], factory ); diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/messages_zh_TW.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.js new file mode 100644 index 0000000..470133e --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.js @@ -0,0 +1,22 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: DE + */ +$.extend($.validator.methods, { + date: function(value, element) { + return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value); + }, + number: function(value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value); + } +}); + +})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_de.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.js new file mode 100644 index 0000000..16446e4 --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.js @@ -0,0 +1,22 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: ES_CL + */ +$.extend($.validator.methods, { + date: function(value, element) { + return this.optional(element) || /^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(value); + }, + number: function(value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value); + } +}); + +})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_es_CL.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.js new file mode 100644 index 0000000..44b3e36 --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.js @@ -0,0 +1,22 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: FI + */ +$.extend($.validator.methods, { + date: function(value, element) { + return this.optional(element) || /^\d{1,2}\.\d{1,2}\.\d{4}$/.test(value); + }, + number: function(value, element) { + return this.optional(element) || /^-?(?:\d+)(?:,\d+)?$/.test(value); + } +}); + +})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_fi.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.js new file mode 100644 index 0000000..91e0d8c --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.js @@ -0,0 +1,19 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: NL + */ +$.extend($.validator.methods, { + date: function(value, element) { + return this.optional(element) || /^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test(value); + } +}); + +})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_nl.min.js diff --git a/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.js new file mode 100644 index 0000000..d06ccec --- /dev/null +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.js @@ -0,0 +1,19 @@ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery", "../jquery.validate"], factory ); + } else { + factory( jQuery ); + } +}(function( $ ) { + +/* + * Localized default methods for the jQuery validation plugin. + * Locale: PT_BR + */ +$.extend($.validator.methods, { + date: function(value, element) { + return this.optional(element) || /^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(value); + } +}); + +})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery-validation/localization/methods_pt.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js similarity index 99% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js index 00482d7..5f9b195 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery.i18n/jquery.i18n.properties-1.0.9.js @@ -1,4 +1,3 @@ - /****************************************************************************** * jquery.i18n.properties * diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/jquery/jquery-1.10.2.min.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/jquery/jquery-1.10.2.min.js similarity index 100% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-metrics/js/jquery/jquery-1.10.2.min.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/jquery/jquery-1.10.2.min.js diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js similarity index 70% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js index 193ce45..4424865 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeController.js @@ -1,1826 +1,1945 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ -var table; -var vm = avalon - .define({ - $id : "routeController", - targetServiceUrl:"", - targetFullServiceUrl:"", - iuiRootPath:iuiRootPath, - apiRootPath:apiRootPath, - apiIframeUrl:"", - iuiIframeUrl:"", - boxVisible:true, - routeTargetTitle:$.i18n.prop("org_openo_msb_route_content_title"), - server_rtn:{ - info_block:false, - warning_block:false, - rtn_info:"" - }, - showAPIType:"0", - showAPITypeName:[$.i18n.prop("org_openo_msb_route_swagger_type_predefined"),$.i18n.prop("org_openo_msb_route_swagger_type_custominput")], - $msbProtocol :["REST","UI","HTTP","MQ","FTP","SNMP","TCP","UDP"], - $msbType:["UI","NAF","SAF"], - apiJson:{ - local:"", - custom:"" - }, - setAPIType:function(type){ - vm.apiRouteInfo.apiJsonType=type; - if(type==0){ - vm.apiJson.local=vm.jsonApiSelectList.selectItems[0]; - } - - }, - jsonApiSelectList: { - condName : "type", - component_type : 'select', - selectItems : [] - }, - - dataTableLanguage: { - "sProcessing": "  Loadding...", - "sLengthMenu": $.i18n.prop("org_openo_msb_route-table-sLengthMenu"), - "sZeroRecords": $.i18n.prop("org_openo_msb_route-table-sZeroRecords"), - "sInfo": " " + $.i18n.prop("org_openo_msb_route-table-sInfo"), - "sInfoEmpty": $.i18n.prop("org_openo_msb_route-table-sInfoEmpty"), - "sGroupActions": $.i18n.prop("org_openo_msb_route-table-sGroupActions"), - "sAjaxRequestGeneralError": $.i18n.prop("org_openo_msb_route-table-sAjaxRequestGeneralError"), - "sEmptyTable": $.i18n.prop("org_openo_msb_route-table-sEmptyTable"), - "oPaginate": { - "sPrevious": $.i18n.prop("org_openo_msb_route-table-sPrevious"), - "sNext": $.i18n.prop("org_openo_msb_route-table-sNext"), - "sPage": $.i18n.prop("org_openo_msb_route-table-sPage"), - "sPageOf": $.i18n.prop("org_openo_msb_route-table-sPageOf") - }, - "sSearch": $.i18n.prop("org_openo_msb_route-table-search"), - "sInfoFiltered": $.i18n.prop("org_openo_msb_route-table-infofilter") - }, - $apiRouteUrl :apiBasePath+'/apiRoute', - $apiRouteInstanceUrl :apiBasePath+'/apiRoute/{serviceName}/version/{version}', - $apiRouteStatusUrl :apiBasePath+'/apiRoute/{serviceName}/version/{version}/status/{status}', - $apiDocsUrl :apiBasePath+'/apiRoute/apiDocs', - $apiGatewayPortUrl :apiBasePath+'/apiRoute/apiGatewayPort', - $discoverInfoUrl :apiBasePath+'/apiRoute/discoverInfo', - $iuiRouteUrl :apiBasePath+'/iuiRoute', - $iuiRouteInstanceUrl :apiBasePath+'/iuiRoute/{serviceName}', - $iuiRouteStatusUrl :apiBasePath+'/iuiRoute/{serviceName}/status/{status}', - $customRouteUrl :apiBasePath+'/customRoute/all', - $customRouteInstanceUrl :apiBasePath+'/customRoute/instance', - $customRouteStatusUrl :apiBasePath+'/customRoute/status', - $msbRouteUrl:apiBasePath+'/services', - $msbRouteInstanceUrl :apiBasePath+'/services/{serviceName}/version/{version}', - routeLoading:false, - apiRouteArray : [], - apiRouteInfo : { - oldServiceName:"", - serviceName : "", - oldVersion:"", - version : "", - status:"", - url:"", - metricsUrl:"/admin/metrics", - apiJson:"/swagger.json", - apiJsonType:"1", - control:"", - server:"", - servers: [] - }, - iuiRouteArray : [], - iuiRouteInfo : { - oldServiceName:"", - serviceName : "", - status:"", - url:"", - server:"", - control:"", - servers: [] - }, - customRouteArray : [], - customGroupRouteArray : [], - customRouteInfo : { - oldServiceName:"", - serviceName : "", - status:"", - url:"", - server:"", - control:"", - servers: [] - }, - msbRouteArray : [], - msbRouteInfo : { - oldServiceName:"", - oldVersion:"", - serviceName : "", - version:"", - status:"0", - nodes:[], - newHost:"", - newttl:0, - url:"", - protocol:"", - visualRange:"", - visualRangeArray:[] - }, - discoverInfo:{ - ip:"", - port:"", - enabled:false, - deployMode:"" - }, - selectedRoute:"", - selectedRouteType:"", - routeDlgInfo:{ - titleName:"", - saveType:"" - }, - $initRoute : function() { - - - - vm.routeLoading=true; - - $.ajax({ - "type": 'get', - async: false, - "url": vm.$discoverInfoUrl, - "dataType": "json", - success: function (resp) { - - vm.discoverInfo = (resp==null)?"":resp; - - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get discoverInfo fails:"+textStatus+":"+errorThrown); - } - }); - - $.ajax({ - "type": 'get', - "url": vm.$apiRouteUrl, - "dataType": "json", - success: function (resp) { - vm.apiRouteArray = (resp==null)?[]:resp; - vm.apiRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get api services fails:"+textStatus+":"+errorThrown); - return; - }, - complete:function(){ - vm.routeLoading=false; - routeUtil.refreshRoute(); - $.ajax({ - "type": 'get', - "url": vm.$apiGatewayPortUrl, - "dataType": "text", - success: function (resp) { - - vm.targetServiceUrl=location.hostname+":"+resp; - - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get apiGateway published port fails:"+textStatus+":"+errorThrown); - } - }); - } - }); - - - - $.ajax({ - "type": 'get', - "url": vm.$iuiRouteUrl, - "dataType": "json", - success: function (resp) { - vm.iuiRouteArray = (resp==null)?[]:resp; - vm.iuiRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get iui services fails:"+textStatus+":"+errorThrown); - return; - }, - complete:function(){ - routeUtil.refreshRoute(); - } - }); - - - - $.ajax({ - "type": 'get', - "url": vm.$customRouteUrl, - "dataType": "json", - success: function (resp) { - vm.customRouteArray = (resp==null)?[]:resp; - - if(resp!=null && resp.length>0) - { - routeUtil.groupRoute(resp); - } - - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get custom services fails:"+textStatus+":"+errorThrown); - return; - }, - complete:function(){ - routeUtil.refreshRoute(); - } - }); - - - $.ajax({ - "type": 'get', - "url": vm.$apiDocsUrl, - "dataType": "json", - success: function (resp) { - vm.jsonApiSelectList.selectItems= (resp==null)?[]:resp; - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get local apiDocs fails:"+textStatus+":"+errorThrown); - } - }); - - - - vm.initMSBRoute(); - - - - - }, - initMSBRoute:function(){ - vm.initIUIfori18n(); - - $.ajax({ - "type": 'get', - "url": vm.$msbRouteUrl, - "dataType": "json", - success: function (resp) { - vm.msbRouteArray = (resp==null)?[]:resp; - - vm.msbRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); - - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - bootbox.alert("get msb services fails:"+XMLHttpRequest.responseText); - return; - }, - complete:function(){ - - table=$('#msbTable').DataTable({ - - "oLanguage": vm.dataTableLanguage, - columnDefs: [ { - targets: [ 0,8 ], - "searchable": false, - "bSortable": false, - }], - "order": [[2, 'asc']] - }); - - } - }); - - - }, - - clickDisplayGraphAlink: function () { - vm.boxVisible = !vm.boxVisible; - }, - addmsbHost:function(){ - if(vm.msbRouteInfo.newHost==""){ - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop("org_openo_msb_route_err_host_empty"); - return; - } - - if(vm.msbRouteInfo.newttl==""){ - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop("org_openo_msb_route_err_ttl_empty"); - return; - } - - var reg=/^(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})$/ - var ip,port; - if(!reg.test(vm.msbRouteInfo.newHost)){ - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop("org_openo_msb_route_err_host_format"); - return; - } - else{ - - var hosts=vm.msbRouteInfo.newHost.split(":"); - ip=hosts[0]; - port=hosts[1]; - } - - var reg_ttl=/^\d+$/ - - if(!reg_ttl.test(vm.msbRouteInfo.newttl)){ - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop("org_openo_msb_route_err_ttl_format"); - return; - } - - - - // determine whether host repeated - for(var i=0;ib.serviceName?1:-1}); - - routeUtil.refreshRoute(); - $('#iuirouteDlg').modal('hide'); - routeUtil.growl($.i18n.prop('org_openo_msb_route_tab_iui'),$.i18n.prop('org_openo_msb_route_service_save'),"success"); - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop('org_openo_msb_route_err_service_save')+textStatus+":"+errorThrown; - - } - }); - } - else{ //update - - var url= vm.$iuiRouteInstanceUrl; - url=url.replace("{serviceName}",vm.iuiRouteInfo.oldServiceName); - - //Determine whether to repeat - if(vm.iuiRouteInfo.serviceName!=vm.iuiRouteInfo.oldServiceName) //Has been modified service name - { - for(var i=0;ib.serviceName?1:-1}); - - routeUtil.refreshRoute(); - $('#routeDlg').modal('hide'); - routeUtil.growl($.i18n.prop('org_openo_msb_route_tab_api'),$.i18n.prop('org_openo_msb_route_service_save'),"success"); - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - - vm.server_rtn.warning_block=true; - vm.server_rtn.info_block=false; - vm.server_rtn.rtn_info= $.i18n.prop('org_openo_msb_route_err_service_save')+textStatus+":"+errorThrown; - - } - }); - } - else{ //update - - - //Determine whether to repeat - if(vm.apiRouteInfo.serviceName!=vm.apiRouteInfo.oldServiceName || - vm.apiRouteInfo.version!=vm.apiRouteInfo.oldVersion) //Has been modified service name - { - for(var i=0;i  Loadding...", - "sLengthMenu": $.i18n.prop("org_openo_msb_route-table-sLengthMenu"), - "sZeroRecords": $.i18n.prop("org_openo_msb_route-table-sZeroRecords"), - "sInfo": " " + $.i18n.prop("org_openo_msb_route-table-sInfo"), - "sInfoEmpty": $.i18n.prop("org_openo_msb_route-table-sInfoEmpty"), - "sGroupActions": $.i18n.prop("org_openo_msb_route-table-sGroupActions"), - "sAjaxRequestGeneralError": $.i18n.prop("org_openo_msb_route-table-sAjaxRequestGeneralError"), - "sEmptyTable": $.i18n.prop("org_openo_msb_route-table-sEmptyTable"), - "oPaginate": { - "sPrevious": $.i18n.prop("org_openo_msb_route-table-sPrevious"), - "sNext": $.i18n.prop("org_openo_msb_route-table-sNext"), - "sPage": $.i18n.prop("org_openo_msb_route-table-sPage"), - "sPageOf": $.i18n.prop("org_openo_msb_route-table-sPageOf") - }, - "sSearch": $.i18n.prop("org_openo_msb_route-table-search"), - "sInfoFiltered": $.i18n.prop("org_openo_msb_route-table-infofilter") - }; - - } - - - - }); - - +/* + * 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. + */ +var table; +var vm = avalon + .define({ + $id : "routeController", + route:{ + routeWay:"ip", + routeHost:"", + routeIP:"", + routePort:"", + routeSubDomain:"", + iuiRootPath:iuiRootPath, + apiRootPath:apiRootPath + }, + apiIframeUrl:"", + iuiIframeUrl:"", + boxVisible:true, + routeTargetTitle:"", + server_rtn:{ + info_block:false, + warning_block:false, + rtn_info:"" + }, + showAPIType:"0", + showAPITypeName:[$.i18n.prop("org_onap_msb_route_swagger_type_predefined"),$.i18n.prop("org_onap_msb_route_swagger_type_custominput")], + $msbProtocol :["REST","HTTP","UI","MQ","FTP","SNMP","TCP","UDP"], + $msbType:["UI","NAF","SAF"], + apiJson:{ + local:"", + custom:"" + }, + setAPIType:function(type){ + vm.apiRouteInfo.apiJsonType=type; + if(type==0){ + vm.apiJson.local=vm.jsonApiSelectList.selectItems[0]; + } + + }, + jsonApiSelectList: { + condName : "type", + component_type : 'select', + selectItems : [] + }, + + dataTableLanguage: { + "sProcessing": "  Loadding...", + "sLengthMenu": $.i18n.prop("org_onap_msb_route-table-sLengthMenu"), + "sZeroRecords": $.i18n.prop("org_onap_msb_route-table-sZeroRecords"), + "sInfo": " " + $.i18n.prop("org_onap_msb_route-table-sInfo"), + "sInfoEmpty": $.i18n.prop("org_onap_msb_route-table-sInfoEmpty"), + "sGroupActions": $.i18n.prop("org_onap_msb_route-table-sGroupActions"), + "sAjaxRequestGeneralError": $.i18n.prop("org_onap_msb_route-table-sAjaxRequestGeneralError"), + "sEmptyTable": $.i18n.prop("org_onap_msb_route-table-sEmptyTable"), + "oPaginate": { + "sPrevious": $.i18n.prop("org_onap_msb_route-table-sPrevious"), + "sNext": $.i18n.prop("org_onap_msb_route-table-sNext"), + "sPage": $.i18n.prop("org_onap_msb_route-table-sPage"), + "sPageOf": $.i18n.prop("org_onap_msb_route-table-sPageOf") + }, + "sSearch": $.i18n.prop("org_onap_msb_route-table-search"), + "sInfoFiltered": $.i18n.prop("org_onap_msb_route-table-infofilter") + }, + $apiRouteUrl :apiBasePath+'/apiRoute', + $apiRouteInstanceUrl :apiBasePath+'/apiRoute/{serviceName}/version/{version}', + $apiRouteStatusUrl :apiBasePath+'/apiRoute/{serviceName}/version/{version}/status/{status}', + $apiDocsUrl :apiBasePath+'/apiRoute/apiDocs', + $apiGatewayPortUrl :apiBasePath+'/apiRoute/apiGatewayPort', + $discoverInfoUrl :apiBasePath+'/apiRoute/discoverInfo', + $iuiRouteUrl :apiBasePath+'/iuiRoute', + $iuiRouteInstanceUrl :apiBasePath+'/iuiRoute/{serviceName}', + $iuiRouteStatusUrl :apiBasePath+'/iuiRoute/{serviceName}/status/{status}', + $customRouteUrl :apiBasePath+'/customRoute/all', + $customRouteInstanceUrl :apiBasePath+'/customRoute/instance', + $customRouteStatusUrl :apiBasePath+'/customRoute/status', + $msbRouteUrl:apiBasePath+'/services', + $msbRouteInstanceUrl :apiBasePath+'/services/{serviceName}/version/{version}', + routeLoading:false, + apiRouteArray : [], + apiGroupByPortArray : [], + apiRouteInfo : { + oldServiceName:"", + serviceName : "", + oldVersion:"", + version : "", + status:"", + url:"", + apiJson:"/swagger.json", + apiJsonType:"1", + control:"", + host:"", + publish_port:"", + publishProtocol:"", + server:"", + servers: [] + }, + iuiRouteArray : [], + iuiGroupByPortArray : [], + iuiRouteInfo : { + oldServiceName:"", + serviceName : "", + status:"", + url:"", + server:"", + control:"", + host:"", + publish_port:"", + publishProtocol:"", + servers: [] + }, + customRouteArray : [], + customGroupByPortArray : [], + customGroupRouteArray : [], + customRouteInfo : { + oldServiceName:"", + serviceName : "", + status:"", + url:"", + server:"", + control:"", + host:"", + publish_port:"", + publishProtocol:"", + servers: [] + }, + msbRouteArray : [], + msbRouteInfo : { + oldServiceName:"", + oldVersion:"", + serviceName : "", + version:"", + status:"0", + nodes:[], + newHost:"", + newttl:0, + url:"", + protocol:"", + visualRange:"", + visualRangeArray:[] + }, + discoverInfo:{ + ip:"", + port:"", + enabled:true, + deployMode:"" + }, + selectedRoute:"", + selectedRouteType:"", + routeDlgInfo:{ + titleName:"", + saveType:"" + }, + $initRoute : function() { + + + vm.route.routeSubDomain=window.location.host.substring(3); + + vm.route.routeWay="ip"; + vm.route.routeHost=window.location.host.split(":")[0]; //Default show port:80 + vm.route.routeIP=window.location.host.split(":")[0]; + + /*if(window.location.host.split(":")[1]==null){ + vm.route.routePort="80"; + } + else{ + vm.route.routePort=window.location.host.split(":")[1]; + }*/ + + vm.route.routePort="80"; + + var getDiscoverInfoReturn=true; + $.ajax({ + "type": 'get', + "async": false, + "url": vm.$discoverInfoUrl, + "dataType": "json", + success: function (resp) { + + vm.discoverInfo = (resp==null)?"":resp; + + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + getDiscoverInfoReturn=false; + bootbox.alert("get discoverInfo from server fails:"+XMLHttpRequest.statusText); + + } + }); + + + + + if(!getDiscoverInfoReturn) return; + + vm.routeLoading=true; + + $.ajax({ + "type": 'get', + "url": vm.$apiRouteUrl+"?routeWay="+vm.route.routeWay, + "dataType": "json", + success: function (resp) { + //vm.apiRouteArray = (resp==null)?[]:resp; + //vm.apiRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); + if(resp!=null && resp.length>0){ + vm.apiGroupByPortArray=routeUtil.groupRouteByPort(resp); + } + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + bootbox.alert("get API serviceInfos fails:"+XMLHttpRequest.responseText); + + }, + complete:function(){ + vm.routeLoading=false; + routeUtil.refreshRoute(); + + } + }); + + + $.ajax({ + "type": 'get', + "url": vm.$iuiRouteUrl+"?routeWay="+vm.route.routeWay, + "dataType": "json", + success: function (resp) { + //vm.iuiRouteArray = (resp==null)?[]:resp; + //vm.iuiRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); + if(resp!=null && resp.length>0){ + vm.iuiGroupByPortArray=routeUtil.groupRouteByPort(resp); + } + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + console.info("get iui services fails:"+XMLHttpRequest.responseText); + + }, + complete:function(){ + routeUtil.refreshRoute(); + } + }); + + + + $.ajax({ + "type": 'get', + "url": vm.$customRouteUrl+"?routeWay="+vm.route.routeWay, + "dataType": "json", + success: function (resp) { + //vm.customRouteArray = (resp==null)?[]:resp; + + if(resp!=null && resp.length>0) + { + //routeUtil.groupRoute(resp); + vm.customGroupByPortArray=routeUtil.groupRouteByPort(resp); + } + + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + console.info("get custom services fails:"+XMLHttpRequest.responseText); + + }, + complete:function(){ + routeUtil.refreshRoute(); + } + }); + + + $.ajax({ + "type": 'get', + "url": vm.$apiDocsUrl, + "dataType": "json", + success: function (resp) { + vm.jsonApiSelectList.selectItems= (resp==null)?[]:resp; + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + console.info("get local apiDocs fails:"+textStatus+":"+errorThrown); + } + }); + + + + + vm.initIUIfori18n(); + + + + if(vm.discoverInfo.enabled==false){ + vm.initMSBRoute(); + } + + + + + }, + initMSBRoute:function(){ + vm.initIUIfori18n(); + + $.ajax({ + "type": 'get', + "url": vm.$msbRouteUrl, + "dataType": "json", + success: function (resp) { + vm.msbRouteArray = (resp==null)?[]:resp; + + vm.msbRouteArray.sort(function(a,b){return a.serviceName>b.serviceName?1:-1}); + + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + bootbox.alert("get msb services fails:"+XMLHttpRequest.responseText); + return; + }, + complete:function(){ + + table=$('#msbTable').DataTable({ + + "oLanguage": vm.dataTableLanguage, + columnDefs: [ { + targets: [ 0,8 ], + "searchable": false, + "bSortable": false + }], + "order": [[2, 'asc']] + }); + + } + }); + + + }, + + clickDisplayGraphAlink: function () { + vm.boxVisible = !vm.boxVisible; + }, + addmsbHost:function(){ + if(vm.msbRouteInfo.newHost==""){ + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop("org_onap_msb_route_err_host_empty"); + return; + } + + if(vm.msbRouteInfo.newttl==""){ + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop("org_onap_msb_route_err_ttl_empty"); + return; + } + + var reg=/^(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})$/ + var ip,port; + if(!reg.test(vm.msbRouteInfo.newHost)){ + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop("org_onap_msb_route_err_host_format"); + return; + } + else{ + + var hosts=vm.msbRouteInfo.newHost.split(":"); + ip=hosts[0]; + port=hosts[1]; + } + + var reg_ttl=/^\d+$/ + + if(!reg_ttl.test(vm.msbRouteInfo.newttl)){ + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop("org_onap_msb_route_err_ttl_format"); + return; + } + + + + // determine whether host repeated + for(var i=0;ib.serviceName?1:-1}); + + routeUtil.refreshRoute(); + $('#iuirouteDlg').modal('hide'); + routeUtil.growl($.i18n.prop('org_onap_msb_route_tab_iui'),$.i18n.prop('org_onap_msb_route_service_save'),"success"); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop('org_onap_msb_route_err_service_save')+textStatus+":"+errorThrown; + + } + }); + } + else{ //update + + var url= vm.$iuiRouteInstanceUrl; + url=url.replace("{serviceName}",vm.iuiRouteInfo.oldServiceName); + url=url+"?host="+vm.iuiRouteInfo.host+"&publish_port="+vm.iuiRouteInfo.publish_port+"&routeWay="+vm.route.routeWay; + + + //Determine whether to repeat + if(vm.iuiRouteInfo.serviceName!=vm.iuiRouteInfo.oldServiceName) //Has been modified service name + { + for(var i=0;ib.serviceName?1:-1}); + + routeUtil.refreshRoute(); + $('#routeDlg').modal('hide'); + routeUtil.growl($.i18n.prop('org_onap_msb_route_tab_api'),$.i18n.prop('org_onap_msb_route_service_save'),"success"); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + + vm.server_rtn.warning_block=true; + vm.server_rtn.info_block=false; + vm.server_rtn.rtn_info= $.i18n.prop('org_onap_msb_route_err_service_save')+textStatus+":"+errorThrown; + + } + }); + } + else{ //update + + + //Determine whether to repeat + if(vm.apiRouteInfo.serviceName!=vm.apiRouteInfo.oldServiceName || + vm.apiRouteInfo.version!=vm.apiRouteInfo.oldVersion) //Has been modified service name + { + for(var i=0;i  Loadding...", + "sLengthMenu": $.i18n.prop("org_onap_msb_route-table-sLengthMenu"), + "sZeroRecords": $.i18n.prop("org_onap_msb_route-table-sZeroRecords"), + "sInfo": " " + $.i18n.prop("org_onap_msb_route-table-sInfo"), + "sInfoEmpty": $.i18n.prop("org_onap_msb_route-table-sInfoEmpty"), + "sGroupActions": $.i18n.prop("org_onap_msb_route-table-sGroupActions"), + "sAjaxRequestGeneralError": $.i18n.prop("org_onap_msb_route-table-sAjaxRequestGeneralError"), + "sEmptyTable": $.i18n.prop("org_onap_msb_route-table-sEmptyTable"), + "oPaginate": { + "sPrevious": $.i18n.prop("org_onap_msb_route-table-sPrevious"), + "sNext": $.i18n.prop("org_onap_msb_route-table-sNext"), + "sPage": $.i18n.prop("org_onap_msb_route-table-sPage"), + "sPageOf": $.i18n.prop("org_onap_msb_route-table-sPageOf") + }, + "sSearch": $.i18n.prop("org_onap_msb_route-table-search"), + "sInfoFiltered": $.i18n.prop("org_onap_msb_route-table-infofilter") + }; + + } + + + + }); + + diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js similarity index 93% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js index 26fe171..aabd941 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeFunc.js @@ -1,649 +1,645 @@ -/* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - * - * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn - */ -$(function(){ - - $('#msbTable tbody').on('click', 'td.details-control', function () { - var tr = $(this).closest('tr'); - var row = table.row( tr ); - if ( row.child.isShown() ) { - // This row is already open - close it - row.child.hide(); - tr.removeClass('shown'); - } - else { - // Open this row - var nodes=row.data()[1].match(/\d+.\d+.\d+.\d+:\d+:(-)?\d+/g) - - row.child( routeUtil.formatDetail(nodes) ).show(); - tr.addClass('shown'); - } - } ); - - $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { - //Get the name of the TAB has been activated - var activeTab = $(e.target).text(); - if(this.id=="customTab" || this.id=="msbTab"){ - $("#serviceContent").hide(); - $("#upArrawDiv").hide(); - } - else{ - $("#serviceContent").show(); - $("#upArrawDiv").show(); - $('#msbSubPage').attr("src",""); - $(".stats_box .routeDiv").removeClass("active"); - vm.selectedRouteType=""; - vm.routeTargetTitle=$.i18n.prop("org_openo_msb_route_content_title"); - - } - }); - - - $("[data-toggle='tooltip']").tooltip(); - - $('#metricsFullurl').on('show.bs.collapse', function () { - $('#metricsUrlCollapse').removeClass('fa-plus').addClass('fa-minus'); - - }); - - $('#metricsFullurl').on('hide.bs.collapse', function () { - $('#metricsUrlCollapse').removeClass('fa-minus').addClass('fa-plus'); - }); - - $('#apiJsonFullurl').on('show.bs.collapse', function () { - $('#apiJsonCollapse').removeClass('fa-plus').addClass('fa-minus'); - - }); - - $('#apiJsonFullurl').on('hide.bs.collapse', function () { - $('#apiJsonCollapse').removeClass('fa-minus').addClass('fa-plus'); - }); - - - - $(".form-tip").blur(function(){ - if($.trim($(this).val())==""){ - $(this).removeClass("form-input-focus"); - $(this).prev().removeClass("item-tip-focus"); - }}); - -$(".form-tip").focus(function(){ - if(!$(this).hasClass("form-input-focus")){ - $(this).addClass("form-input-focus"); - $(this).prev().addClass("item-tip-focus"); - }}); - -$(".item-tip").click(function(){ - $(this).next().focus(); -}); - - - -$("input[name='version']").blur(function(){ - $(this).val($(this).val().toLowerCase()); - routeUtil.changeTargetServiceUrl(); -}); - - -$("input[name='url']").blur(function(){ - -routeUtil.changeTargetServiceUrl(); - -}); -$("input[name='serviceName']").blur(function(){ - -routeUtil.changeTargetServiceUrl(); - -}); - - - -$("select[name='protocol']").change(function(){ - -routeUtil.changeTargetServiceUrl(); - -}); - -/* - -$("input[name='oriService']").blur(function(){ - var oriService=$.trim($(this).val()); - if(oriService==""){ - $("input[name='serviceName']").val(""); - $("input[name='version']").val(""); - $("input[name='server']").val(""); - $("input[name='url']").val(""); - return; - } - - - - var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ - var reg_standard_match=/^(.*:\d{1,5})\/api\/(.*)\/(v.*)$/ - var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ - if(reg.test(oriService)){ - if(reg_standard_match.test(oriService)){ - //标准api - var group = oriService.match(reg_standard_match); - $("input[name='serviceName']").val(group[2]); - $("input[name='server']").val(group[1].replace("http://","")); - - - var version=group[3]; - var reg_endName_match=/^(.*?)\/.*$/ - if(reg_endName_match.test(version)){ - version = version.match(reg_endName_match)[1]; - } - $("input[name='version']").val(version); - $("input[name='url']").val("/api/"+group[2]+"/"+version); - - if(!$("input[name='version']").hasClass("form-input-focus")){ - $("input[name='version']").addClass("form-input-focus"); - $("input[name='version']").prev().addClass("item-tip-focus"); - } - - - - } - else{ - //非标准api - var group = oriService.match(reg_unstandard_match); - var reg_endName_match=/^(.*?)\/$/ - var url=group[2]; - if(url!="/" && reg_endName_match.test(url)){ - url = url.match(reg_endName_match)[1]; - } - - - $("input[name='serviceName']").val(""); - $("input[name='version']").val(""); - $("input[name='server']").val(group[1].replace("http://","")); - $("input[name='url']").val(url); - } - - if(!$("input[name='server']").hasClass("form-input-focus")){ - $("input[name='server']").addClass("form-input-focus"); - $("input[name='server']").prev().addClass("item-tip-focus"); - } - } - - -}); - - -$("input[name='iuioriService']").blur(function(){ - var oriService=$.trim($(this).val()); - if(oriService==""){ - $("input[name='iuiserviceName']").val(""); - $("input[name='iuiserver']").val(""); - $("input[name='iuiurl']").val(""); - return; - } - - - - var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ - var reg_standard_match=/^(.*:\d{1,5})\/iui\/(.*|.*\/)$/ - var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ - if(reg.test(oriService)){ - if(reg_standard_match.test(oriService)){ - //标准api - var group = oriService.match(reg_standard_match); - - - $("input[name='iuiserver']").val(group[1].replace("http://","")); - - - var serviceName=group[2]; - var reg_endName_match=/^(.*?)\/.*$/ - if(reg_endName_match.test(serviceName)){ - serviceName = serviceName.match(reg_endName_match)[1]; - } - $("input[name='iuiserviceName']").val(serviceName); - $("input[name='iuiurl']").val("/iui/"+serviceName); - - } - else{ - //非标准api - var group = oriService.match(reg_unstandard_match); - - var reg_endName_match=/^(.*?)\/$/ - var url=group[2]; - if(url!="/" && reg_endName_match.test(url)){ - url = url.match(reg_endName_match)[1]; - } - $("input[name='iuiserver']").val(group[1].replace("http://","")); - $("input[name='iuiurl']").val(url); - } - - if(!$("input[name='iuiserver']").hasClass("form-input-focus")){ - $("input[name='iuiserver']").addClass("form-input-focus"); - $("input[name='iuiserver']").prev().addClass("item-tip-focus"); - } - } - - -}); - -$("input[name='customoriService']").blur(function(){ - var oriService=$.trim($(this).val()); - if(oriService==""){ - $("input[name='customserviceName']").val(""); - $("input[name='customserver']").val(""); - $("input[name='customurl']").val(""); - return; - } - - - - var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ - - var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ - if(reg.test(oriService)){ - - - var group = oriService.match(reg_unstandard_match); - - var reg_endName_match=/^(.*?)\/$/ - var url=group[2]; - if(url!="/" && reg_endName_match.test(url)){ - url = url.match(reg_endName_match)[1]; - } - $("input[name='customserver']").val(group[1].replace("http://","")); - $("input[name='customurl']").val(url); - $("input[name='customserviceName']").val(url); - - - if(!$("input[name='customserver']").hasClass("form-input-focus")){ - $("input[name='customserver']").addClass("form-input-focus"); - $("input[name='customserver']").prev().addClass("item-tip-focus"); - } - } - - -}); - -*/ - - jQuery.validator.addMethod("ip", function(value, element) { - return this.optional(element) || /^(([-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})$/.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_ip_format')); - - - - jQuery.validator.addMethod("url_head", function(value, element) { - return this.optional(element) || /^\/.+((?!\/).)$/i.test(value) || /^\/$/i.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_url_head_format')); - - -jQuery.validator.addMethod("url_head_only", function(value, element) { - return this.optional(element) || /^\/.*$/i.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_url_head_only_format')); - - jQuery.validator.addMethod("version", function(value, element) { - return this.optional(element) || /^v\d+(\.\d+)?$/i.test(value); - }, $.i18n.prop('org_openo_msb_route_form_version_tip')); - - jQuery.validator.addMethod("service_url", function(value, element) { - return this.optional(element) || /^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_url_format')); - - jQuery.validator.addMethod("url_line", function(value, element) { - return this.optional(element) || /^((?!\/).)*$/.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_url_line_format')); - - jQuery.validator.addMethod("content", function(value, element) { - return this.optional(element) || /^([0-9a-zA-Z]|-|_)*$/i.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_content_format')); - - jQuery.validator.addMethod("custom_content", function(value, element) { - return this.optional(element) || /^([0-9a-zA-Z]|-|_|\/)*$/i.test(value); - }, $.i18n.prop('org_openo_msb_route_validator_content_format')); - - - }); - - var form = $('#routeForm'); - var error = $('.alert-danger', form); - var success = $('.alert-success', form); - - var iuiform = $('#iuirouteForm'); - var iuierror = $('.alert-danger', iuiform); - var iuisuccess = $('.alert-success', iuiform); - - - var customform = $('#customrouteForm'); - var customerror = $('.alert-danger', customform); - var customsuccess = $('.alert-success', customform); - - var msbform = $('#msbForm'); - var msberror = $('.alert-danger', msbform); - var msbsuccess = $('.alert-success', msbform); - - - form.validate({ - doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. - errorElement: 'span', //default input error message container - errorClass: 'help-block', // default input error message class - focusInvalid: false, // do not focus the last invalid input - rules: { - /* oriService:{ - service_url:true, - maxlength:100 - },*/ - serviceName:{ - required: true, - url_line:true, - content:true, - maxlength:50 - }, - version:{ - // required: true, - maxlength:50, - version:true - }, - url:{ - required: true, - url_head:true, - maxlength:50 - }, - metricsUrl:{ - url_head:true, - maxlength:50 - }, - server:{ - ip:true, - maxlength:50 - } - }, - messages: { - serviceName:{ - required: "Please enter the service name" - }, - url:{ - required: "Please enter the URL address" - - }, - server:{ - required:"Please enter the Host address" - - }, - - }, - errorPlacement: function (error, element) { // render error placement for each input type - error.insertAfter(element); // for other inputs, just perform default behavior - }, - - invalidHandler: function (event, validator) { //display error alert on form submit - success.hide(); - error.show(); - //ZteFrameWork.scrollTo(error, -200); - }, - - highlight: function (element) { // hightlight error inputs - $(element) - .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group - }, - - unhighlight: function (element) { // revert the change done by hightlight - $(element) - .closest('.form-group').removeClass('has-error'); // set error class to the control group - }, - - success: function (label) { - label - .addClass('valid') // mark the current input as valid and display OK icon - .closest('.form-group').removeClass('has-error'); // set success class to the control group - }, - submitHandler: function (form) { - success.show(); - error.hide(); - //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax - } - - }); - - iuiform.validate({ - doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. - errorElement: 'span', //default input error message container - errorClass: 'help-block', // default input error message class - focusInvalid: false, // do not focus the last invalid input - rules: { - /*iuioriService:{ - service_url:true, - maxlength:100 - },*/ - iuiserviceName:{ - required: true, - url_line:true, - maxlength:50, - content:true - }, - iuiurl:{ - required: true, - url_head:true, - maxlength:50 - }, - iuiserver:{ - ip:true, - maxlength:50 - } - }, - messages: { - iuiserviceName:{ - required: "Please enter the service name" - }, - iuiurl:{ - required:"Please enter the URL address" - - }, - iuiserver:{ - required: "Please enter the Host address" - }, - - }, - errorPlacement: function (iuierror, element) { // render error placement for each input type - iuierror.insertAfter(element); // for other inputs, just perform default behavior - }, - - invalidHandler: function (event, validator) { //display error alert on form submit - iuisuccess.hide(); - iuierror.show(); - //ZteFrameWork.scrollTo(error, -200); - }, - - highlight: function (element) { // hightlight error inputs - $(element) - .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group - }, - - unhighlight: function (element) { // revert the change done by hightlight - $(element) - .closest('.form-group').removeClass('has-error'); // set error class to the control group - }, - - success: function (label) { - label - .addClass('valid') // mark the current input as valid and display OK icon - .closest('.form-group').removeClass('has-error'); // set success class to the control group - }, - submitHandler: function (form) { - iuisuccess.show(); - iuierror.hide(); - //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax - } - - }); - - customform.validate({ - doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. - errorElement: 'span', //default input error message container - errorClass: 'help-block', // default input error message class - focusInvalid: false, // do not focus the last invalid input - rules: { - /*customoriService:{ - service_url:true, - maxlength:100 - },*/ - customserviceName:{ - required: false, - url_head:true, - maxlength:100, - custom_content:true - }, - customurl:{ - required: true, - url_head:true, - maxlength:50 - }, - customserver:{ - ip:true, - maxlength:50 - } - }, - messages: { - customserviceName:{ - required: "Please enter the service name" - }, - customurl:{ - required: "Please enter the URL address" - - } - - }, - errorPlacement: function (customerror, element) { // render error placement for each input type - customerror.insertAfter(element); // for other inputs, just perform default behavior - }, - - invalidHandler: function (event, validator) { //display error alert on form submit - customsuccess.hide(); - customerror.show(); - //ZteFrameWork.scrollTo(error, -200); - }, - - highlight: function (element) { // hightlight error inputs - $(element) - .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group - }, - - unhighlight: function (element) { // revert the change done by hightlight - $(element) - .closest('.form-group').removeClass('has-error'); // set error class to the control group - }, - - success: function (label) { - label - .addClass('valid') // mark the current input as valid and display OK icon - .closest('.form-group').removeClass('has-error'); // set success class to the control group - }, - submitHandler: function (form) { - customsuccess.show(); - customerror.hide(); - //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax - } - - }); - - - msbform.validate({ - doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. - errorElement: 'span', //default input error message container - errorClass: 'help-block', // default input error message class - focusInvalid: false, // do not focus the last invalid input - rules: { - - serviceName:{ - required: true, - // url_line:true, - custom_content:true, - maxlength:50 - }, - version:{ - maxlength:50, - version:true - }, - url:{ - url_head:true, - maxlength:50 - }, - newHost:{ - ip:true, - maxlength:50 - }, - newttl:{ - digits:true, - min:0 - }, - protocol:{ - required: true - }, - type:{ - required: true - } - }, - messages: { - serviceName:{ - required: "Please enter the service name" - }, - protocol:{ - required: "Please select a service protocol" - }, - type:{ - required: "Please select a service type" - - }, - newttl:{ - digits:"Please enter an integer", - min: "Not a negative" - } - - }, - errorPlacement: function (msberror, element) { // render error placement for each input type - msberror.insertAfter(element); // for other inputs, just perform default behavior - }, - - invalidHandler: function (event, validator) { //display error alert on form submit - msbsuccess.hide(); - msberror.show(); - //ZteFrameWork.scrollTo(error, -200); - }, - - highlight: function (element) { // hightlight error inputs - $(element) - .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group - }, - - unhighlight: function (element) { // revert the change done by hightlight - $(element) - .closest('.form-group').removeClass('has-error'); // set error class to the control group - }, - - success: function (label) { - label - .addClass('valid') // mark the current input as valid and display OK icon - .closest('.form-group').removeClass('has-error'); // set success class to the control group - }, - submitHandler: function (form) { - msbsuccess.show(); - msberror.hide(); - //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax - } - - }); - - +/* + * 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. + */ +$(function(){ + + $('#msbTable tbody').on('click', 'td.details-control', function () { + var tr = $(this).closest('tr'); + var row = table.row( tr ); + if ( row.child.isShown() ) { + // This row is already open - close it + row.child.hide(); + tr.removeClass('shown'); + } + else { + // Open this row + var nodes=row.data()[1].match(/\d+.\d+.\d+.\d+:\d+:(-)?\d+/g) + + row.child( routeUtil.formatDetail(nodes) ).show(); + tr.addClass('shown'); + } + } ); + + $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { + //Get the name of the TAB has been activated + var activeTab = $(e.target).text(); + if(this.id=="customTab" || this.id=="msbTab"){ + $("#serviceContent").hide(); + $("#upArrawDiv").hide(); + } + else{ + $("#serviceContent").show(); + $("#upArrawDiv").show(); + $('#msbSubPage').attr("src",""); + $(".stats_box .routeDiv").removeClass("active"); + vm.selectedRouteType=""; + vm.routeTargetTitle=$.i18n.prop("org_onap_msb_route_content_title"); + + } + }); + + + $("[data-toggle='tooltip']").tooltip(); + + $('#metricsFullurl').on('show.bs.collapse', function () { + $('#metricsUrlCollapse').removeClass('fa-plus').addClass('fa-minus'); + + }); + + $('#metricsFullurl').on('hide.bs.collapse', function () { + $('#metricsUrlCollapse').removeClass('fa-minus').addClass('fa-plus'); + }); + + $('#apiJsonFullurl').on('show.bs.collapse', function () { + $('#apiJsonCollapse').removeClass('fa-plus').addClass('fa-minus'); + + }); + + $('#apiJsonFullurl').on('hide.bs.collapse', function () { + $('#apiJsonCollapse').removeClass('fa-minus').addClass('fa-plus'); + }); + + + + $(".form-tip").blur(function(){ + if($.trim($(this).val())==""){ + $(this).removeClass("form-input-focus"); + $(this).prev().removeClass("item-tip-focus"); + }}); + +$(".form-tip").focus(function(){ + if(!$(this).hasClass("form-input-focus")){ + $(this).addClass("form-input-focus"); + $(this).prev().addClass("item-tip-focus"); + }}); + +$(".item-tip").click(function(){ + $(this).next().focus(); +}); + + + +$("input[name='version']").blur(function(){ + $(this).val($(this).val().toLowerCase()); + routeUtil.changeTargetServiceUrl(); +}); + + +$("input[name='url']").blur(function(){ + +routeUtil.changeTargetServiceUrl(); + +}); +$("input[name='serviceName']").blur(function(){ + +routeUtil.changeTargetServiceUrl(); + +}); + + + +$("select[name='protocol']").change(function(){ + +routeUtil.changeTargetServiceUrl(); + +}); + +/* + +$("input[name='oriService']").blur(function(){ + var oriService=$.trim($(this).val()); + if(oriService==""){ + $("input[name='serviceName']").val(""); + $("input[name='version']").val(""); + $("input[name='server']").val(""); + $("input[name='url']").val(""); + return; + } + + + + var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ + var reg_standard_match=/^(.*:\d{1,5})\/api\/(.*)\/(v.*)$/ + var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ + if(reg.test(oriService)){ + if(reg_standard_match.test(oriService)){ + //标准api + var group = oriService.match(reg_standard_match); + $("input[name='serviceName']").val(group[2]); + $("input[name='server']").val(group[1].replace("http://","")); + + + var version=group[3]; + var reg_endName_match=/^(.*?)\/.*$/ + if(reg_endName_match.test(version)){ + version = version.match(reg_endName_match)[1]; + } + $("input[name='version']").val(version); + $("input[name='url']").val("/api/"+group[2]+"/"+version); + + if(!$("input[name='version']").hasClass("form-input-focus")){ + $("input[name='version']").addClass("form-input-focus"); + $("input[name='version']").prev().addClass("item-tip-focus"); + } + + + + } + else{ + //非标准api + var group = oriService.match(reg_unstandard_match); + var reg_endName_match=/^(.*?)\/$/ + var url=group[2]; + if(url!="/" && reg_endName_match.test(url)){ + url = url.match(reg_endName_match)[1]; + } + + + $("input[name='serviceName']").val(""); + $("input[name='version']").val(""); + $("input[name='server']").val(group[1].replace("http://","")); + $("input[name='url']").val(url); + } + + if(!$("input[name='server']").hasClass("form-input-focus")){ + $("input[name='server']").addClass("form-input-focus"); + $("input[name='server']").prev().addClass("item-tip-focus"); + } + } + + +}); + + +$("input[name='iuioriService']").blur(function(){ + var oriService=$.trim($(this).val()); + if(oriService==""){ + $("input[name='iuiserviceName']").val(""); + $("input[name='iuiserver']").val(""); + $("input[name='iuiurl']").val(""); + return; + } + + + + var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ + var reg_standard_match=/^(.*:\d{1,5})\/iui\/(.*|.*\/)$/ + var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ + if(reg.test(oriService)){ + if(reg_standard_match.test(oriService)){ + //标准api + var group = oriService.match(reg_standard_match); + + + $("input[name='iuiserver']").val(group[1].replace("http://","")); + + + var serviceName=group[2]; + var reg_endName_match=/^(.*?)\/.*$/ + if(reg_endName_match.test(serviceName)){ + serviceName = serviceName.match(reg_endName_match)[1]; + } + $("input[name='iuiserviceName']").val(serviceName); + $("input[name='iuiurl']").val("/iui/"+serviceName); + + } + else{ + //非标准api + var group = oriService.match(reg_unstandard_match); + + var reg_endName_match=/^(.*?)\/$/ + var url=group[2]; + if(url!="/" && reg_endName_match.test(url)){ + url = url.match(reg_endName_match)[1]; + } + $("input[name='iuiserver']").val(group[1].replace("http://","")); + $("input[name='iuiurl']").val(url); + } + + if(!$("input[name='iuiserver']").hasClass("form-input-focus")){ + $("input[name='iuiserver']").addClass("form-input-focus"); + $("input[name='iuiserver']").prev().addClass("item-tip-focus"); + } + } + + +}); + +$("input[name='customoriService']").blur(function(){ + var oriService=$.trim($(this).val()); + if(oriService==""){ + $("input[name='customserviceName']").val(""); + $("input[name='customserver']").val(""); + $("input[name='customurl']").val(""); + return; + } + + + + var reg=/^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/ + + var reg_unstandard_match=/^(.*:\d{1,5})(\/.*)$/ + if(reg.test(oriService)){ + + + var group = oriService.match(reg_unstandard_match); + + var reg_endName_match=/^(.*?)\/$/ + var url=group[2]; + if(url!="/" && reg_endName_match.test(url)){ + url = url.match(reg_endName_match)[1]; + } + $("input[name='customserver']").val(group[1].replace("http://","")); + $("input[name='customurl']").val(url); + $("input[name='customserviceName']").val(url); + + + if(!$("input[name='customserver']").hasClass("form-input-focus")){ + $("input[name='customserver']").addClass("form-input-focus"); + $("input[name='customserver']").prev().addClass("item-tip-focus"); + } + } + + +}); + +*/ + + jQuery.validator.addMethod("ip", function(value, element) { + return this.optional(element) || /^(([-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})$/.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_ip_format')); + + + + jQuery.validator.addMethod("url_head", function(value, element) { + return this.optional(element) || /^\/.+((?!\/).)$/i.test(value) || /^\/$/i.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_url_head_format')); + + +jQuery.validator.addMethod("url_head_only", function(value, element) { + return this.optional(element) || /^\/.*$/i.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_url_head_only_format')); + + jQuery.validator.addMethod("version", function(value, element) { + return this.optional(element) || /^v\d+(\.\d+)?$/i.test(value); + }, $.i18n.prop('org_onap_msb_route_form_version_tip')); + + jQuery.validator.addMethod("service_url", function(value, element) { + return this.optional(element) || /^(|http:\/\/)(([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.)(([0-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))):(\d{1,5})\/.*$/.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_url_format')); + + jQuery.validator.addMethod("url_line", function(value, element) { + return this.optional(element) || /^((?!\/).)*$/.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_url_line_format')); + + jQuery.validator.addMethod("content", function(value, element) { + return this.optional(element) || /^([0-9a-zA-Z]|-|_)*$/i.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_content_format')); + + jQuery.validator.addMethod("custom_content", function(value, element) { + return this.optional(element) || /^([0-9a-zA-Z]|-|_|\/)*$/i.test(value); + }, $.i18n.prop('org_onap_msb_route_validator_content_format')); + + + }); + + var form = $('#routeForm'); + var error = $('.alert-danger', form); + var success = $('.alert-success', form); + + var iuiform = $('#iuirouteForm'); + var iuierror = $('.alert-danger', iuiform); + var iuisuccess = $('.alert-success', iuiform); + + + var customform = $('#customrouteForm'); + var customerror = $('.alert-danger', customform); + var customsuccess = $('.alert-success', customform); + + var msbform = $('#msbForm'); + var msberror = $('.alert-danger', msbform); + var msbsuccess = $('.alert-success', msbform); + + + form.validate({ + doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. + errorElement: 'span', //default input error message container + errorClass: 'help-block', // default input error message class + focusInvalid: false, // do not focus the last invalid input + rules: { + /* oriService:{ + service_url:true, + maxlength:100 + },*/ + serviceName:{ + required: true, + url_line:true, + content:true, + maxlength:50 + }, + version:{ + // required: true, + maxlength:50, + version:true + }, + url:{ + required: true, + url_head:true, + maxlength:50 + }, + metricsUrl:{ + url_head:true, + maxlength:50 + }, + server:{ + ip:true, + maxlength:50 + } + }, + messages: { + serviceName:{ + required: "Please enter the service name" + }, + url:{ + required: "Please enter the URL address" + + }, + server:{ + required:"Please enter the Host address" + + } + + }, + errorPlacement: function (error, element) { // render error placement for each input type + error.insertAfter(element); // for other inputs, just perform default behavior + }, + + invalidHandler: function (event, validator) { //display error alert on form submit + success.hide(); + error.show(); + //ZteFrameWork.scrollTo(error, -200); + }, + + highlight: function (element) { // hightlight error inputs + $(element) + .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group + }, + + unhighlight: function (element) { // revert the change done by hightlight + $(element) + .closest('.form-group').removeClass('has-error'); // set error class to the control group + }, + + success: function (label) { + label + .addClass('valid') // mark the current input as valid and display OK icon + .closest('.form-group').removeClass('has-error'); // set success class to the control group + }, + submitHandler: function (form) { + success.show(); + error.hide(); + //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax + } + + }); + + iuiform.validate({ + doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. + errorElement: 'span', //default input error message container + errorClass: 'help-block', // default input error message class + focusInvalid: false, // do not focus the last invalid input + rules: { + /*iuioriService:{ + service_url:true, + maxlength:100 + },*/ + iuiserviceName:{ + required: true, + url_line:true, + maxlength:50, + content:true + }, + iuiurl:{ + required: true, + url_head:true, + maxlength:50 + }, + iuiserver:{ + ip:true, + maxlength:50 + } + }, + messages: { + iuiserviceName:{ + required: "Please enter the service name" + }, + iuiurl:{ + required:"Please enter the URL address" + + }, + iuiserver:{ + required: "Please enter the Host address" + } + }, + errorPlacement: function (iuierror, element) { // render error placement for each input type + iuierror.insertAfter(element); // for other inputs, just perform default behavior + }, + + invalidHandler: function (event, validator) { //display error alert on form submit + iuisuccess.hide(); + iuierror.show(); + //ZteFrameWork.scrollTo(error, -200); + }, + + highlight: function (element) { // hightlight error inputs + $(element) + .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group + }, + + unhighlight: function (element) { // revert the change done by hightlight + $(element) + .closest('.form-group').removeClass('has-error'); // set error class to the control group + }, + + success: function (label) { + label + .addClass('valid') // mark the current input as valid and display OK icon + .closest('.form-group').removeClass('has-error'); // set success class to the control group + }, + submitHandler: function (form) { + iuisuccess.show(); + iuierror.hide(); + //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax + } + + }); + + customform.validate({ + doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. + errorElement: 'span', //default input error message container + errorClass: 'help-block', // default input error message class + focusInvalid: false, // do not focus the last invalid input + rules: { + /*customoriService:{ + service_url:true, + maxlength:100 + },*/ + customserviceName:{ + required: false, + url_head:true, + maxlength:100, + custom_content:true + }, + customurl:{ + required: true, + url_head:true, + maxlength:50 + }, + customserver:{ + ip:true, + maxlength:50 + } + }, + messages: { + customserviceName:{ + required: "Please enter the service name" + }, + customurl:{ + required: "Please enter the URL address" + + } + + }, + errorPlacement: function (customerror, element) { // render error placement for each input type + customerror.insertAfter(element); // for other inputs, just perform default behavior + }, + + invalidHandler: function (event, validator) { //display error alert on form submit + customsuccess.hide(); + customerror.show(); + //ZteFrameWork.scrollTo(error, -200); + }, + + highlight: function (element) { // hightlight error inputs + $(element) + .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group + }, + + unhighlight: function (element) { // revert the change done by hightlight + $(element) + .closest('.form-group').removeClass('has-error'); // set error class to the control group + }, + + success: function (label) { + label + .addClass('valid') // mark the current input as valid and display OK icon + .closest('.form-group').removeClass('has-error'); // set success class to the control group + }, + submitHandler: function (form) { + customsuccess.show(); + customerror.hide(); + //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax + } + + }); + + + msbform.validate({ + doNotHideMessage: true, //this option enables to show the error/success messages on tab switch. + errorElement: 'span', //default input error message container + errorClass: 'help-block', // default input error message class + focusInvalid: false, // do not focus the last invalid input + rules: { + + serviceName:{ + required: true, + // url_line:true, + custom_content:true, + maxlength:50 + }, + version:{ + maxlength:50, + version:true + }, + url:{ + url_head:true, + maxlength:50 + }, + newHost:{ + ip:true, + maxlength:50 + }, + newttl:{ + digits:true, + min:0 + }, + protocol:{ + required: true + }, + type:{ + required: true + } + }, + messages: { + serviceName:{ + required: "Please enter the service name" + }, + protocol:{ + required: "Please select a service protocol" + }, + type:{ + required: "Please select a service type" + + }, + newttl:{ + digits:"Please enter an integer", + min: "Not a negative" + } + + }, + errorPlacement: function (msberror, element) { // render error placement for each input type + msberror.insertAfter(element); // for other inputs, just perform default behavior + }, + + invalidHandler: function (event, validator) { //display error alert on form submit + msbsuccess.hide(); + msberror.show(); + //ZteFrameWork.scrollTo(error, -200); + }, + + highlight: function (element) { // hightlight error inputs + $(element) + .closest('.form-group').removeClass('has-success').addClass('has-error'); // set error class to the control group + }, + + unhighlight: function (element) { // revert the change done by hightlight + $(element) + .closest('.form-group').removeClass('has-error'); // set error class to the control group + }, + + success: function (label) { + label + .addClass('valid') // mark the current input as valid and display OK icon + .closest('.form-group').removeClass('has-error'); // set success class to the control group + }, + submitHandler: function (form) { + msbsuccess.show(); + msberror.hide(); + //add here some ajax code to submit your form or just call form.submit() if you want to submit the form without ajax + } + + }); + + diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js similarity index 72% rename from msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js rename to apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js index 42629cc..954e68c 100644 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js +++ b/apiroute/apiroute-service/src/main/resources/iui-route/js/routeUtil.js @@ -1,33 +1,42 @@ /* - * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. + * 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 + * 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. - * - * Author: Zhaoxing Meng - * email: meng.zhaoxing1@zte.com.cn */ var routeUtil = {}; routeUtil.growl=function(title,message,type){ $.growl({ icon: "fa fa-envelope-o fa-lg", - title: "  "+$.i18n.prop('org_openo_msb_route_property_ttl')+title, + title: "  "+$.i18n.prop('org_onap_msb_route_property_ttl')+title, message: message+"        " },{ type: type }); } +routeUtil.cutString=function(str){ + var newStr; + if(str.length>22){ + newStr=str.substring(0,20)+"..."; + } + else{ + newStr=str; + } + + return newStr; +} + routeUtil.refreshRoute=function(){ $(".stats_box .routeDiv div[data-name='route_click_zone']").on({ @@ -54,6 +63,74 @@ routeUtil.refreshRoute=function(){ } +routeUtil.groupRouteByPort=function(resp){ + var routeArray=new Array(); + var routeGroupArray=[[]]; + for(var i=0;i 1 + + + for(var groupServiceName in routeArray){ + + if(groupServiceName==""){ + routeGroupArray[0]=routeArray[groupServiceName]; + } + else{ + routeGroupArray.push(routeArray[groupServiceName]); + } + + } + + + for(var i=0;ib.serviceName?1:-1}); + } + + + + return routeGroupArray; + +} + +routeUtil.showGroupPort=function(index,serviceArray){ + + var defaultPort=vm.route.routePort+" http / 443 https"; + + if(serviceArray[0]==null) {return defaultPort;} + + var publish_port=serviceArray[0].publish_port + + if(publish_port==""){ return defaultPort;} + else { return publish_port} + +} + +routeUtil.showPotocol=function(publish_port,publishProtocol){ + + if(publish_port=="") return ""; + + return "
    "+publishProtocol+"
    "; + +} + + + //Sorting grouping custom service routeUtil.groupRoute=function(resp){ var routeArray=new Array(); @@ -77,7 +154,7 @@ routeUtil.groupRoute=function(resp){ groupServiceName = fullServiceName.match(reg_match2)[1]; } else{ - groupServiceName=$.i18n.prop('org_openo_msb_route_property_root'); + groupServiceName=$.i18n.prop('org_onap_msb_route_property_root'); } @@ -137,7 +214,7 @@ routeUtil.showGroupName=function(index,serviceArray){ var maxGroupSN=vm.customGroupRouteArray.length-1; if(index==maxGroupSN){ - return $.i18n.prop('org_openo_msb_route_property_other_group'); + return $.i18n.prop('org_onap_msb_route_property_other_group'); } else{ var serviceName=serviceArray[0].serviceName; @@ -193,13 +270,13 @@ routeUtil.currentTime=function() routeUtil.showStatus=function(status){ if(status === '1'){ - return " "+$.i18n.prop('org_openo_msb_route_property_normal')+""; + return " "+$.i18n.prop('org_onap_msb_route_property_normal')+""; } else if(status === '0'){ - return " "+$.i18n.prop('org_openo_msb_route_property_disable')+""; + return " "+$.i18n.prop('org_onap_msb_route_property_disable')+""; } else { - return " "+$.i18n.prop('org_openo_msb_route_property_unknown')+""; + return " "+$.i18n.prop('org_onap_msb_route_property_unknown')+""; } @@ -213,10 +290,10 @@ routeUtil.showVisualRange=function(visualRange){ for(var i=0;i0){ + latestTime=initDatas[initDatas.length-1]; + } + + + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + statusUtil.connection=false; + alert("get Chart Data fails:"+textStatus+":"+errorThrown); + } + }); + + + var requestChart = echarts.init(document.getElementById('statisticsLineChartDiv'), 'macarons'); + + var option = { + + tooltip : { + trigger: 'axis' + }, + toolbox: { + feature: { + saveAsImage: { + name:'MSB历史访问次数统计图' + } + } + }, + legend: { + data:['每分钟处理请求数'] + }, + xAxis: + { + type: 'category', + boundaryGap: false, + data: times, + name: '采集点' + + }, + yAxis: + { + type: 'value', + scale: true, + name: '请求数', + minInterval: 1, + min: 0, + boundaryGap: [0.1, 0.1] + }, + series: [ + { + name:'每分钟处理请求数', + type:'line', + stack: 'status', + data:datas + } + ] + }; + + // 使用刚指定的配置项和数据显示图表。 + requestChart.setOption(option); + window.onresize = requestChart.resize; + if(statusUtil.connection==true){ + setInterval(function () { + + $.ajax({ + "type": 'get', + "async": true, + "timeout" : 3000, + "url": apiBasePath+"/statistics/request", + "dataType": "json", + success: function (resp) { + + var latestData = (resp==null)?[]:resp; + + if(latestData.length>0){ + var dataArray=latestData[0].split("|"); + + var data = option.series[0].data; + + if(latestTime!=dataArray[0]){ + data.push(dataArray[1]); + option.xAxis.data.push(statusUtil.getLocalTime(dataArray[0])); + if(data.length>=statusUtil.statisticsXAxisCount){ + data.shift(); + option.xAxis.data.shift(); + } + + + var maxVaule=Math.max.apply(null, data); + if(maxVaule<5){ + option.yAxis.max=5; + } + else{ + option.yAxis.max=null; + } + requestChart.setOption(option); + + latestTime=dataArray[0]; + } + + } + } + }); + + + }, statusUtil.statisticsPollTime); + } +} + +var statusLineChart; +var statusLineChartOption; +statusUtil.init_status_requestChart= function(){ + +statusLineChart = echarts.init(document.getElementById('statusLineChartDiv'), 'macarons'); + +statusLineChartOption = { + color:[ "#2ec7c9", + "#b6a2de", + "#ffb980"], + tooltip : { + trigger: 'axis' + }, + toolbox: { + feature: { + saveAsImage: { + name:'MSB正在处理请求数图' + } + } + }, + legend: { + data:['已转发等待响应','已接收待转发','收到响应待返回'] + }, + xAxis: + { + type: 'category', + boundaryGap: false, + name: '采集点', + data: [] + }, + yAxis: + { + type: 'value', + scale: true, + name: '请求数', + min: 0, + minInterval: 1, + boundaryGap: [0.1, 0.1] + }, + series: [ + { + name:'已转发等待响应', + type:'line', + data:[] + }, + { + name:'已接收待转发', + type:'line', + data:[] + }, + { + name:'收到响应待返回', + type:'line', + data:[] + } + + ] + }; + + // 使用刚指定的配置项和数据显示图表。 + statusLineChart.setOption(statusLineChartOption); + window.onresize = statusLineChart.resize; + if(statusUtil.connection==true){ + + statusUtil.getStatusLineChart4Data(); + + setInterval(function () { + statusUtil.getStatusLineChart4Data(); + }, statusUtil.connectionsPollTime); + } +} + +statusUtil.getStatusLineChart4Data=function(){ + + $.ajax({ + "type": 'get', + "async": true, + "timeout" : 3000, + "url": apiBasePath+"/status/request", + "dataType": "json", + success: function (resp) { + + if(resp!=null){ + var forward_data= statusLineChartOption.series[0].data; + var accept_data = statusLineChartOption.series[1].data; + var receive_data = statusLineChartOption.series[2].data; + + + + if(accept_data.length>=statusUtil.statisticsXAxisCount){ + accept_data.shift(); + forward_data.shift(); + receive_data.shift(); + statusLineChartOption.xAxis.data.shift(); + } + + + accept_data.push(resp.accept_preparing_forward); + forward_data.push(resp.forward_waiting_response); + receive_data.push(resp.receive_resp_not_return); + + var allValue=accept_data.concat(forward_data).concat(receive_data); + var maxVaule=Math.max.apply(null, allValue); + if(maxVaule<5){ + statusLineChartOption.yAxis.max=5; + } + else{ + statusLineChartOption.yAxis.max=null; + } + + + statusLineChartOption.xAxis.data.push(statusUtil.getCurrentTime()); + + statusLineChart.setOption(statusLineChartOption); + } + } + }); +} + +var connectionChart; +var connectionChartOption; + +statusUtil.init_connectionChart= function(){ + + + + connectionChart = echarts.init(document.getElementById('connectionBarChartDiv'), 'macarons'); + + + connectionChartOption = { + + tooltip : { + trigger: 'axis', + axisPointer : { + type : 'shadow' + } + }, + toolbox: { + feature: { + saveAsImage: { + name:'MSB当前连接数统计图' + } + } + }, + legend: { + data:['Active','Waiting','Writing','Reading'] + }, + xAxis: + { + type: 'category', + boundaryGap: true, + name: '采集点', + // axisLabel:{ + // interval:0, + // rotate:45 + // }, + data: [] + }, + yAxis: + { + type: 'value', + scale: true, + name: '连接数', + min: 0, + minInterval: 1, + boundaryGap: [0.1, 0.1] + + }, + series: [ + { + name:'Active', + type:'bar', + data:[] + }, + { + name:'Waiting', + type:'bar', + stack: 'connection', + data:[] + }, + { + name:'Writing', + type:'bar', + stack: 'connection', + data:[] + }, + { + name:'Reading', + type:'bar', + stack: 'connection', + data:[] + } + ] + }; + + // 使用刚指定的配置项和数据显示图表。 + connectionChart.setOption(connectionChartOption); + window.onresize = connectionChart.resize; + + if(statusUtil.connection==true){ + statusUtil.getConnectionChart4Data(); + + setInterval(function () { + statusUtil.getConnectionChart4Data(); + }, statusUtil.connectionsPollTime); + } +} + +statusUtil.getConnectionChart4Data=function(){ +$.ajax({ + "type": 'get', + "async": true, + "url": apiBasePath+"/status/connection", + "dataType": "json", + success: function (resp) { + + if(resp!=null){ + var active_data = connectionChartOption.series[0].data; + var waiting_data = connectionChartOption.series[1].data; + var writing_data = connectionChartOption.series[2].data; + var reading_data = connectionChartOption.series[3].data; + + + if(active_data.length>=statusUtil.connectionsXAxisCount){ + active_data.shift(); + waiting_data.shift(); + writing_data.shift(); + reading_data.shift(); + connectionChartOption.xAxis.data.shift(); + } + + active_data.push(resp.connections_active); + waiting_data.push(resp.connections_waiting); + writing_data.push(resp.connections_writing); + reading_data.push(resp.connections_reading); + + var allValue=active_data.concat(waiting_data).concat(writing_data).concat(reading_data) + var maxVaule=Math.max.apply(null, allValue) + if(maxVaule<5){ + connectionChartOption.yAxis.max=5; + } + else{ + connectionChartOption.yAxis.max=null; + } + + + connectionChartOption.xAxis.data.push(statusUtil.getCurrentTime()); + + connectionChart.setOption(connectionChartOption); + + } + } + }); + +} + + +statusUtil.getCurrentTime=function(){ + var date = new Date(); + var axisData = [statusUtil.addZero(date.getHours()),statusUtil.addZero(date.getMinutes()),statusUtil.addZero(date.getSeconds())].join(":"); + return axisData; + } + +statusUtil.addZero=function(s) { + return s < 10 ? '0' + s: s; + } + + +statusUtil.getLocalTime=function(nS) { + var date = new Date(parseInt(nS)*1000); + var fullDate= [statusUtil.addZero(date.getFullYear()),statusUtil.addZero(date.getMonth() + 1 ) ,statusUtil.addZero(date.getDate())].join("-"); + fullDate+=" "; + fullDate += [statusUtil.addZero(date.getHours()),statusUtil.addZero(date.getMinutes()),statusUtil.addZero(date.getSeconds())].join(":"); + return fullDate; + +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/SyncDataManagerTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/SyncDataManagerTest.java new file mode 100644 index 0000000..668d445 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/SyncDataManagerTest.java @@ -0,0 +1,56 @@ +package org.onap.msb.apiroute; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.msb.apiroute.SyncDataManager; +import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback; +import org.onap.msb.apiroute.wrapper.consulextend.util.Http; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.fasterxml.jackson.core.type.TypeReference; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Http.class }) +@PowerMockIgnore({ "javax.net.ssl.*" }) +public class SyncDataManagerTest { + + @SuppressWarnings("unchecked") + @Before + public void setUpBeforeTest() { + Http http = PowerMockito.mock(Http.class); + + PowerMockito + .doNothing() + .when(http) + .asyncGet(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + PowerMockito + .doNothing() + .when(http) + .asyncGetDelayHandle(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + // + PowerMockito.spy(Http.class); + PowerMockito.when(Http.getInstance()).thenReturn(http); + + } + + @Test + public void testSyncDataManager() + { + SyncDataManager.initSyncTask("127.0.0.1",8500); + SyncDataManager.startWatchService("huangleibo"); + SyncDataManager.resetIndex("huangleibo"); + SyncDataManager.stopWatchService("huangleibo"); + SyncDataManager.stopWatchServiceList(); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ApiRouteHealthCheckTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ApiRouteHealthCheckTest.java new file mode 100644 index 0000000..1048ce0 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ApiRouteHealthCheckTest.java @@ -0,0 +1,69 @@ +package org.onap.msb.apiroute.health; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.msb.apiroute.health.ApiRouteHealthCheck; +import org.onap.msb.apiroute.wrapper.util.HttpClientUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.codahale.metrics.health.HealthCheck.Result; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ HttpClientUtil.class }) +public class ApiRouteHealthCheckTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(ApiRouteHealthCheckTest.class); + + @Test + public void testchecksuccess() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(200); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + ApiRouteHealthCheck check = new ApiRouteHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testchecksuccess health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testchecksuccess health"); + } + } + + @Test + public void testcheckfailed() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(400); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + ApiRouteHealthCheck check = new ApiRouteHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testcheckfailed health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testcheckfailed health"); + } + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheckTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheckTest.java new file mode 100644 index 0000000..50ac829 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/ConsulLinkHealthCheckTest.java @@ -0,0 +1,103 @@ +package org.onap.msb.apiroute.health; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.msb.apiroute.health.ConsulLinkHealthCheck; +import org.onap.msb.apiroute.wrapper.util.HttpClientUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.codahale.metrics.health.HealthCheck.Result; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ HttpClientUtil.class,ConsulLinkHealthCheck.class }) +public class ConsulLinkHealthCheckTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(ConsulLinkHealthCheckTest.class); + + @Test + public void testchecksuccess() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(200); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("CONSUL_IP")).thenReturn("192.168.0.1"); + + ConsulLinkHealthCheck check = new ConsulLinkHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testchecksuccess health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testchecksuccess health"); + } + } + + @Test + public void testcheckfailed() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(400); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("CONSUL_IP")).thenReturn("192.168.0.1"); + + ConsulLinkHealthCheck check = new ConsulLinkHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testcheckfailed health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug("testcheckfailed health"); + } + } + + + @Test + public void testcheckNoENV() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(400); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("CONSUL_IP")).thenReturn(""); + + ConsulLinkHealthCheck check = new ConsulLinkHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testcheckNoENV health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug("testcheckNoENV health"); + } + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/OpenRestyHealthCheckTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/OpenRestyHealthCheckTest.java new file mode 100644 index 0000000..810f645 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/OpenRestyHealthCheckTest.java @@ -0,0 +1,77 @@ +package org.onap.msb.apiroute.health; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.msb.apiroute.health.OpenRestyHealthCheck; +import org.onap.msb.apiroute.wrapper.util.HttpClientUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.codahale.metrics.health.HealthCheck.Result; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ HttpClientUtil.class,OpenRestyHealthCheck.class }) +public class OpenRestyHealthCheckTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(OpenRestyHealthCheckTest.class); + + @Test + public void testchecksuccess() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(200); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("HTTP_OVERWRITE_PORT")).thenReturn("10080"); + + OpenRestyHealthCheck check = new OpenRestyHealthCheck(); + + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testchecksuccess health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testchecksuccess health"); + } + } + + @Test + public void testcheckfailed() + { + PowerMockito.mockStatic(HttpClientUtil.class); + try { + + PowerMockito.when(HttpClientUtil.httpGetStatus(Mockito.anyString())).thenReturn(400); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("HTTP_OVERWRITE_PORT")).thenReturn(""); + + OpenRestyHealthCheck check = new OpenRestyHealthCheck(); + + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testchecksuccess health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testchecksuccess health"); + } + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/RedisHealthCheckTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/RedisHealthCheckTest.java new file mode 100644 index 0000000..a667df2 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/health/RedisHealthCheckTest.java @@ -0,0 +1,77 @@ +package org.onap.msb.apiroute.health; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.health.RedisHealthCheck; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.codahale.metrics.health.HealthCheck.Result; +import com.fiftyonred.mock_jedis.MockJedisPool; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class RedisHealthCheckTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(RedisHealthCheckTest.class); + + @Before + public void setUpBeforeTest() throws Exception { + + } + + @SuppressWarnings("static-access") + @Test + public void testchecksuccess() + { + + try { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + RedisHealthCheck check = new RedisHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testchecksuccess health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug(" testchecksuccess health"); + } + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Test + public void testcheckfailed() + { + RedisHealthCheck check = new RedisHealthCheck(); + Result rst = check.execute(); + + if (!rst.isHealthy()) { + LOGGER.warn("testcheckfailed health check failed:"+rst.getMessage()); + } + else + { + LOGGER.debug("testcheckfailed health"); + } + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapperTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapperTest.java new file mode 100644 index 0000000..bb90a2c --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/ApiRouteServiceWrapperTest.java @@ -0,0 +1,252 @@ +/** + * 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.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.ApiRouteInfo; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException; +import org.onap.msb.apiroute.wrapper.ApiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.RouteUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RouteUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class ApiRouteServiceWrapperTest { + private static ApiRouteServiceWrapper apiRouteServiceWrapper; + private static Comparator apiRouteComparator = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + apiRouteServiceWrapper=ApiRouteServiceWrapper.getInstance(); + apiRouteComparator = new Comparator() { + @Override + public int compare(ApiRouteInfo o1, ApiRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + if (!o1.getVersion().equals(o2.getVersion())) + return (o1.getVersion()).compareTo(o2.getVersion()); + return 0; + } + }; + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn(null); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn("ip|domain"); + ConfigUtil.getInstance().initRouteWay(); + } + + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + + + @Test + public void test_getApiRouteInstance_not_exist(){ + try { + apiRouteServiceWrapper.getApiRouteInstance("testForJunit", "v1","","","ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_getApiRouteInstance(){ + + ApiRouteInfo apirouteInfo = buildApiRouteInfo(); + try { + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo, "ip"); + ApiRouteInfo dbApirouteInfo=apiRouteServiceWrapper.getApiRouteInstance("testapi", "v1", "", "", "ip"); + Assert.assertEquals(apirouteInfo,dbApirouteInfo ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + + @Test + public void test_getAllApiRouteInstances(){ + ApiRouteInfo apirouteInfo = buildApiRouteInfo(); + ApiRouteInfo apirouteInfo2 = buildApiRouteInfo2(); + List expected = new ArrayList<>(); + expected.add(apirouteInfo); + expected.add(apirouteInfo2); + Collections.sort(expected, apiRouteComparator); + + try { + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo, "ip"); + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo2, "ip"); + + + PowerMockito.mockStatic(RouteUtil.class); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.APIROUTE, "ip")).thenReturn("msb:routing:api:*"); + List apiRouterList=apiRouteServiceWrapper.getAllApiRouteInstances("ip"); + Collections.sort(apiRouterList, apiRouteComparator); + + Assert.assertEquals(expected,apiRouterList); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_updateApiRouteStatus(){ + ApiRouteInfo apirouteInfo = buildApiRouteInfo(); + try { + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo, "ip"); + ApiRouteInfo dbApirouteInfo=apiRouteServiceWrapper.getApiRouteInstance("testapi", "v1", "", "", "ip"); + Assert.assertEquals("1",dbApirouteInfo.getStatus() ); + apiRouteServiceWrapper.updateApiRouteStatus("testapi","v1","","","0", "ip"); + dbApirouteInfo=apiRouteServiceWrapper.getApiRouteInstance("testapi", "v1", "", "", "ip"); + Assert.assertEquals("0",dbApirouteInfo.getStatus() ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + + @Test + public void test_deleteApiRoute(){ + ApiRouteInfo apirouteInfo2 = buildApiRouteInfo2(); + try { + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo2, "ip"); + ApiRouteInfo dbApirouteInfo=apiRouteServiceWrapper.getApiRouteInstance("testapi2", "null","","","ip"); + Assert.assertNotNull(dbApirouteInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + try { + apiRouteServiceWrapper.deleteApiRoute("testapi2", "null","","","ip"); + apiRouteServiceWrapper.getApiRouteInstance("testapi2", "","","","ip"); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + } + + @Test + public void test_getAllApiDocs(){ + String[] paths=apiRouteServiceWrapper.getAllApiDocs(); + String[] expecteds_paths={"api-doc1.json","api-doc2.json"}; + Arrays.sort(expecteds_paths); + Arrays.sort(paths); + Assert.assertArrayEquals(expecteds_paths, paths); + } + + @Test + public void test_getAllrouteByJson(){ + ApiRouteInfo apirouteInfo = buildApiRouteInfo(); + try { + apiRouteServiceWrapper.saveApiRouteInstance4Rest(apirouteInfo, "ip"); + + ApiRouteInfo[] apirouteList={apirouteInfo}; + String expected_routeJson=JacksonJsonUtil.beanToJson(apirouteList); + + PowerMockito.mockStatic(RouteUtil.class); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.APIROUTE, "ip")).thenReturn("msb:routing:api:*"); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.IUIROUTE, "ip")).thenReturn("msb:routing:iui:*"); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.CUSTOMROUTE, "ip")).thenReturn("msb:routing:custom:*"); + + String allrouteJson= apiRouteServiceWrapper.getAllrouteByJson("ip"); + Assert.assertEquals(expected_routeJson, allrouteJson); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + + } + + + + private ApiRouteInfo buildApiRouteInfo(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + apirouteInfo.setServers(servers); + return apirouteInfo; + } + + private ApiRouteInfo buildApiRouteInfo2(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi2"); + apirouteInfo.setVersion(""); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi2/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("1"); + apirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.89","8080")}; + apirouteInfo.setServers(servers); + return apirouteInfo; + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapperTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapperTest.java new file mode 100644 index 0000000..3c77dbf --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/CustomRouteServiceWrapperTest.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; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.CustomRouteInfo; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException; +import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.RouteUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RouteUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class CustomRouteServiceWrapperTest { + + private static CustomRouteServiceWrapper customRouteServiceWrapper; + private static Comparator customRouteComparator = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + customRouteServiceWrapper=CustomRouteServiceWrapper.getInstance(); + customRouteComparator = new Comparator() { + @Override + public int compare(CustomRouteInfo o1, CustomRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + return 0; + } + }; + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn(null); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn("ip|domain"); + ConfigUtil.getInstance().initRouteWay(); + } + + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + @Test + public void test_getCustomRouteInstance_not_exist(){ + try { + customRouteServiceWrapper.getCustomRouteInstance("/testForJunit","","","ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + + } + + } + + @Test + public void test_getCustomRouteInstance(){ + + CustomRouteInfo customrouteInfo = buildCustomRouteInfo(); + try { + customRouteServiceWrapper.saveCustomRouteInstance4Rest(customrouteInfo, "ip"); + CustomRouteInfo dbCustomRouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/testcustom", "", "", "ip"); + Assert.assertEquals(customrouteInfo,dbCustomRouteInfo ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_getAllCustomRouteInstances(){ + CustomRouteInfo customrouteInfo = buildCustomRouteInfo(); + CustomRouteInfo customrouteInfo2 = buildCustomRouteInfo2(); + List expected = new ArrayList<>(); + expected.add(customrouteInfo); + expected.add(customrouteInfo2); + Collections.sort(expected, customRouteComparator); + + try { + customRouteServiceWrapper.saveCustomRouteInstance4Rest(customrouteInfo, "ip"); + customRouteServiceWrapper.saveCustomRouteInstance4Rest(customrouteInfo2, "ip"); + + PowerMockito.mockStatic(RouteUtil.class); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.CUSTOMROUTE, "ip")).thenReturn("msb:routing:custom:*"); + List customRouterList=customRouteServiceWrapper.getAllCustomRouteInstances("ip"); + Collections.sort(customRouterList, customRouteComparator); + + Assert.assertEquals(expected,customRouterList); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_updateCustomRouteStatus(){ + CustomRouteInfo customrouteInfo = buildCustomRouteInfo(); + try { + customRouteServiceWrapper.saveCustomRouteInstance4Rest(customrouteInfo, "ip"); + CustomRouteInfo dbCustomrouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/testcustom", "", "", "ip"); + Assert.assertEquals("1",dbCustomrouteInfo.getStatus() ); + customRouteServiceWrapper.updateCustomRouteStatus("/testcustom","","","0", "ip"); + dbCustomrouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/testcustom", "", "", "ip"); + Assert.assertEquals("0",dbCustomrouteInfo.getStatus() ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + + @Test + public void test_deleteCustomRoute(){ + CustomRouteInfo customrouteInfo2 = buildCustomRouteInfo2(); + try { + customRouteServiceWrapper.saveCustomRouteInstance4Rest(customrouteInfo2, "ip"); + CustomRouteInfo dbCustomrouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/testcustom2","","","ip"); + Assert.assertNotNull(dbCustomrouteInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + try { + customRouteServiceWrapper.deleteCustomRoute("/testcustom2","","","ip"); + customRouteServiceWrapper.getCustomRouteInstance("/testcustom2","","","ip"); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + } + + + private CustomRouteInfo buildCustomRouteInfo(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("/testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + return customrouteInfo; + } + + private CustomRouteInfo buildCustomRouteInfo2(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("/testcustom2"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("1"); + customrouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.89","8080")}; + customrouteInfo.setServers(servers); + return customrouteInfo; + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapperTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapperTest.java new file mode 100644 index 0000000..7c183dd --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/InitRouteServiceWrapperTest.java @@ -0,0 +1,241 @@ +package org.onap.msb.apiroute.wrapper; + +import io.dropwizard.jetty.HttpConnectorFactory; +import io.dropwizard.server.SimpleServerFactory; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.msb.apiroute.ApiRouteAppConfig; +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.wrapper.ApiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.IuiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback; +import org.onap.msb.apiroute.wrapper.consulextend.util.Http; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fiftyonred.mock_jedis.MockJedisPool; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ JedisUtil.class, RedisAccessWrapper.class, ConfigUtil.class, + Http.class, InitRouteServiceWrapper.class }) +@PowerMockIgnore({ "javax.management.*", "javax.net.ssl.*" }) +public class InitRouteServiceWrapperTest { + private static InitRouteServiceWrapper initRouteServiceWrapper; + private static Consul consul; + + @SuppressWarnings("unchecked") + @BeforeClass + public static void setUpBeforeClass() throws Exception { + initRouteServiceWrapper = InitRouteServiceWrapper.getInstance(); + + Http http = PowerMockito.mock(Http.class); + + PowerMockito + .doNothing() + .when(http) + .asyncGet(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + PowerMockito + .doNothing() + .when(http) + .asyncGetDelayHandle(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + PowerMockito.spy(Http.class); + PowerMockito.when(Http.getInstance()).thenReturn(http); + + consul = Consul.builder().withHostAndPort("127.0.0.1", 8500).build(); + } + + @Before + public void initReidsMock() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool( + new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil = PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn( + mockJedisPool.getResource()); + + PowerMockito.replace( + PowerMockito.method(RedisAccessWrapper.class, "filterKeys")) + .with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, + Object[] args) throws Throwable { + return mockJedisPool.getResource().keys( + (String) args[0]); + } + }); + } + + @Test + public void test_startCheckRedisConnect() { + try { + boolean ifRedisConnect = initRouteServiceWrapper + .startCheckRedisConnect(); + Assert.assertEquals(true, ifRedisConnect); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + + } + } + + @Test + public void test_runConsulClientApp() { + + DiscoverInfo discoverInfo = new DiscoverInfo(); + discoverInfo.setEnabled(true); + discoverInfo.setIp("127.0.0.1"); + discoverInfo.setPort(10081); + + ApiRouteAppConfig configuration = new ApiRouteAppConfig(); + configuration.setDiscoverInfo(discoverInfo); + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("SDCLIENT_IP")).thenReturn("127.0.0.1"); + ConfigUtil.getInstance().initDiscoverInfo(configuration); + + try { + initRouteServiceWrapper.runConsulClientApp(); + + 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); + + ApiRouteInfo db_discoverApiService = ApiRouteServiceWrapper + .getInstance().getApiRouteInstance("msdiscover", "v1", + "msb", "", "ip"); + Assert.assertEquals(discoverApiService, db_discoverApiService); + + IuiRouteInfo discoverIUIService = new IuiRouteInfo(); + discoverIUIService.setServiceName("msdiscover"); + discoverIUIService.setUrl("/iui/microservices"); + discoverIUIService.setHost("msb"); + discoverIUIService.setServers(servers); + + Assert.assertEquals( + discoverIUIService, + IuiRouteServiceWrapper.getInstance().getIuiRouteInstance( + "msdiscover", "msb", "", "ip")); + + } catch (Exception e) { + assert false : "throw exception means error occured!" + + e.getMessage(); + } + } + + @Test + public void test_initRouteInfoFromJson() { + try { + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("dwApp_server_connector_port")) + .thenReturn("8068"); + initRouteServiceWrapper.initRouteInfoFromJson(); + + ApiRouteInfo apiroute = new ApiRouteInfo(); + apiroute.setServiceName("microservices"); + apiroute.setUrl("/api/microservices/v1"); + apiroute.setVersion("v1"); + apiroute.setMetricsUrl("/admin/metrics"); + apiroute.setApiJson("/api/microservices/v1/swagger.json"); + apiroute.setHost("msb"); + apiroute.setControl("1"); + apiroute.setStatus("1"); + + RouteServer[] servers = new RouteServer[1]; + servers[0] = new RouteServer("127.0.0.1", "8068"); + apiroute.setServers(servers); + + ApiRouteInfo db_apiService = ApiRouteServiceWrapper + .getInstance() + .getApiRouteInstance("microservices", "v1", "msb", "", "ip"); + Assert.assertEquals(apiroute, db_apiService); + + IuiRouteInfo iuiRoute = new IuiRouteInfo(); + iuiRoute.setServiceName("microservices"); + iuiRoute.setUrl("/iui/microservices"); + iuiRoute.setHost("msb"); + iuiRoute.setControl("1"); + iuiRoute.setStatus("1"); + iuiRoute.setServers(servers); + + Assert.assertEquals(iuiRoute, IuiRouteServiceWrapper.getInstance() + .getIuiRouteInstance("microservices", "msb", "", "ip")); + + CustomRouteInfo customRoute = new CustomRouteInfo(); + customRoute.setServiceName("/custom"); + customRoute.setUrl("/custom"); + customRoute.setHost("msb"); + customRoute.setControl("1"); + customRoute.setStatus("1"); + RouteServer[] servers2 = new RouteServer[1]; + servers2[0] = new RouteServer("127.0.0.1", "8066"); + customRoute.setServers(servers2); + + Assert.assertEquals(customRoute, + CustomRouteServiceWrapper.getInstance() + .getCustomRouteInstance("/custom", "msb", "", "ip")); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + } + + @Test + public void test_initMetricsConfig() { + ApiRouteAppConfig configuration = new ApiRouteAppConfig(); + SimpleServerFactory simpleServerFactory = new SimpleServerFactory(); + HttpConnectorFactory httpConnectorFactory = new HttpConnectorFactory(); + httpConnectorFactory.setPort(8888); + simpleServerFactory.setConnector(httpConnectorFactory); + simpleServerFactory.setAdminContextPath("/admin"); + + configuration.setServerFactory(simpleServerFactory); + + initRouteServiceWrapper.initMetricsConfig(configuration); + + Assert.assertEquals("http://127.0.0.1:8888/admin/metrics", ConfigUtil + .getInstance().getMetricsUrl()); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapperTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapperTest.java new file mode 100644 index 0000000..7451e9b --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/IuiRouteServiceWrapperTest.java @@ -0,0 +1,212 @@ +/** + * 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.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +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.wrapper.IuiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.RouteUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RouteUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class IuiRouteServiceWrapperTest { + private static IuiRouteServiceWrapper iuiRouteServiceWrapper; + private static Comparator iuiRouteComparator = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + iuiRouteServiceWrapper=IuiRouteServiceWrapper.getInstance(); + iuiRouteComparator = new Comparator() { + @Override + public int compare(IuiRouteInfo o1, IuiRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + return 0; + } + }; + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn(null); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn("ip|domain"); + ConfigUtil.getInstance().initRouteWay(); + } + + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + + @Test + public void test_getIuiRouteInstance_not_exist(){ + try { + iuiRouteServiceWrapper.getIuiRouteInstance("testForJunit","","","ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + + } + + } + + @Test + public void test_getIuiRouteInstance(){ + + IuiRouteInfo iuirouteInfo = buildIuiRouteInfo(); + try { + iuiRouteServiceWrapper.saveIuiRouteInstance4Rest(iuirouteInfo, "ip"); + IuiRouteInfo dbIuiRouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("testiui", "", "", "ip"); + Assert.assertEquals(iuirouteInfo,dbIuiRouteInfo ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_getAllIuiRouteInstances(){ + IuiRouteInfo iuirouteInfo = buildIuiRouteInfo(); + IuiRouteInfo iuirouteInfo2 = buildIuiRouteInfo2(); + List expected = new ArrayList<>(); + expected.add(iuirouteInfo); + expected.add(iuirouteInfo2); + Collections.sort(expected, iuiRouteComparator); + + try { + iuiRouteServiceWrapper.saveIuiRouteInstance4Rest(iuirouteInfo, "ip"); + iuiRouteServiceWrapper.saveIuiRouteInstance4Rest(iuirouteInfo2, "ip"); + + + + PowerMockito.mockStatic(RouteUtil.class); + PowerMockito.when(RouteUtil.getMutiRedisKey(RouteUtil.IUIROUTE, "ip")).thenReturn("msb:routing:iui:*"); + List iuiRouterList=iuiRouteServiceWrapper.getAllIuiRouteInstances("ip"); + Collections.sort(iuiRouterList, iuiRouteComparator); + + Assert.assertEquals(expected,iuiRouterList); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_updateIuiRouteStatus(){ + IuiRouteInfo iuirouteInfo = buildIuiRouteInfo(); + try { + iuiRouteServiceWrapper.saveIuiRouteInstance4Rest(iuirouteInfo, "ip"); + IuiRouteInfo dbIuirouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("testiui", "", "", "ip"); + Assert.assertEquals("1",dbIuirouteInfo.getStatus() ); + iuiRouteServiceWrapper.updateIuiRouteStatus("testiui","","","0", "ip"); + dbIuirouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("testiui", "", "", "ip"); + Assert.assertEquals("0",dbIuirouteInfo.getStatus() ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + + @Test + public void test_deleteIuiRoute(){ + IuiRouteInfo iuirouteInfo2 = buildIuiRouteInfo2(); + try { + iuiRouteServiceWrapper.saveIuiRouteInstance4Rest(iuirouteInfo2, "ip"); + IuiRouteInfo dbIuirouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("testiui2","","","ip"); + Assert.assertNotNull(dbIuirouteInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + try { + iuiRouteServiceWrapper.deleteIuiRoute("testiui2","","","ip"); + iuiRouteServiceWrapper.getIuiRouteInstance("testiui2","","","ip"); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + } + + + private IuiRouteInfo buildIuiRouteInfo(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + iuirouteInfo.setServers(servers); + return iuirouteInfo; + } + + private IuiRouteInfo buildIuiRouteInfo2(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui2"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("1"); + iuirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.89","8080")}; + iuirouteInfo.setServers(servers); + return iuirouteInfo; + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapperTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapperTest.java new file mode 100644 index 0000000..d830397 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/MicroServiceWrapperTest.java @@ -0,0 +1,294 @@ +package org.onap.msb.apiroute.wrapper; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.MicroServiceFullInfo; +import org.onap.msb.apiroute.api.Node; +import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException; +import org.onap.msb.apiroute.api.exception.UnprocessableEntityException; +import org.onap.msb.apiroute.wrapper.MicroServiceWrapper; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class MicroServiceWrapperTest { + private static MicroServiceWrapper microServiceWrapper; + private static Comparator microServiceComparator = null; + + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + microServiceWrapper=MicroServiceWrapper.getInstance(); + microServiceComparator = new Comparator() { + @Override + public int compare(MicroServiceFullInfo o1, MicroServiceFullInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + return 0; + } + }; + } + + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + @Test + public void test_getMicroServiceFullInfo_not_exist(){ + try { + microServiceWrapper.getMicroServiceInstance("testForJunit","v1"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + + } + + } + + @Test + public void test_getMicroServiceFullInfo(){ + + MicroServiceFullInfo microServiceFullInfo = buildMicroServiceFullInfo(); + try { + microServiceWrapper.saveMicroServiceInstance(microServiceFullInfo, false, "", ""); + MicroServiceFullInfo dbMicroServiceFullInfo=microServiceWrapper.getMicroServiceInstance("testService", "v1"); + Assert.assertEquals(microServiceFullInfo,dbMicroServiceFullInfo ); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + + } + + @Test + public void test_getAllMicroServiceInstances(){ + MicroServiceFullInfo microService = buildMicroServiceFullInfo(); + MicroServiceFullInfo microService2 = buildMicroServiceFullInfo2(); + List expected = new ArrayList<>(); + expected.add(microService); + expected.add(microService2); + Collections.sort(expected, microServiceComparator); + + try { + microServiceWrapper.saveMicroServiceInstance(microService, false, "", ""); + microServiceWrapper.saveMicroServiceInstance(microService2, false, "", ""); + + List microServiceList=microServiceWrapper.getAllMicroServiceInstances(); + Collections.sort(microServiceList, microServiceComparator); + + Assert.assertEquals(expected,microServiceList); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + @Test + public void test_updateMicroServiceStatus(){ + MicroServiceFullInfo microService = buildMicroServiceFullInfo(); + + try { + microServiceWrapper.saveMicroServiceInstance(microService, false, "", ""); + MicroServiceFullInfo dbMicroServiceFullInfo=microServiceWrapper.getMicroServiceInstance("testService", "v1"); + Assert.assertEquals("1",dbMicroServiceFullInfo.getStatus() ); + microServiceWrapper.updateMicroServiceStatus("testService","v1","0"); + dbMicroServiceFullInfo=microServiceWrapper.getMicroServiceInstance("testService", "v1"); + Assert.assertEquals("0",dbMicroServiceFullInfo.getStatus() ); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + + @Test + public void test_deleteMicroService(){ + MicroServiceFullInfo microService = buildMicroServiceFullInfo2(); + try { + microServiceWrapper.saveMicroServiceInstance(microService, false, "", ""); + MicroServiceFullInfo dbMicroServiceFullInfo=microServiceWrapper.getMicroServiceInstance("testService2", "v1"); + Assert.assertNotNull(dbMicroServiceFullInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + try { + microServiceWrapper.deleteMicroService("testService2","v1"); + microServiceWrapper.getMicroServiceInstance("testService2", "v1"); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + } + + @Test + public void test_deleteMicroServiceInstance(){ + + + //添加多版本服务 + MicroServiceFullInfo microService4v2 = buildMicroServiceFullInfo4version2(); + try { + microServiceWrapper.saveMicroServiceInstance(microService4v2, false, "", ""); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + //删除不存在实例 + try { + microServiceWrapper.deleteMicroServiceInstance("testService","v2","127.0.0.1","8989"); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + //删除其中一个实例 + microServiceWrapper.deleteMicroServiceInstance("testService","v2","10.74.148.87","8080"); + MicroServiceFullInfo microService =microServiceWrapper.getMicroServiceInstance("testService", "v2"); + + Set nodeSet=new HashSet(); + nodeSet.add(new Node("10.74.148.86","8080")); + Assert.assertEquals(nodeSet, microService.getNodes()); + + //删除服务 + microServiceWrapper.deleteMicroServiceInstance("testService","v2","10.74.148.86","8080"); + } + catch(Exception e){ + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + microServiceWrapper.getMicroServiceInstance("testService","v2"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + + } + } + + @Test + public void test_getAllVersion(){ + try { + microServiceWrapper.saveMicroServiceInstance(buildMicroServiceFullInfo(), false, "", ""); + microServiceWrapper.saveMicroServiceInstance(buildMicroServiceFullInfo4version2(), false, "", ""); + Set versionSet=new HashSet(); + versionSet.add("v1"); + versionSet.add("v2"); + Assert.assertEquals(versionSet,microServiceWrapper.getAllVersion("testService")); + + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + try { + microServiceWrapper.deleteMicroService4AllVersion("testService"); + Assert.assertEquals(0,microServiceWrapper.getAllVersion("testService").size()); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + + } + + } + + @Test + public void test_getAllMicroServiceKey(){ + microServiceWrapper.saveMicroServiceInstance(buildMicroServiceFullInfo(), false, "", ""); + microServiceWrapper.saveMicroServiceInstance(buildMicroServiceFullInfo2(), false, "", ""); + Set builder = new HashSet(); + builder.add("testService"); + builder.add("testService2"); + Assert.assertEquals(builder,microServiceWrapper.getAllMicroServiceKey()); + + + } + + private MicroServiceFullInfo buildMicroServiceFullInfo(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("HTTP"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + + return microServiceFullInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4version2(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v2"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("HTTP"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.87","8080")); + nodeSet.add(new Node("10.74.148.86","8080")); + microServiceFullInfo.setNodes(nodeSet); + + return microServiceFullInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo2(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService2"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/api/testService/v1"); + microServiceFullInfo.setVisualRange("1"); + microServiceFullInfo.setProtocol("REST"); + microServiceFullInfo.setEnable_ssl(true); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.89","8080")); + microServiceFullInfo.setNodes(nodeSet); + + return microServiceFullInfo; + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/ConsulTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/ConsulTest.java new file mode 100644 index 0000000..abf5e09 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/ConsulTest.java @@ -0,0 +1,149 @@ +package org.onap.msb.apiroute.wrapper.consulextend; + +import java.util.List; + +import org.apache.http.HttpEntity; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.msb.apiroute.wrapper.consulextend.CatalogClient; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.HealthClient; +import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback; +import org.onap.msb.apiroute.wrapper.consulextend.async.OriginalConsulResponse; +import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth; +import org.onap.msb.apiroute.wrapper.consulextend.util.Http; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.option.CatalogOptions; +import com.orbitz.consul.option.QueryOptions; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Http.class }) +@PowerMockIgnore({ "javax.net.ssl.*" }) +public class ConsulTest { + private static Consul consul10081; + private static Consul consul8500; + + private static final Logger LOGGER = LoggerFactory + .getLogger(ConsulTest.class); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @BeforeClass + public static void setUpBeforeClass() throws Exception { + + Http http = PowerMockito.mock(Http.class); + + PowerMockito + .doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + ((ConsulResponseCallback) args[2]).onComplete(null); + return null; + } + }) + .when(http) + .asyncGet(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + // + PowerMockito.spy(Http.class); + PowerMockito.when(Http.getInstance()).thenReturn(http); + + // + consul10081 = Consul.builder().withHostAndPort("10.74.148.111", 10081) + .build(); + consul8500 = Consul.builder().withHostAndPort("10.74.148.111", 8500) + .build(); + } + + @Test + public void testcatalogClient() { + + ConsulResponseCallback callback = new ConsulResponseCallback() { + + @Override + public void onComplete( + ConsulResponse consulResponse) { + LOGGER.info("service list complete!"); + } + + @Override + public void onFailure(Throwable throwable) { + LOGGER.info("service list failure!"); + } + + @Override + public void onDelayComplete( + OriginalConsulResponse originalConsulResponse) { + // TODO Auto-generated method stub + LOGGER.info("service list complete!"); + } + + }; + + // 10081 + CatalogClient catalogclient10081 = consul10081.catalogClient(); + catalogclient10081.getServices(CatalogOptions.BLANK, QueryOptions.BLANK, callback); + + // 8500 + CatalogClient catalogclient8500 = consul8500.catalogClient(); + catalogclient8500.getServices(CatalogOptions.BLANK, QueryOptions.BLANK, callback); + } + + @Test + public void testhealthClient() { + + ConsulResponseCallback> callback = new ConsulResponseCallback>() { + + @Override + public void onComplete( + ConsulResponse> consulResponse) { + LOGGER.info("health service complete!"); + + } + + @Override + public void onFailure(Throwable throwable) { + LOGGER.info("health service failure!"); + } + + @Override + public void onDelayComplete( + OriginalConsulResponse> originalConsulResponse) { + // TODO Auto-generated method stub + LOGGER.info("health service complete!"); + } + + }; + + // 10081 + HealthClient healthClient10081 = consul10081.healthClient(); + healthClient10081.getAllServiceInstances("apigateway-default", CatalogOptions.BLANK, + QueryOptions.BLANK, callback); + + healthClient10081.getHealthyServiceInstances("apigateway-default", + CatalogOptions.BLANK, QueryOptions.BLANK, callback); + + // 8500 + HealthClient healthClient8500 = consul8500.healthClient(); + healthClient8500.getAllServiceInstances("apigateway-default", CatalogOptions.BLANK, + QueryOptions.BLANK, callback); + healthClient8500.getHealthyServiceInstances("apigateway-default", CatalogOptions.BLANK, + QueryOptions.BLANK, callback); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCacheTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCacheTest.java new file mode 100644 index 0000000..03cc209 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServiceHealthCacheTest.java @@ -0,0 +1,24 @@ +package org.onap.msb.apiroute.wrapper.consulextend.cache; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.cache.ServiceHealthCache; + +import com.orbitz.consul.option.CatalogOptions; + +public class ServiceHealthCacheTest { + + @Test + public void testnewCache() { + Consul consul = Consul.newClient(); + ServiceHealthCache cache1 = ServiceHealthCache.newCache( + consul.healthClient(), "huangleibo"); + Assert.assertNotNull(cache1); + + ServiceHealthCache cache2 = ServiceHealthCache.newCache( + consul.healthClient(), "huangleibo", false, + CatalogOptions.BLANK, 10); + Assert.assertNotNull(cache2); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCacheTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCacheTest.java new file mode 100644 index 0000000..7518ad7 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/cache/ServicesCatalogCacheTest.java @@ -0,0 +1,15 @@ +package org.onap.msb.apiroute.wrapper.consulextend.cache; + +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.cache.ServicesCatalogCache; + +public class ServicesCatalogCacheTest { + + @Test + public void testnewCache() + { + Consul consul = Consul.newClient(); + ServicesCatalogCache cache = ServicesCatalogCache.newCache(consul.catalogClient()); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilterTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilterTest.java new file mode 100644 index 0000000..9b9dd17 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckServiceDataEmptyAndAutoStopWatchFilterTest.java @@ -0,0 +1,53 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + + + + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.expose.CheckServiceDataEmptyAndAutoStopWatchFilter; +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.util.RouteUtil; + +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.model.health.ImmutableNode; + +public class CheckServiceDataEmptyAndAutoStopWatchFilterTest { + @Test + public void testfilter() + { + + + CheckServiceDataEmptyAndAutoStopWatchFilter filter = new CheckServiceDataEmptyAndAutoStopWatchFilter("huangleibo"); + + + List list = new ArrayList(); + + //id:huangleibo1,name:huangleibo,modifyIndex:1,createindex:1 + Service service0 = ImmutableService.builder().id("huangleibo1").port(0).address("") + .service("huangleibo").addTags("").createIndex(1).modifyIndex(1).build(); + ServiceHealth serviceHealth0 = ImmutableServiceHealth.builder() + .service(service0) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + + list.add(serviceHealth0); + ConsulResponse> object = new ConsulResponse>(list,1,true, BigInteger.valueOf(1)); + + //have service,return true + Assert.assertTrue(filter.filter(object)); + + //empty [],return false + list.clear(); + Assert.assertFalse(filter.filter(object)); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilterTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilterTest.java new file mode 100644 index 0000000..bd9fe3a --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/CheckTagAndAutoStopWatchFilterTest.java @@ -0,0 +1,70 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.expose.CheckTagAndAutoStopWatchFilter; +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.util.RouteUtil; + +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.model.health.ImmutableNode; + +public class CheckTagAndAutoStopWatchFilterTest { + + @Test + public void testfilter() { + + CheckTagAndAutoStopWatchFilter filter = new CheckTagAndAutoStopWatchFilter("huangleibo"); + + + List list = new ArrayList(); + + //visual range:0,tags meet conditions + List tags = new ArrayList(); + tags.add("\"base\":{\"protocol\":\"REST\",\"is_manual\":\"true\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tags.add("\"ns\":{\"namespace\":\"nsName\"}"); + tags.add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + + Service service0 = ImmutableService.builder().id("huangleibo1").port(0) + .address("").service("huangleibo").tags(tags).createIndex(1) + .modifyIndex(1).build(); + ServiceHealth serviceHealth0 = ImmutableServiceHealth.builder() + .service(service0) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + + list.add(serviceHealth0); + ConsulResponse> object = new ConsulResponse>(list,1,true,BigInteger.valueOf(1)); + + //visual range:0,tags meet conditions,return true + Assert.assertTrue(filter.filter(object)); + + //visual range:1,tags don't meet conditions + List tags1 = new ArrayList(); + tags1.add("\"base\":{\"protocol\":\"REST\",\"is_manual\":\"true\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tags1.add("\"ns\":{\"namespace\":\"nsName\"}"); + tags1.add("\"labels\":{\"visualRange\":\"1\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + + Service service1 = ImmutableService.builder().id("huangleibo1").port(0) + .address("").service("huangleibo").tags(tags1).createIndex(1) + .modifyIndex(1).build(); + ServiceHealth serviceHealth1 = ImmutableServiceHealth.builder() + .service(service1) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + list.clear(); + list.add(serviceHealth1); + + //visual range:1,tags don't meet conditions,return false + Assert.assertFalse(filter.filter(object)); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilterTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilterTest.java new file mode 100644 index 0000000..51dfa49 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ConsulIndexFilterTest.java @@ -0,0 +1,42 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.expose.ConsulIndexFilter; + +import com.orbitz.consul.model.ConsulResponse; + +public class ConsulIndexFilterTest { + @BeforeClass + public static void setUpBeforeClass() throws Exception { + + } + + @Test + public void testfilter() + { + ConsulIndexFilter filter = new ConsulIndexFilter(); + + int response = 1; + long lastContact= 1; + boolean knownLeader = true; + + ConsulResponse object = new ConsulResponse(response,lastContact,knownLeader,BigInteger.valueOf(1)); + + //index 1;the first time,return true + Assert.assertTrue(filter.filter(object)); + + + //index 1;same index,return false + Assert.assertFalse(filter.filter(object)); + + ConsulResponse object1 = new ConsulResponse(response,lastContact,knownLeader,BigInteger.valueOf(2)); + + //index 2;different index,return true + Assert.assertTrue(filter.filter(object1)); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilterTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilterTest.java new file mode 100644 index 0000000..bc01589 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/ServiceModifyIndexFilterTest.java @@ -0,0 +1,114 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.expose.ServiceModifyIndexFilter; +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 com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.model.health.ImmutableNode; + +public class ServiceModifyIndexFilterTest { + + @Test + public void testfilter() + { + ServiceModifyIndexFilter filter = new ServiceModifyIndexFilter(); + + + List list0 = new ArrayList(); + + //id:huangleibo1,name:huangleibo,modifyIndex:1,createIndex:1 + Service service0 = ImmutableService.builder().id("huangleibo1").port(0).address("") + .service("huangleibo").addTags("").createIndex(1).modifyIndex(1).build(); + ServiceHealth serviceHealth0 = ImmutableServiceHealth.builder() + .service(service0) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + list0.add(serviceHealth0); + + ConsulResponse> object0 = new ConsulResponse>(list0,1,true,BigInteger.valueOf(1)); + + //list-size:1,id:huangleibo1,name:huangleibo,modifyIndex:1;the first time:return true + Assert.assertTrue(filter.filter(object0)); + + //list-size:1,id:huangleibo1,name:huangleibo,modifyIndex:1;same index:return false + Assert.assertFalse(filter.filter(object0)); + + ///////////////////////////////////////////////////////////////////////////////// + + List list1 = new ArrayList(); + + //id:huangleibo2,name:huangleibo,modifyIndex:1,createIndex:1 + Service service1 = ImmutableService.builder().id("huangleibo2").port(0).address("") + .service("huangleibo").addTags("").createIndex(1).modifyIndex(1).build(); + ServiceHealth serviceHealth1 = ImmutableServiceHealth.builder() + .service(service1) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + + list1.add(serviceHealth0); + list1.add(serviceHealth1); + + ConsulResponse> object1 = new ConsulResponse>(list1,1,true,BigInteger.valueOf(1)); + + //list-size:2, + //id:huangleibo1,name:huangleibo,modifyIndex:1,createIndex:1 + //id:huangleibo2,name:huangleibo,modifyIndex:1,createIndex:1 + //size different,return true + Assert.assertTrue(filter.filter(object1)); + + ////////////////////////////////////////////////////////////////////////// + List list2 = new ArrayList(); + + //id:huangleibo3,name:huangleibo,modifyIndex:1,createIndex:1 + ImmutableService service2 = ImmutableService.builder().id("huangleibo3").port(0).address("") + .service("huangleibo").addTags("").createIndex(1).modifyIndex(1).build(); + ServiceHealth serviceHealth2 = ImmutableServiceHealth.builder() + .service(service2) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + list2.add(serviceHealth0); + list2.add(serviceHealth2); + + ConsulResponse> object2 = new ConsulResponse>(list2,1,true,BigInteger.valueOf(1)); + + //list-size:2, + //id:huangleibo1,name:huangleibo,modifyIndex:1,createIndex:1 + //id:huangleibo3,name:huangleibo,modifyIndex:1,createIndex:1 + //instance id different,return true + Assert.assertTrue(filter.filter(object2)); + + + ////////////////////////////////////////////////////////////////////////// + List list3 = new ArrayList(); + + //edit modifyindex 1 to 2 + Service service3 = service2.withModifyIndex(2); + ServiceHealth serviceHealth3 = ImmutableServiceHealth.builder() + .service(service3) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + list3.add(serviceHealth0); + list3.add(serviceHealth3); + + ConsulResponse> object3 = new ConsulResponse>(list3,1,true,BigInteger.valueOf(1)); + + //list-size:2, + //id:huangleibo1,name:huangleibo,modifyIndex:1,createIndex:1 + //id:huangleibo3,name:huangleibo,modifyIndex:2,createIndex:1 + //modifyIndex different,return true + Assert.assertTrue(filter.filter(object3)); + + //the same content,return false + Assert.assertFalse(filter.filter(object3)); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTaskTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTaskTest.java new file mode 100644 index 0000000..14455ee --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchCatalogServicesTaskTest.java @@ -0,0 +1,138 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchCatalogServicesTask; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchTask; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchTask.Filter; +import org.onap.msb.apiroute.wrapper.consulextend.util.Http; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.option.CatalogOptions; +import com.orbitz.consul.option.QueryOptions; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Http.class }) +@PowerMockIgnore({ "javax.net.ssl.*" }) +public class WatchCatalogServicesTaskTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(WatchCatalogServicesTaskTest.class); + + private Consul consul; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Before + public void init() { + + Map> catalogservices = new HashMap>(); + String servicename = "huangleibo"; + List tags = new ArrayList(); + tags.add("1111"); + tags.add("2222"); + catalogservices.put(servicename, tags); + + long lastContact = 1; + boolean knownLeader = true; + BigInteger index = BigInteger.valueOf(1); + final ConsulResponse>> response = new ConsulResponse>>( + catalogservices, lastContact, knownLeader, index); + + // + Http http = PowerMockito.mock(Http.class); + + PowerMockito + .doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + ((ConsulResponseCallback) args[2]).onComplete(response); + return null; + } + }) + .when(http) + .asyncGet(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + // + PowerMockito.spy(Http.class); + PowerMockito.when(Http.getInstance()).thenReturn(http); + + consul = Consul.newClient(); + + WatchCatalogServicesTask task0 = new WatchCatalogServicesTask( + consul.catalogClient(), CatalogOptions.BLANK, + QueryOptions.BLANK, 10); + + WatchCatalogServicesTask task1 = new WatchCatalogServicesTask( + consul.catalogClient(), 10); + + WatchCatalogServicesTask task2 = new WatchCatalogServicesTask( + consul.catalogClient()); + + } + + public class StopHandler implements WatchTask.Handler + { + + private WatchCatalogServicesTask task; + + StopHandler(WatchCatalogServicesTask task) + { + this.task = task; + } + + @Override + public void handle(ConsulResponse object) { + // TODO Auto-generated method stub +// Map> map = (Map>)object.getResponse(); + LOGGER.debug("handler is here"); + task.stopWatch(); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void teststartWatch() { + WatchCatalogServicesTask task0 = new WatchCatalogServicesTask( + consul.catalogClient(), CatalogOptions.BLANK, + QueryOptions.BLANK, 10); + + task0.addFilter(new Filter() { + @Override + public boolean filter(ConsulResponse object) { + // TODO Auto-generated method stub +// Map> map = (Map>)object.getResponse(); + LOGGER.debug("filter is here"); + return true; + } + + }); + + task0.addHandler(new StopHandler(task0)); + + task0.startWatch(); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTaskTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTaskTest.java new file mode 100644 index 0000000..0e5f95b --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WatchServiceHealthTaskTest.java @@ -0,0 +1,156 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.msb.apiroute.wrapper.consulextend.Consul; +import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchServiceHealthTask; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchTask; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WatchTask.Filter; +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.consulextend.util.Http; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.model.health.ImmutableNode; +import com.orbitz.consul.option.CatalogOptions; +import com.orbitz.consul.option.QueryOptions; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Http.class }) +@PowerMockIgnore({ "javax.net.ssl.*" }) +public class WatchServiceHealthTaskTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(WatchServiceHealthTaskTest.class); + + private Consul consul; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Before + public void init() { + + List list = new ArrayList(); + + Service service = ImmutableService.builder().id("").port(0).address("") + .service("huangleibo").addTags("").createIndex(1).modifyIndex(1).build(); + ServiceHealth serviceHealth = ImmutableServiceHealth.builder() + .service(service) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + list.add(serviceHealth); + + long lastContact = 1; + boolean knownLeader = true; + BigInteger index = BigInteger.valueOf(1); + final ConsulResponse> response = new ConsulResponse>( + list, lastContact, knownLeader, index); + + // + Http http = PowerMockito.mock(Http.class); + + PowerMockito + .doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + ((ConsulResponseCallback) args[2]).onComplete(response); + return null; + } + }) + .when(http) + .asyncGet(Mockito.anyString(), + Mockito.any(TypeReference.class), + Mockito.any(ConsulResponseCallback.class)); + + // + PowerMockito.spy(Http.class); + PowerMockito.when(Http.getInstance()).thenReturn(http); + + } + + @Test + public void testgetServiceName() { + consul = Consul.newClient(); + + WatchServiceHealthTask task0 = new WatchServiceHealthTask( + consul.healthClient(), "huangleibo_task0", true, + CatalogOptions.BLANK, 10, QueryOptions.BLANK); + + LOGGER.info("service name:" + task0.getServiceName()); + + WatchServiceHealthTask task1 = new WatchServiceHealthTask( + consul.healthClient(), "huangleibo_task1", true, 10); + + LOGGER.debug("service name:" + task1.getServiceName()); + + WatchServiceHealthTask task2 = new WatchServiceHealthTask( + consul.healthClient(), "huangleibo_task2", 10); + + LOGGER.debug("service name:" + task2.getServiceName()); + + } + + public class StopHandler implements WatchTask.Handler> + { + + private WatchServiceHealthTask task; + + StopHandler(WatchServiceHealthTask task) + { + this.task = task; + } + + @Override + public void handle(ConsulResponse> object) { + // TODO Auto-generated method stub + List list = (List)object.getResponse(); + LOGGER.debug("handler:"+list.get(0).getService().getService()); + task.stopWatch(); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void teststartWatch() { + Consul consul = Consul.newClient(); + String serviceName = "huangleibo"; + + WatchServiceHealthTask task0 = new WatchServiceHealthTask( + consul.healthClient(), serviceName, true, CatalogOptions.BLANK, + 10, QueryOptions.BLANK); + + task0.addFilter(new Filter() { + + @Override + public boolean filter(ConsulResponse object) { + // TODO Auto-generated method stub + List list = (List)object.getResponse(); + LOGGER.debug("filter:"+list.get(0).getService().getService()); + return true; + } + + }); + + task0.addHandler(new StopHandler(task0)); + + task0.startWatch(); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandlerTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandlerTest.java new file mode 100644 index 0000000..a86baf1 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/expose/WriteBufferHandlerTest.java @@ -0,0 +1,46 @@ +package org.onap.msb.apiroute.wrapper.consulextend.expose; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.expose.WriteBufferHandler; +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.ServiceData; + +import com.orbitz.consul.model.ConsulResponse; +import com.orbitz.consul.model.health.ImmutableNode; + +public class WriteBufferHandlerTest { + @Test + public void testhandle() { + List list = new ArrayList(); + + // modifyIndex 1 + Service service0 = ImmutableService.builder().id("huangleibo1").port(0) + .address("").service("huangleibo").addTags("").createIndex(1) + .modifyIndex(1).build(); + ServiceHealth serviceHealth0 = ImmutableServiceHealth.builder() + .service(service0) + .node(ImmutableNode.builder().node("").address("").build()) + .build(); + + list.add(serviceHealth0); + + long lastContact = 1; + boolean knownLeader = true; + BigInteger index = BigInteger.valueOf(1); + ConsulResponse> object = new ConsulResponse>( + list, lastContact, knownLeader, index); + + WriteBufferHandler> handler = new WriteBufferHandler>( + ServiceData.DataType.service); + + handler.handle(object); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealthTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealthTest.java new file mode 100644 index 0000000..008a28d --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceHealthTest.java @@ -0,0 +1,54 @@ +package org.onap.msb.apiroute.wrapper.consulextend.model.health; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.consulextend.model.health.Service; + +import com.orbitz.consul.model.health.HealthCheck; +import com.orbitz.consul.model.health.ImmutableHealthCheck; +import com.orbitz.consul.model.health.ImmutableNode; +import com.orbitz.consul.model.health.Node; + +public class ServiceHealthTest { + + @Test + public void TestImmutableServiceHealth() { + Service service = ImmutableService.builder().id("").port(0).address("") + .service("huangleibo").addTags("").createIndex(1) + .modifyIndex(1).build(); + Node node = ImmutableNode.builder().node("").address("").build(); + + HealthCheck healthCheck0 = ImmutableHealthCheck.builder().checkId("") + .name("").node("").notes("").output("").serviceId("") + .serviceName("").status("").build(); + HealthCheck healthCheck1 = ImmutableHealthCheck.builder().checkId("") + .name("").node("").notes("").output("").serviceId("") + .serviceName("").status("").build(); + HealthCheck healthCheck2 = ImmutableHealthCheck.builder().checkId("") + .name("").node("").notes("").output("").serviceId("") + .serviceName("").status("").build(); + + ImmutableServiceHealth serviceHealth0 = ImmutableServiceHealth + .builder().service(service).node(node).addChecks(healthCheck0) + .addChecks(healthCheck1, healthCheck2).build(); + + Assert.assertNotNull(serviceHealth0.getNode()); + Assert.assertNotNull(serviceHealth0.getChecks()); + /* ############################################################### */ + + ImmutableServiceHealth serviceHealth1 = serviceHealth0.withNode(node) + .withNode(ImmutableNode.builder().node("").address("").build()) + .withService(service).withService(ImmutableService.builder().id("").port(0).address("") + .service("huangleibo1111").addTags("").createIndex(1) + .modifyIndex(1).build()).withChecks(healthCheck0); + + Assert.assertFalse(serviceHealth1.equals(serviceHealth0)); + System.out.println(serviceHealth1.hashCode()); + + /* ############################################################### */ + + ImmutableServiceHealth serviceHealth2 = ImmutableServiceHealth.builder().from(serviceHealth1).build(); + Assert.assertTrue(serviceHealth1.equals(serviceHealth2)); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceTest.java new file mode 100644 index 0000000..81629c5 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/model/health/ServiceTest.java @@ -0,0 +1,32 @@ +package org.onap.msb.apiroute.wrapper.consulextend.model.health; + +import org.junit.Assert; +import org.junit.Test; + +public class ServiceTest { + + @Test + public void testImmutableService() { + ImmutableService service0 = ImmutableService.builder() + .id("huangleibo_id").port(0).address("").service("huangleibo") + .addTags("111", "222").createIndex(1).modifyIndex(1).build(); + Assert.assertEquals("huangleibo_id", service0.getId()); + Assert.assertEquals(1, service0.getCreateIndex()); + Assert.assertEquals(1, service0.getModifyIndex()); + + ImmutableService service1 = service0.withId("huangleibo_id") + .withId("new_id").withService("huangleibo") + .withService("new_service").withTags("new_tags") + .withAddress("").withAddress("new_address").withPort(0) + .withPort(1).withCreateIndex(1).withCreateIndex(2) + .withModifyIndex(1).withModifyIndex(2); + + Assert.assertFalse(service0.equals(service1)); + + System.out.println(service1.hashCode()); + + ImmutableService service2 = ImmutableService.builder().from(service1) + .build(); + Assert.assertEquals("new_id", service2.getId()); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/util/HttpTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/util/HttpTest.java new file mode 100644 index 0000000..af2197e --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/consulextend/util/HttpTest.java @@ -0,0 +1,80 @@ +package org.onap.msb.apiroute.wrapper.consulextend.util; + +import java.io.InputStream; +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.ProtocolVersion; +import org.apache.http.StatusLine; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.junit.Before; +import org.junit.Test; +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.ConsistencyMode; +import com.orbitz.consul.option.ImmutableCatalogOptions; +import com.orbitz.consul.option.ImmutableQueryOptions; +import com.orbitz.consul.option.QueryOptions; + +public class HttpTest { + private static final Logger LOGGER = LoggerFactory + .getLogger(HttpTest.class); + + @Before + public void init() { + + } + + @Test + public void testoptionsFrom() { + ImmutableCatalogOptions catalogs = ImmutableCatalogOptions.builder() + .build(); + catalogs = catalogs.withDatacenter("datacenter").withTag("tag"); + + BigInteger index = new BigInteger("1"); + ImmutableQueryOptions querys = QueryOptions.blockSeconds(10, index) + .build(); + querys = querys.withConsistencyMode(ConsistencyMode.STALE) + .withDatacenter("datacenter").withNear("near") + .withToken("taoken"); + String url = Http.optionsFrom(catalogs, querys); + LOGGER.info(url); + } + + @Test + public void testconsulResponse() { + + TypeReference>> TYPE_SERVICES_MAP = new TypeReference>>() {}; + + ProtocolVersion version = new ProtocolVersion("HTTP",1,1); + StatusLine status= new BasicStatusLine(version,200,"ok"); + BasicHttpResponse response = new BasicHttpResponse(status); + + response.setHeader("X-Consul-Index", "1"); + response.setHeader("X-Consul-Lastcontact", "1"); + response.setHeader("X-Consul-Knownleader", "true"); + + BasicHttpEntity entity = new BasicHttpEntity(); + InputStream content = HttpTest.class.getResourceAsStream("serviceslist.json"); + entity.setContent(content); + response.setEntity(entity); + + Http.consulResponse(TYPE_SERVICES_MAP, response); + + TypeReference TYPE_SERVICES_MAP_STRING = new TypeReference() {}; + InputStream content1 = HttpTest.class.getResourceAsStream("serviceslist.json"); + entity.setContent(content1); + + Http.consulResponse(TYPE_SERVICES_MAP_STRING, response); + + TypeReference TYPE_SERVICES_MAP_ENTITY = new TypeReference() {}; + Http.consulResponse(TYPE_SERVICES_MAP_ENTITY, response); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/queue/QueueManagerTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/queue/QueueManagerTest.java new file mode 100644 index 0000000..a76575f --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/queue/QueueManagerTest.java @@ -0,0 +1,178 @@ +package org.onap.msb.apiroute.wrapper.queue; + +import java.io.InputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.entity.BasicHttpEntity; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +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.consulextend.util.HttpTest; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.queue.QueueManager; +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.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.RouteUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; +import com.orbitz.consul.model.health.ImmutableNode; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RouteUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class QueueManagerTest { + private static QueueManager queueManager; + + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + queueManager=QueueManager.getInstance(); + putInServiceListQueue(); + putInServiceQueue4Update(); + + } + + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + + + public void test_ServiceConsumer(){ + + //start ServiceListConsumer +// new Thread(new ServiceListConsumer(this),"ServiceListConsumerThread").start(); + + //start Service Consumer + int serviceQueneNum=RouteUtil.SERVICE_DATA_QUEUE_NUM; + for(int i=0;i data=new ServiceData(); + data.setDataType(ServiceData.DataType.service_list); + + BasicHttpEntity entity = new BasicHttpEntity(); + InputStream content = HttpTest.class.getResourceAsStream("serviceslist.json"); + entity.setContent(content); + data.setData(entity); + + try { + queueManager.putIn(data); + } catch (Exception e) { + Assert.assertTrue(e instanceof InterruptedException); + } + } + + private static void putInServiceQueue4Update(){ + ServiceData> data=new ServiceData>(); + data.setDataType(ServiceData.DataType.service); + data.setOperate(ServiceData.Operate.delete); + + List tagList = new ArrayList(); + tagList.add("\"base\":{\"protocol\":\"REST\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + + Service service = + ImmutableService.builder().id("id").port(8686).address("10.74.165.246").service("msbtest") + .addAllTags(tagList).createIndex(0).modifyIndex(0).build(); + ServiceHealth serviceHealth = + ImmutableServiceHealth.builder().service(service) + .node(ImmutableNode.builder().node("server").address("192.168.1.98").build()).build(); + List serviceHealthList = new ArrayList(); + serviceHealthList.add(serviceHealth); + + data.setData(serviceHealthList); + + try { + queueManager.putIn(data); + } catch (Exception e) { + Assert.assertTrue(e instanceof InterruptedException); + } + } + + private static void putInServiceQueue4Delete(){ + ServiceData> data=new ServiceData>(); + data.setDataType(ServiceData.DataType.service); + data.setOperate(ServiceData.Operate.update); + + List tagList = new ArrayList(); + tagList.add("\"base\":{\"protocol\":\"REST\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + + Service service = + ImmutableService.builder().id("id").port(8686).address("10.74.165.246").service("msbtest") + .addAllTags(tagList).createIndex(0).modifyIndex(0).build(); + ServiceHealth serviceHealth = + ImmutableServiceHealth.builder().service(service) + .node(ImmutableNode.builder().node("server").address("192.168.1.98").build()).build(); + List serviceHealthList = new ArrayList(); + serviceHealthList.add(serviceHealth); + + data.setData(serviceHealthList); + + try { + queueManager.putIn(data); + } catch (Exception e) { + Assert.assertTrue(e instanceof InterruptedException); + } + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/ApiRouteServiceTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/ApiRouteServiceTest.java new file mode 100644 index 0000000..a5aa87a --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/ApiRouteServiceTest.java @@ -0,0 +1,251 @@ +package org.onap.msb.apiroute.wrapper.service; + +import com.fiftyonred.mock_jedis.MockJedisPool; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.ApiRouteInfo; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.service.ApiRouteService; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.junit.Assert.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class ApiRouteServiceTest { + private static ApiRouteService apiRouteService = null; + private static Comparator apiRouteComparator = null; + @BeforeClass + public static void setUp() throws Exception{ + apiRouteService = ApiRouteService.getInstance(); + apiRouteComparator = new Comparator() { + @Override + public int compare(ApiRouteInfo o1, ApiRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + if (!o1.getVersion().equals(o2.getVersion())) + return (o1.getVersion()).compareTo(o2.getVersion()); + return 0; + } + }; + } + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + @Test + public void testGetApiRouteInstance_key_not_exist(){ + try { + assertNull(apiRouteService.getApiRouteInstance("msb:routing:api:notexistservice:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetApiRouteInstance_key_exist(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + apirouteInfo.setServers(servers); + try { + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + assertEquals(apirouteInfo, apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testSaveApiRouteService2Redis(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + apirouteInfo.setServers(servers); + try { + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + assertEquals(apirouteInfo, apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testSaveApiRouteService2Redis2(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("test26msb"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/microservices/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.151.26","443")}; + apirouteInfo.setServers(servers); + try { + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:test26msb:v1"); + assertEquals(apirouteInfo, apiRouteService.getApiRouteInstance("msb:routing:api:test26msb:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testDeleteApiRouteService2Redis(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + apirouteInfo.setServers(servers); + try { + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + assertNotNull(apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1")); + apiRouteService.deleteApiRouteService2Redis("msb:routing:api:testapi:v1"); + assertNull(apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testUpdateApiRouteStatus2Redis(){ + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + apirouteInfo.setServers(servers); + try { + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + assertEquals("1", apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1").getStatus()); + apiRouteService.updateApiRouteStatus2Redis("msb:routing:api:testapi:v1","0"); + assertEquals("0", apiRouteService.getApiRouteInstance("msb:routing:api:testapi:v1").getStatus()); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetMultiApiRouteInstances() throws Exception { + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(false); + apirouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + ApiRouteInfo apirouteInfo2 = new ApiRouteInfo(); + apirouteInfo2.setServiceName("testapi"); + apirouteInfo2.setVersion("v2"); + apirouteInfo2.setStatus("0"); + apirouteInfo2.setUrl("/api/testapi/v2"); + apirouteInfo2.setUseOwnUpstream("0"); + apirouteInfo2.setVisualRange("0");; + apirouteInfo.setEnable_ssl(true); + apirouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + apiRouteService.saveApiRouteService2Redis(apirouteInfo2,"msb:routing:api:testapi:v2"); + + List expected = new ArrayList<>(); + expected.add(apirouteInfo); + expected.add(apirouteInfo2); + Collections.sort(expected, apiRouteComparator); + + List result = apiRouteService.getMultiApiRouteInstances("msb:routing:api:*"); + + Collections.sort(result, apiRouteComparator); + assertEquals(expected, result); + } + + @Test + public void testDeleteMultiApiRouteInstances() throws Exception { + ApiRouteInfo apirouteInfo = new ApiRouteInfo(); + apirouteInfo.setServiceName("testapi"); + apirouteInfo.setVersion("v1"); + apirouteInfo.setStatus("1"); + apirouteInfo.setUrl("/api/testapi/v1"); + apirouteInfo.setUseOwnUpstream("0"); + apirouteInfo.setVisualRange("0"); + apirouteInfo.setEnable_ssl(false); + apirouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + ApiRouteInfo apirouteInfo2 = new ApiRouteInfo(); + apirouteInfo2.setServiceName("testapi"); + apirouteInfo2.setVersion("v2"); + apirouteInfo2.setStatus("0"); + apirouteInfo2.setUrl("/api/testapi/v2"); + apirouteInfo2.setUseOwnUpstream("0"); + apirouteInfo2.setVisualRange("0");; + apirouteInfo.setEnable_ssl(true); + apirouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + apiRouteService.saveApiRouteService2Redis(apirouteInfo,"msb:routing:api:testapi:v1"); + apiRouteService.saveApiRouteService2Redis(apirouteInfo2,"msb:routing:api:testapi:v2"); + + assertEquals(2,apiRouteService.getMultiApiRouteInstances("msb:routing:api:testapi:*").size()); + assertEquals(2,apiRouteService.deleteMultiApiRouteService2Redis("msb:routing:api:testapi:*")); + assertEquals(0,apiRouteService.getMultiApiRouteInstances("msb:routing:api:testapi:*").size()); + } + + @Test(expected = Exception.class) + public void testUpdateApiRouteStatus2Redis_keyNotExist() throws Exception { + apiRouteService.updateApiRouteStatus2Redis("msb:routing:api:notexistservice:v1","0"); + } + + @Test(expected = Exception.class) + public void testSaveApiRouteService2Redis_null() throws Exception { + apiRouteService.saveApiRouteService2Redis(null,"msb:routing:api:null:v1"); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/CustomRouteServiceTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/CustomRouteServiceTest.java new file mode 100644 index 0000000..d34958b --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/CustomRouteServiceTest.java @@ -0,0 +1,241 @@ +package org.onap.msb.apiroute.wrapper.service; + +import com.fiftyonred.mock_jedis.MockJedisPool; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.CustomRouteInfo; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.service.CustomRouteService; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.junit.Assert.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class CustomRouteServiceTest { + private static CustomRouteService customRouteService = null; + private static Comparator customRouteComparator = null; + @BeforeClass + public static void setUp() throws Exception{ + customRouteService = CustomRouteService.getInstance(); + customRouteComparator = new Comparator() { + @Override + public int compare(CustomRouteInfo o1, CustomRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + return 0; + } + }; + } + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + @Test + public void testGetCustomRouteInstance_key_not_exist(){ + try { + assertNull(customRouteService.getCustomRouteInstance("msb:routing:custom:notexistservice:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetCustomRouteInstance_key_exist(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + try { + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + assertEquals(customrouteInfo, customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testSaveCustomRouteService2Redis(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom/v1"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + try { + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + assertEquals(customrouteInfo, customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testSaveCustomRouteService2Redis_urlIsSlash(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + try { + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + customrouteInfo.setUrl(""); + assertEquals(customrouteInfo, customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testDeleteCustomRouteService2Redis(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom/v1"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + try { + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + assertNotNull(customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom")); + customRouteService.deleteCustomRouteService2Redis("msb:routing:custom:testcustom"); + assertNull(customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testUpdateCustomRouteStatus2Redis(){ + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom/v1"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + customrouteInfo.setServers(servers); + try { + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + assertEquals("1", customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom").getStatus()); + customRouteService.updateCustomRouteStatus2Redis("msb:routing:custom:testcustom", "0"); + assertEquals("0", customRouteService.getCustomRouteInstance("msb:routing:custom:testcustom").getStatus()); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetMultiCustomRouteInstances() throws Exception { + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(false); + customrouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + CustomRouteInfo customrouteInfo2 = new CustomRouteInfo(); + customrouteInfo2.setServiceName("testcustom2"); + customrouteInfo2.setStatus("0"); + customrouteInfo2.setUrl("/custom/testcustom2"); + customrouteInfo2.setUseOwnUpstream("0"); + customrouteInfo2.setVisualRange("0");; + customrouteInfo.setEnable_ssl(true); + customrouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + customRouteService.saveCustomRouteService2Redis(customrouteInfo2, "msb:routing:custom:testcustom2"); + + List expected = new ArrayList<>(); + expected.add(customrouteInfo); + expected.add(customrouteInfo2); + Collections.sort(expected, customRouteComparator); + + List result = customRouteService.getMultiCustomRouteInstances("msb:routing:custom:*"); + + Collections.sort(result, customRouteComparator); + assertEquals(expected, result); + } + + @Test + public void testDeleteMultiCustomRouteInstances() throws Exception { + CustomRouteInfo customrouteInfo = new CustomRouteInfo(); + customrouteInfo.setServiceName("testcustom"); + customrouteInfo.setStatus("1"); + customrouteInfo.setUrl("/custom/testcustom"); + customrouteInfo.setUseOwnUpstream("0"); + customrouteInfo.setVisualRange("0"); + customrouteInfo.setEnable_ssl(false); + customrouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + CustomRouteInfo customrouteInfo2 = new CustomRouteInfo(); + customrouteInfo2.setServiceName("testcustom2"); + customrouteInfo2.setStatus("0"); + customrouteInfo2.setUrl("/custom/testcustom2"); + customrouteInfo2.setUseOwnUpstream("0"); + customrouteInfo2.setVisualRange("0");; + customrouteInfo.setEnable_ssl(true); + customrouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + customRouteService.saveCustomRouteService2Redis(customrouteInfo, "msb:routing:custom:testcustom"); + customRouteService.saveCustomRouteService2Redis(customrouteInfo2, "msb:routing:custom:testcustom2"); + + assertEquals(2,customRouteService.getMultiCustomRouteInstances("msb:routing:custom:*").size()); + assertEquals(2,customRouteService.deleteMultiCustomRouteService2Redis("msb:routing:custom:*")); + assertEquals(0, customRouteService.getMultiCustomRouteInstances("msb:routing:custom:*").size()); + } + + @Test(expected = Exception.class) + public void testUpdateCustomRouteStatus2Redis_keyNotExist() throws Exception { + customRouteService.updateCustomRouteStatus2Redis("msb:routing:custom:notexistservice", "0"); + } + + @Test(expected = Exception.class) + public void testSaveCustomRouteService2Redis_null() throws Exception { + customRouteService.saveCustomRouteService2Redis(null, "msb:routing:custom:null"); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/IuiRouteServiceTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/IuiRouteServiceTest.java new file mode 100644 index 0000000..0ddbb32 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/IuiRouteServiceTest.java @@ -0,0 +1,221 @@ +package org.onap.msb.apiroute.wrapper.service; + +import com.fiftyonred.mock_jedis.MockJedisPool; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.IuiRouteInfo; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.service.IuiRouteService; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.junit.Assert.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class IuiRouteServiceTest { + private static IuiRouteService iuiRouteService = null; + private static Comparator iuiRouteComparator = null; + @BeforeClass + public static void setUp() throws Exception{ + iuiRouteService = IuiRouteService.getInstance(); + iuiRouteComparator = new Comparator() { + @Override + public int compare(IuiRouteInfo o1, IuiRouteInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + return 0; + } + }; + } + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + @Test + public void testGetIuiRouteInstance_key_not_exist(){ + try { + assertNull(iuiRouteService.getIuiRouteInstance("msb:routing:iui:notexistservice:v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetIuiRouteInstance_key_exist(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + iuirouteInfo.setServers(servers); + try { + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + assertEquals(iuirouteInfo, iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testSaveIuiRouteService2Redis(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui/v1"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + iuirouteInfo.setServers(servers); + try { + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + assertEquals(iuirouteInfo, iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testDeleteIuiRouteService2Redis(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui/v1"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(false); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + iuirouteInfo.setServers(servers); + try { + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + assertNotNull(iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui")); + iuiRouteService.deleteIuiRouteService2Redis("msb:routing:iui:testiui"); + assertNull(iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testUpdateIuiRouteStatus2Redis(){ + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui/v1"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(true); + RouteServer[] servers = new RouteServer[]{new RouteServer("10.74.148.88","8080")}; + iuirouteInfo.setServers(servers); + try { + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + assertEquals("1", iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui").getStatus()); + iuiRouteService.updateIuiRouteStatus2Redis("msb:routing:iui:testiui","0"); + assertEquals("0", iuiRouteService.getIuiRouteInstance("msb:routing:iui:testiui").getStatus()); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetMultiIuiRouteInstances() throws Exception { + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(false); + iuirouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + IuiRouteInfo iuirouteInfo2 = new IuiRouteInfo(); + iuirouteInfo2.setServiceName("testiui2"); + iuirouteInfo2.setStatus("0"); + iuirouteInfo2.setUrl("/iui/testiui2"); + iuirouteInfo2.setUseOwnUpstream("0"); + iuirouteInfo2.setVisualRange("0");; + iuirouteInfo.setEnable_ssl(true); + iuirouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo2,"msb:routing:iui:testiui2"); + + List expected = new ArrayList<>(); + expected.add(iuirouteInfo); + expected.add(iuirouteInfo2); + Collections.sort(expected, iuiRouteComparator); + + List result = iuiRouteService.getMultiIuiRouteInstances("msb:routing:iui:*"); + + Collections.sort(result, iuiRouteComparator); + assertEquals(expected, result); + } + + @Test + public void testDeleteMultiIuiRouteInstances() throws Exception { + IuiRouteInfo iuirouteInfo = new IuiRouteInfo(); + iuirouteInfo.setServiceName("testiui"); + iuirouteInfo.setStatus("1"); + iuirouteInfo.setUrl("/iui/testiui"); + iuirouteInfo.setUseOwnUpstream("0"); + iuirouteInfo.setVisualRange("0"); + iuirouteInfo.setEnable_ssl(false); + iuirouteInfo.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + IuiRouteInfo iuirouteInfo2 = new IuiRouteInfo(); + iuirouteInfo2.setServiceName("testiui2"); + iuirouteInfo2.setStatus("0"); + iuirouteInfo2.setUrl("/iui/testiui2"); + iuirouteInfo2.setUseOwnUpstream("0"); + iuirouteInfo2.setVisualRange("0");; + iuirouteInfo.setEnable_ssl(true); + iuirouteInfo2.setServers(new RouteServer[]{new RouteServer("10.74.148.88","8088")}); + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo,"msb:routing:iui:testiui"); + iuiRouteService.saveIuiRouteService2Redis(iuirouteInfo2,"msb:routing:iui:testiui2"); + + assertEquals(2,iuiRouteService.getMultiIuiRouteInstances("msb:routing:iui:*").size()); + assertEquals(2,iuiRouteService.deleteMultiIuiRouteService2Redis("msb:routing:iui:*")); + assertEquals(0,iuiRouteService.getMultiIuiRouteInstances("msb:routing:iui:*").size()); + } + + @Test(expected = Exception.class) + public void testUpdateIuiRouteStatus2Redis_keyNotExist() throws Exception { + iuiRouteService.updateIuiRouteStatus2Redis("msb:routing:iui:notexistservice","0"); + } + + @Test(expected = Exception.class) + public void testSaveIuiRouteService2Redis_null() throws Exception { + iuiRouteService.saveIuiRouteService2Redis(null,"msb:routing:iui:null"); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullServiceTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullServiceTest.java new file mode 100644 index 0000000..7ca2ff7 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/service/MicroServiceFullServiceTest.java @@ -0,0 +1,413 @@ +package org.onap.msb.apiroute.wrapper.service; + +import com.fiftyonred.mock_jedis.MockJedisPool; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.MicroServiceFullInfo; +import org.onap.msb.apiroute.api.Node; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.service.MicroServiceFullService; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.*; + +import static org.junit.Assert.*; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,RedisAccessWrapper.class}) +@PowerMockIgnore( {"javax.management.*"}) +public class MicroServiceFullServiceTest { + private static MicroServiceFullService microServiceFullService = null; + private static Comparator serviceComparator = null; + @BeforeClass + public static void setUp() throws Exception{ + microServiceFullService = MicroServiceFullService.getInstance(); + serviceComparator = new Comparator() { + @Override + public int compare(MicroServiceFullInfo o1, MicroServiceFullInfo o2) { + if (!o1.getServiceName().equals(o2.getServiceName())) + return (o1.getServiceName()).compareTo(o2.getServiceName()); + if (!o1.getVersion().equals(o2.getVersion())) + return (o1.getVersion()).compareTo(o2.getVersion()); + return 0; + } + }; + } + @Before + public void setUpBeforeTest() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + @Test + public void testExistsMicroServiceInstance_notExist(){ + try { + assertFalse(microServiceFullService.existsMicroServiceInstance("notExist", "v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + @Test + public void testExistsMicroServiceInstance_Exist(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + try { + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", "v1")); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + assertTrue(microServiceFullService.existsMicroServiceInstance("testService", "v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + + @Test + public void testSaveMicroServiceInfo2Redis(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + MicroServiceFullInfo actual = microServiceFullService.getMicroServiceInstance("testService", "v1"); + assertEquals(microServiceFullInfo, actual); + } catch (Exception e) { + e.printStackTrace(); + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testDeleteMicroService(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + assertTrue(microServiceFullService.existsMicroServiceInstance("testService", "v1")); + microServiceFullService.deleteMicroService("testService","v1"); + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", "v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + + @Test + public void testUpdateMicroServiceStatus(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + assertEquals("1", microServiceFullService.getMicroServiceInstance("testService","v1").getStatus()); + microServiceFullService.updateMicroServiceStatus("testService", "v1", "0"); + assertEquals("0", microServiceFullService.getMicroServiceInstance("testService", "v1").getStatus()); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void testGetAllMicroServiceKey(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + + MicroServiceFullInfo microServiceFullInfo2 = new MicroServiceFullInfo(); + microServiceFullInfo2.setServiceName("testService2"); + microServiceFullInfo2.setVersion(""); + microServiceFullInfo2.setStatus("1"); + microServiceFullInfo2.setUrl("/testService2"); + microServiceFullInfo2.setVisualRange("0"); + microServiceFullInfo2.setProtocol("http"); + microServiceFullInfo2.setEnable_ssl(false); + Set nodeSet2 = new HashSet<>(); + nodeSet2.add(new Node("10.74.148.88","8081")); + microServiceFullInfo2.setNodes(nodeSet2); + + MicroServiceFullInfo microServiceFullInfo3 = new MicroServiceFullInfo(); + microServiceFullInfo3.setServiceName("testService"); + microServiceFullInfo3.setVersion("v2"); + microServiceFullInfo3.setStatus("1"); + microServiceFullInfo3.setUrl("/testService/v2"); + microServiceFullInfo3.setVisualRange("0"); + microServiceFullInfo3.setProtocol("http"); + microServiceFullInfo3.setEnable_ssl(false); + Set nodeSet3 = new HashSet<>(); + nodeSet3.add(new Node("10.74.148.89","8080")); + microServiceFullInfo3.setNodes(nodeSet3); + + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo2); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo3); + + Set result = microServiceFullService.getAllMicroServiceKey(); + final Set expected =new HashSet(); + expected.add("testService"); + expected.add("testService2"); + + assertEquals(expected, result); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + + } + + @Test + public void testGetAllVersionsOfTheService(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + + MicroServiceFullInfo microServiceFullInfo2 = new MicroServiceFullInfo(); + microServiceFullInfo2.setServiceName("testService2"); + microServiceFullInfo2.setVersion(""); + microServiceFullInfo2.setStatus("1"); + microServiceFullInfo2.setUrl("/testService2"); + microServiceFullInfo2.setVisualRange("0"); + microServiceFullInfo2.setProtocol("http"); + microServiceFullInfo2.setEnable_ssl(false); + Set nodeSet2 = new HashSet<>(); + nodeSet2.add(new Node("10.74.148.88","8081")); + microServiceFullInfo2.setNodes(nodeSet2); + + MicroServiceFullInfo microServiceFullInfo3 = new MicroServiceFullInfo(); + microServiceFullInfo3.setServiceName("testService"); + microServiceFullInfo3.setVersion("v2"); + microServiceFullInfo3.setStatus("1"); + microServiceFullInfo3.setUrl("/testService/v2"); + microServiceFullInfo3.setVisualRange("0"); + microServiceFullInfo3.setProtocol("http"); + microServiceFullInfo3.setEnable_ssl(false); + Set nodeSet3 = new HashSet<>(); + nodeSet3.add(new Node("10.74.148.89","8080")); + microServiceFullInfo3.setNodes(nodeSet3); + + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo3); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo2); + + + List result = microServiceFullService.getAllVersionsOfTheService("testService"); + + List expected = new ArrayList<>(); + expected.add(microServiceFullInfo); + expected.add(microServiceFullInfo3); + + Collections.sort(expected,serviceComparator); + Collections.sort(result,serviceComparator); + assertEquals(expected, result); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + + } + + @Test + public void testGetAllMicroServicesInstances(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + + MicroServiceFullInfo microServiceFullInfo2 = new MicroServiceFullInfo(); + microServiceFullInfo2.setServiceName("testService2"); + microServiceFullInfo2.setVersion(""); + microServiceFullInfo2.setStatus("1"); + microServiceFullInfo2.setUrl("/testService/v1"); + microServiceFullInfo2.setVisualRange("0"); + microServiceFullInfo2.setProtocol("http"); + microServiceFullInfo2.setEnable_ssl(true); + Set nodeSet2 = new HashSet<>(); + nodeSet2.add(new Node("10.74.148.89","8080")); + microServiceFullInfo2.setNodes(nodeSet2); + + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo2); + + List expected = new ArrayList(); + expected.add(microServiceFullInfo); + expected.add(microServiceFullInfo2); + List result = microServiceFullService.getAllMicroServiceInstances(); + Collections.sort(expected, serviceComparator); + Collections.sort(result,serviceComparator ); + assertEquals(expected, result); + } catch (Exception e) { + e.printStackTrace(); + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + + @Test + public void testDeleteMultiMicroService(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion("v1"); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + + + MicroServiceFullInfo microServiceFullInfo3 = new MicroServiceFullInfo(); + microServiceFullInfo3.setServiceName("testService"); + microServiceFullInfo3.setVersion("v2"); + microServiceFullInfo3.setStatus("1"); + microServiceFullInfo3.setUrl("/testService/v2"); + microServiceFullInfo3.setVisualRange("0"); + microServiceFullInfo3.setProtocol("http"); + microServiceFullInfo3.setEnable_ssl(false); + Set nodeSet3 = new HashSet<>(); + nodeSet3.add(new Node("10.74.148.89","8080")); + microServiceFullInfo3.setNodes(nodeSet3); + + try { + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo3); + //two versions of testservice exist + assertEquals(2,microServiceFullService.getAllVersionsOfTheService("testService").size()); + //delete all versions of testservice + long size = microServiceFullService.deleteMultiMicroService(MicroServiceUtil.getPrefixedKey("testService","*")); + //after delete,no version exist + assertEquals(0,microServiceFullService.getAllVersionsOfTheService("testService").size()); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test + public void tesGetMicroServiceInstance_notExist(){ + try { + assertNull(microServiceFullService.getMicroServiceInstance("notExist","v1")); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + + } + @Test + public void tesExistsGetUpdateDeleteMicroServiceStatus_versionNull(){ + MicroServiceFullInfo microServiceFullInfo = new MicroServiceFullInfo(); + microServiceFullInfo.setServiceName("testService"); + microServiceFullInfo.setVersion(""); + microServiceFullInfo.setStatus("1"); + microServiceFullInfo.setUrl("/testService/v1"); + microServiceFullInfo.setVisualRange("0"); + microServiceFullInfo.setProtocol("http"); + microServiceFullInfo.setEnable_ssl(false); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88","8080")); + microServiceFullInfo.setNodes(nodeSet); + try { + //test null + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", "null")); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + assertEquals("1", microServiceFullService.getMicroServiceInstance("testService","null").getStatus()); + microServiceFullService.updateMicroServiceStatus("testService", "null", "0"); + assertEquals("0", microServiceFullService.getMicroServiceInstance("testService", "null").getStatus()); + microServiceFullService.deleteMicroService("testService","null"); + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", "null")); + + + //test String "null" + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", null)); + microServiceFullService.saveMicroServiceInfo2Redis(microServiceFullInfo); + assertEquals("1", microServiceFullService.getMicroServiceInstance("testService",null).getStatus()); + microServiceFullService.updateMicroServiceStatus("testService", null, "0"); + assertEquals("0", microServiceFullService.getMicroServiceInstance("testService", null).getStatus()); + microServiceFullService.deleteMicroService("testService",null); + assertFalse(microServiceFullService.existsMicroServiceInstance("testService", null)); + } catch (Exception e) { + assert false:"throw exception means error occured!"+e.getMessage(); + } + } + + @Test(expected = Exception.class) + public void tesSaveMicroService_null() throws Exception { + microServiceFullService.saveMicroServiceInfo2Redis(null); + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListenerTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListenerTest.java new file mode 100644 index 0000000..f537e0e --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/serviceListener/MicroServiceChangeListenerTest.java @@ -0,0 +1,666 @@ +package org.onap.msb.apiroute.wrapper.serviceListener; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.ApiRouteAppConfig; +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.RouteServer; +import org.onap.msb.apiroute.api.exception.ExtendedNotFoundException; +import org.onap.msb.apiroute.wrapper.ApiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.CustomRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.InitRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.IuiRouteServiceWrapper; +import org.onap.msb.apiroute.wrapper.dao.RedisAccessWrapper; +import org.onap.msb.apiroute.wrapper.serviceListener.RouteNotify; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.HttpClientUtil; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; +import org.onap.msb.apiroute.wrapper.util.RouteUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import com.fiftyonred.mock_jedis.MockJedisPool; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({JedisUtil.class,ConfigUtil.class,HttpClientUtil.class, RedisAccessWrapper.class,}) +@PowerMockIgnore({"javax.management.*"}) +public class MicroServiceChangeListenerTest { + private static RouteNotify routeInstance; + private static ApiRouteServiceWrapper apiRouteServiceWrapper; + private static IuiRouteServiceWrapper iuiRouteServiceWrapper; + private static CustomRouteServiceWrapper customRouteServiceWrapper; + + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + InitRouteServiceWrapper.getInstance().registerServiceChangeListener(); + routeInstance=RouteNotify.getInstance(); + apiRouteServiceWrapper=ApiRouteServiceWrapper.getInstance(); + iuiRouteServiceWrapper=IuiRouteServiceWrapper.getInstance(); + customRouteServiceWrapper=CustomRouteServiceWrapper.getInstance(); + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn("ip|domain"); + ConfigUtil.getInstance().initRouteWay(); + } + + @Before + public void initReidsMock() throws Exception { + final JedisPool mockJedisPool = new MockJedisPool(new JedisPoolConfig(), "localhost"); + PowerMockito.mockStatic(JedisUtil.class); + JedisUtil jedisUtil=PowerMockito.mock(JedisUtil.class); + PowerMockito.when(jedisUtil.borrowJedisInstance()).thenReturn(mockJedisPool.getResource()); + + PowerMockito.replace(PowerMockito.method(RedisAccessWrapper.class, "filterKeys")).with(new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return mockJedisPool.getResource().keys((String) args[0]); + } + }); + } + + @Test + public void test_noticeRouteListener4Update_api(){ + try { + routeInstance.noticeRouteListener4Update("apiTest-ns", "v1", buildMicroServiceFullInfo4API()); + ApiRouteInfo apiRouteInfo=apiRouteServiceWrapper.getApiRouteInstance("apiTest-ns", "v1", "host", "20081", "ip"); + + Assert.assertNotNull(apiRouteInfo); + Assert.assertEquals("1", apiRouteInfo.getStatus()); + + routeInstance.noticeUpdateStatusListener(buildMicroServiceFullInfo4API(),"0"); + apiRouteInfo=apiRouteServiceWrapper.getApiRouteInstance("apiTest-ns", "v1", "host", "20081", "ip"); + Assert.assertEquals("0", apiRouteInfo.getStatus()); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + } + + @Test + public void test_noticeRouteListener4Update_iui(){ + try { + routeInstance.noticeRouteListener4Update("iuiTest-ns", "v1", buildMicroServiceFullInfo4IUI()); + IuiRouteInfo iuiRouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest-ns", "host", "20081", "ip"); + + Assert.assertNotNull(iuiRouteInfo); + Assert.assertEquals("1", iuiRouteInfo.getStatus()); + + routeInstance.noticeUpdateStatusListener(buildMicroServiceFullInfo4IUI(),"0"); + iuiRouteInfo=iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest-ns", "host", "20081", "ip"); + Assert.assertEquals("0", iuiRouteInfo.getStatus()); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + } + + @Test + public void test_noticeRouteListener4Update_http(){ + try { + routeInstance.noticeRouteListener4Update("httpTest-ns", "v1", buildMicroServiceFullInfo4HTTP()); + CustomRouteInfo customRouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/httpTest-ns", "host", "20081", "ip"); + Assert.assertNotNull(customRouteInfo); + Assert.assertEquals("1", customRouteInfo.getStatus()); + + routeInstance.noticeUpdateStatusListener(buildMicroServiceFullInfo4HTTP(),"0"); + customRouteInfo=customRouteServiceWrapper.getCustomRouteInstance("/httpTest-ns", "host", "20081", "ip"); + Assert.assertEquals("0", customRouteInfo.getStatus()); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + } + + @Test + public void test_noticeRouteListener4Add_del_api(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4API(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "20081", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/", "apitest-ns", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "20081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "apitest-ns", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + + } + + @Test + public void test_noticeRouteListener4Add_del_api_path(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4API_path(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "", "10081", "ip")); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "", "10082", "ip")); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "host", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest4Path", "v1", "host", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_noticeRouteListener4Add_del_api_mutiPort(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4API_path(); + microServiceInfo.setPath(""); + microServiceInfo.setHost(""); + + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "10081", "ip")); + Assert.assertNotNull(apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "10082", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/", "apitest", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + apiRouteServiceWrapper.getApiRouteInstance("apiTest", "v1", "apitest", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_noticeRouteListener4Add_del_iui(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4IUI(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "20081", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/", "iuitest-ns", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "20081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "iuitest-ns", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_noticeRouteListener4Add_del_iui_path(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4IUI_path(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "", "10081", "ip")); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "", "10082", "ip")); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "host", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest4Path", "host", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + + @Test + public void test_noticeRouteListener4Add_del_iui_mutiPort(){ + try { + MicroServiceFullInfo microServiceInfo =buildMicroServiceFullInfo4IUI_path(); + microServiceInfo.setPath(""); + microServiceInfo.setHost(""); + + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "10081", "ip")); + Assert.assertNotNull(iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "10082", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/", "iuitest", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + iuiRouteServiceWrapper.getIuiRouteInstance("iuiTest", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/", "iuitest", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_noticeRouteListener4Add_del_http(){ + try { + MicroServiceFullInfo microServiceInfo=buildMicroServiceFullInfo4HTTP(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "20081", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "httptest-ns", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "20081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest", "httptest-ns", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + @Test + public void test_noticeRouteListener4Add_del_http_path(){ + try { + MicroServiceFullInfo microServiceInfo=buildMicroServiceFullInfo4HTTP_path(); + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "", "10081", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "", "10082", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "host", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest4Path", "host", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + + @Test + public void test_noticeRouteListener4Add_del_http_mutiPort(){ + try { + MicroServiceFullInfo microServiceInfo=buildMicroServiceFullInfo4HTTP_path(); + microServiceInfo.setPath(""); + microServiceInfo.setHost(""); + + routeInstance.noticeRouteListener4Add(microServiceInfo); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "10081", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "10082", "ip")); + Assert.assertNotNull(customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "httptest", "", "domain")); + + routeInstance.noticeRouteListener4Delete(microServiceInfo); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "10081", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest/v1", "", "10082", "ip"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + try { + customRouteServiceWrapper.getCustomRouteInstance("/httpTest", "httptest", "", "domain"); + Assert.fail("should not process to here."); + } + catch(Exception e){ + Assert.assertTrue(e instanceof ExtendedNotFoundException); + } + + } + + + @Test + public void test_noticeRouteListener4Add_portal(){ + try { + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("SDCLIENT_IP")).thenReturn("127.0.0.1"); + ApiRouteAppConfig configuration=new ApiRouteAppConfig(); + + DiscoverInfo discoverInfo=new DiscoverInfo(); + discoverInfo.setEnabled(true); + discoverInfo.setIp("127.0.0.2"); + discoverInfo.setPort(10081); + configuration.setDiscoverInfo(discoverInfo); + ConfigUtil.getInstance().initDiscoverInfo(configuration); + + + PowerMockito.mockStatic(HttpClientUtil.class); + String publishUrl="http://127.0.0.1:10081/api/microservices/v1/services/portalTest/version/v1/allpublishaddress?namespace=&visualRange=0"; + String resultJson ="[{\"domain\":\"opapi.openpalette.zte.com.cn\",\"port\":\"443\",\"publish_url\":\"/api\",\"visualRange\":\"0\",\"publish_protocol\":\"https\"},{\"ip\":\"10.74.165.246\",\"port\":\"443\",\"publish_url\":\"/opapi\",\"visualRange\":\"0\",\"publish_protocol\":\"https\"},{\"ip\":\"10.74.165.246\",\"port\":\"80\",\"publish_url\":\"/opapi\",\"visualRange\":\"0\",\"publish_protocol\":\"http\"}]"; + PowerMockito.when(HttpClientUtil.httpGet(publishUrl)).thenReturn(resultJson); + + MicroServiceFullInfo microServiceInfo=buildMicroServiceFullInfo4PORTAL(); + + routeInstance.noticeRouteListener4Add(microServiceInfo); + + CustomRouteInfo routeInfo_ip=customRouteServiceWrapper.getCustomRouteInstance("/portalTest/v1", "", "10088", "ip"); + RouteServer[] servers_ip = new RouteServer[]{new RouteServer("10.74.148.99","8080")}; + Assert.assertArrayEquals(servers_ip, routeInfo_ip.getServers()); + + CustomRouteInfo routeInfo_domain=customRouteServiceWrapper.getCustomRouteInstance("/portalTest/v1", "host", "", "domain"); + RouteServer[] servers_domain = new RouteServer[]{new RouteServer("10.74.165.246","443")}; + + Assert.assertArrayEquals(servers_domain, routeInfo_domain.getServers()); + + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + } + + } + + + private MicroServiceFullInfo buildMicroServiceFullInfo4API(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("apiTest-ns"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(false); + microServiceInfo.setPublish_port("20081"); + microServiceInfo.setProtocol("REST"); + microServiceInfo.setUrl("/api/apiTest/v1"); + microServiceInfo.setVisualRange("1"); + microServiceInfo.setStatus("1"); + microServiceInfo.setNamespace("ns"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4API_path(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("apiTest"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(true); + microServiceInfo.setHost("host"); + microServiceInfo.setPath("/api/apiTest4Path/v1"); + microServiceInfo.setPublish_port("10081|10082"); + microServiceInfo.setProtocol("REST"); + microServiceInfo.setUrl("/api/apiTest/v1"); + microServiceInfo.setVisualRange("0"); + microServiceInfo.setLb_policy("ip_hash"); + microServiceInfo.setStatus("1"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + + private MicroServiceFullInfo buildMicroServiceFullInfo4PORTAL(){ + + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("portalTest"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(true); + microServiceInfo.setHost("host"); + microServiceInfo.setPublish_port("10088"); + microServiceInfo.setProtocol("HTTP"); + microServiceInfo.setUrl("/portalTestUrl/v1"); + microServiceInfo.setVisualRange("0"); + microServiceInfo.setLb_policy("ip_hash"); + microServiceInfo.setStatus("1"); + microServiceInfo.setCustom(RouteUtil.CUSTOM_PORTAL); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.99","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4IUI(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("iuiTest-ns"); + microServiceInfo.setNamespace("ns"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(false); + microServiceInfo.setPublish_port("20081"); + microServiceInfo.setProtocol("UI"); + microServiceInfo.setUrl("/iui/iuiTest"); + microServiceInfo.setVisualRange("1"); + microServiceInfo.setStatus("1"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4IUI_path(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("iuiTest"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(true); + microServiceInfo.setHost("host"); + microServiceInfo.setProtocol("UI"); + microServiceInfo.setUrl("/iui/iuiTest"); + microServiceInfo.setLb_policy("ip_hash"); + microServiceInfo.setPublish_port("10081|10082"); + microServiceInfo.setPath("/iui/iuiTest4Path"); + microServiceInfo.setVisualRange("0"); + microServiceInfo.setStatus("1"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4HTTP(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("httpTest-ns"); + microServiceInfo.setNamespace("ns"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(false); + microServiceInfo.setPublish_port("20081"); + microServiceInfo.setProtocol("HTTP"); + microServiceInfo.setUrl("/httpTest"); + microServiceInfo.setVisualRange("1"); + microServiceInfo.setStatus("1"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + private MicroServiceFullInfo buildMicroServiceFullInfo4HTTP_path(){ + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("httpTest"); + microServiceInfo.setVersion("v1"); + microServiceInfo.setEnable_ssl(true); + microServiceInfo.setHost("host"); + microServiceInfo.setPublish_port("20081"); + microServiceInfo.setProtocol("HTTP"); + microServiceInfo.setUrl("/httpTest"); + microServiceInfo.setVisualRange("0"); + microServiceInfo.setStatus("1"); + microServiceInfo.setLb_policy("ip_hash"); + microServiceInfo.setPublish_port("10081|10082"); + microServiceInfo.setPath("/httpTest4Path"); + Set nodes = new HashSet(); + nodes.add(new Node("10.74.148.88","8080")); + nodes.add(new Node("10.74.148.89","8080")); + microServiceInfo.setNodes(nodes); + + return microServiceInfo; + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/CommonUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/CommonUtilTest.java new file mode 100644 index 0000000..825868c --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/CommonUtilTest.java @@ -0,0 +1,61 @@ +package org.onap.msb.apiroute.wrapper.util; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.util.CommonUtil; + +public class CommonUtilTest { + + + + @Test + public void test_concat() { + Object[] str1 = new String[] {"test1", "test2"}; + Object[] str2 = new String[] {"test3"}; + Object[] str3 = CommonUtil.concat(str1, str2); + + Assert.assertEquals(3, str3.length); + } + + @Test + public void test_containStr() { + String value = "1"; + String array[] = {"1", "2"}; + Assert.assertTrue(CommonUtil.contain(array, value)); + Assert.assertFalse(CommonUtil.contain(array, "3")); + } + + @Test + public void test_containArray() { + String value[] = {"0"}; + String array[] = {"1", "2"}; + String array2[] = {"2", "1"}; + Assert.assertFalse(CommonUtil.contain(array, value)); + Assert.assertTrue(CommonUtil.contain(array, array2)); + } + + @Test + public void test_containStrArray() { + Assert.assertFalse(CommonUtil.contain("0,1,2", "3")); + Assert.assertTrue(CommonUtil.contain("0,1,2", "1")); + } + + @Test + public void test_getDiffrent() { + Set list1 = new HashSet(); + list1.add("test1"); + list1.add("test2"); + + Set list2 = new HashSet(); + list2.add("test2"); + list2.add("test3"); + + Set diff = CommonUtil.getDiffrent(list1, list2); + Assert.assertEquals(1, diff.size()); + Assert.assertTrue(diff.contains("test3")); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ConfigUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ConfigUtilTest.java new file mode 100644 index 0000000..e17c177 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ConfigUtilTest.java @@ -0,0 +1,214 @@ +package org.onap.msb.apiroute.wrapper.util; + + + +import java.lang.reflect.Field; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.ApiRouteAppConfig; +import org.onap.msb.apiroute.api.DiscoverInfo; +import org.onap.msb.apiroute.wrapper.util.ConfigUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ConfigUtil.class}) +public class ConfigUtilTest { + + @Test + public void test_initRootPath() { + try { + ConfigUtil.getInstance().initRootPath(); + String iuiRootPath = ConfigUtil.getInstance().getIUI_ROOT_PATH(); + String apiRootPath = ConfigUtil.getInstance().getAPI_ROOT_PATH(); + Assert.assertEquals("iui", iuiRootPath); + Assert.assertEquals("api", apiRootPath); + } catch (Exception e) { + Assert.fail("throw exception means error occured!" + e.getMessage()); + + } + + } + + @Test + public void test_initApiGatewayPort() { + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("APIGATEWAY_EXPOSE_PORT")).thenReturn(null); + ConfigUtil.getInstance().initApiGatewayPort(); + Assert.assertEquals("80", ConfigUtil.getInstance().getServerPort()); + + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("APIGATEWAY_EXPOSE_PORT")).thenReturn("81"); + + ConfigUtil.getInstance().initApiGatewayPort(); + Assert.assertEquals("81", ConfigUtil.getInstance().getServerPort()); + } + + @Test + public void test_initRouteNameSpaceMatches() { + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("APIGATEWAY_EXPOSE_PORT")).thenReturn(null); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertEquals("all", ConfigUtil.getInstance().getNamespaceMatches()); + + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("net"); + + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertEquals("net", ConfigUtil.getInstance().getNamespaceMatches()); + } + + @Test + public void test_initRouteLabelsMatches() { + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn(null); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertEquals("0", ConfigUtil.getInstance().getVisualRangeMatches()); + Assert.assertEquals("net", ConfigUtil.getInstance().getNetwork_plane_typeMatches()); + Assert.assertTrue(ConfigUtil.getInstance().getLabelMapMatches().containsKey("custom-key")); + + + + + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("visualRange:1,network_plane_type:net,custom:test"); + + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertEquals("1", ConfigUtil.getInstance().getVisualRangeMatches()); + Assert.assertEquals("net", ConfigUtil.getInstance().getNetwork_plane_typeMatches()); + Assert.assertTrue(ConfigUtil.getInstance().getLabelMapMatches().containsKey("custom")); + + } + + @Test + public void test_initRouteWay() { + PowerMockito.mockStatic(System.class); + + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn(null); + ConfigUtil.getInstance().initRouteWay(); + String[] ip_routeWay={"ip"}; + Assert.assertArrayEquals(ip_routeWay, ConfigUtil.getInstance().getRouteWay()); + + PowerMockito.when(System.getenv("ROUTE_WAY")).thenReturn("ip|domain"); + + ConfigUtil.getInstance().initRouteWay(); + String[] routeWay={"ip","domain"}; + Assert.assertArrayEquals(routeWay, ConfigUtil.getInstance().getRouteWay()); + } + + @Test + public void test_initDiscoverInfo() { + PowerMockito.mockStatic(System.class); + + + ApiRouteAppConfig configuration=new ApiRouteAppConfig(); + + DiscoverInfo discoverInfo=new DiscoverInfo(); + discoverInfo.setEnabled(true); + discoverInfo.setIp("127.0.0.1"); + discoverInfo.setPort(10081); + + configuration.setDiscoverInfo(discoverInfo); + PowerMockito.when(System.getenv("SDCLIENT_IP")).thenReturn(null); + ConfigUtil.getInstance().initDiscoverInfo(configuration); + Assert.assertEquals("127.0.0.1:10081", ConfigUtil.getInstance().getDiscoverInfo().toString()); + + PowerMockito.when(System.getenv("SDCLIENT_IP")).thenReturn("10.74.44.86"); + ConfigUtil.getInstance().initDiscoverInfo(configuration); + Assert.assertEquals("10.74.44.86:10081", ConfigUtil.getInstance().getDiscoverInfo().toString()); + } + + @Test + public void test_initNodeMeta() { + + //CONSUL_REGISTER_MODE not catalog + ConfigUtil util=ConfigUtil.getInstance(); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),""); + + //CONSUL_REGISTER_MODE catalog + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("CONSUL_REGISTER_MODE")).thenReturn("agnet"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),""); + + + //CONSUL_REGISTER_MODE catalog + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("CONSUL_REGISTER_MODE")).thenReturn("catalog"); + try { + Field visualRangeField=util.getClass().getDeclaredField("visualRangeMatches"); + visualRangeField.setAccessible(true); + + Field namespaceField = util.getClass().getDeclaredField("namespaceMatches"); + namespaceField.setAccessible(true); + + //0:default; + visualRangeField.set(util, "0"); + namespaceField.set(util, "default"); + + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=external:true&node-meta=ns:default"); + + //1:default; + visualRangeField.set(util, "1"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=internal:true&node-meta=ns:default"); + + //0|1:default + visualRangeField.set(util, "0|1"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=ns:default"); + + //0|1:all + namespaceField.set(util, "all"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),""); + + /////////////////////////////////////////////////////////////////////////// + //1:all + visualRangeField.set(util, "1"); + namespaceField.set(util, "all"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=internal:true"); + + //1:! + namespaceField.set(util, "!default"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=internal:true"); + + //1:& + namespaceField.set(util, "tenant1&tenant2"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=internal:true"); + + //1:| + namespaceField.set(util, "tenant1|tenant2"); + util.initNodeMetaQueryParam(); + System.out.println(util.getNodeMetaQueryParam()); + Assert.assertEquals(util.getNodeMetaQueryParam(),"node-meta=internal:true"); + + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtilTest.java new file mode 100644 index 0000000..568e4f9 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/HttpClientUtilTest.java @@ -0,0 +1,29 @@ +package org.onap.msb.apiroute.wrapper.util; + +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.util.HttpClientUtil; + +public class HttpClientUtilTest { + + private String testIp="http://10.74.151.26:8500"; + + @Test + public void test_httpGet() { + /*try { + int result = HttpClientUtil.httpGetStatus(testIp); + if(result==200){ + Assert.assertEquals("Consul Agent", HttpClientUtil.httpGet(testIp)); + } + else{ + Assert.assertEquals(500, result); + } + + + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + }*/ + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtilTest.java new file mode 100644 index 0000000..f9835d9 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JacksonJsonUtilTest.java @@ -0,0 +1,94 @@ +/** + * 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.List; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.api.PublishFullAddress; +import org.onap.msb.apiroute.api.RouteServer; +import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil; + +import com.fasterxml.jackson.core.type.TypeReference; + + +public class JacksonJsonUtilTest { + @Test + public void testBeanToJson(){ + try{ + RouteServer server=new RouteServer("127.0.0.1","80"); + String json=JacksonJsonUtil.beanToJson(server); + Assert.assertEquals("{\"ip\":\"127.0.0.1\",\"port\":\"80\",\"weight\":0}",json); + } + catch(Exception e){ + Assert.fail("Exception" + e.getMessage()); + } + } + + @Test + public void testJsonToBean(){ + try{ + String json="{\"ip\":\"127.0.0.1\",\"port\":\"80\",\"weight\":0}"; + RouteServer server=(RouteServer) JacksonJsonUtil.jsonToBean(json, RouteServer.class); + Assert.assertEquals("127.0.0.1",server.getIp()); + Assert.assertEquals("80",server.getPort()); + } + catch(Exception e){ + Assert.fail("Exception" + e.getMessage()); + } + } + + +// @Test +// public void testJsonToBean_Fail(){ +// try{ +// String json="{\"ip\":\"127.0.0.1\",\"port\":\"80\",\"weight\":0"; +// RouteServer server=(RouteServer) JacksonJsonUtil.jsonToBean(json, RouteServer.class); +// } +// catch(Exception e){ +// Assert.assertEquals("class org.onap.msb.apiroute.api.RouteServer JsonTobean faild",e.getMessage()); +// } +// } + + @Test + public void testJsonToListBean(){ + try{ + String resultJson="[{\"domain\": \"wudith.openpalette.zte.com.cn\",\"port\": \"80\",\"publish_url\": \"/api/wudith/v1\",\"visualRange\": \"0\",\"publish_protocol\": \"http\"}," + + "{\"ip\": \"10.74.165.246\",\"port\": \"80\",\"publish_url\": \"/api/wudith/v1\",\"visualRange\": \"0\",\"publish_protocol\": \"http\"}]"; + List publishFullAddressList = + JacksonJsonUtil.jsonToListBean(resultJson, new TypeReference>() {}); + Assert.assertEquals(2,publishFullAddressList.size()); + Assert.assertEquals("80",publishFullAddressList.get(0).getPort()); + } + catch(Exception e){ + Assert.fail("Exception" + e.getMessage()); + } + } + + @Test + public void testJsonToListBean_Fail(){ + try{ + String resultJson="[\"domain\": \"wudith.openpalette.zte.com.cn\",\"port\": \"80\",\"publish_url\": \"/api/wudith/v1\",\"visualRange\": \"0\",\"publish_protocol\": \"http\"}," + + "{\"ip\": \"10.74.165.246\",\"port\": \"80\",\"publish_url\": \"/api/wudith/v1\",\"visualRange\": \"0\",\"publish_protocol\": \"http\"}]"; + List publishFullAddressList = + JacksonJsonUtil.jsonToListBean(resultJson, new TypeReference>() {}); + } + catch(Exception e){ + Assert.assertTrue(e instanceof Exception); + } + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JedisUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JedisUtilTest.java new file mode 100644 index 0000000..5a92e32 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/JedisUtilTest.java @@ -0,0 +1,20 @@ +package org.onap.msb.apiroute.wrapper.util; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.util.JedisUtil; + +import redis.clients.jedis.exceptions.JedisConnectionException; + +public class JedisUtilTest { + @Test + public void test_initialPool() { + try { + JedisUtil.borrowJedisInstance(); + + } catch (Exception e) { + Assert.assertTrue(e instanceof JedisConnectionException); + + } + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtilTest.java new file mode 100644 index 0000000..2012413 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/MicroServiceUtilTest.java @@ -0,0 +1,45 @@ +package org.onap.msb.apiroute.wrapper.util; + +import javax.servlet.http.HttpServletRequest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import redis.clients.jedis.Jedis; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({HttpServletRequest.class}) +public class MicroServiceUtilTest { + + @Test + public void test_getPrefixedKey(){ + Assert.assertEquals("discover:microservices:test:v1",MicroServiceUtil.getPrefixedKey("test","v1")); + } + + @Test + public void test_getServiceKey(){ + Assert.assertEquals("discover:microservices:test:v1",MicroServiceUtil.getServiceKey("test","v1")); + } + + @Test + public void test_getRealIp(){ + HttpServletRequest request=PowerMockito.mock(HttpServletRequest.class); + PowerMockito.when(request.getHeader("X-Forwarded-For")).thenReturn("127.0.0.1"); + Assert.assertEquals("127.0.0.1",MicroServiceUtil.getRealIp(request)); + + PowerMockito.when(request.getHeader("X-Forwarded-For")).thenReturn(""); + PowerMockito.when(request.getHeader("X-Real-IP")).thenReturn("127.0.0.2"); + Assert.assertEquals("127.0.0.2",MicroServiceUtil.getRealIp(request)); + + PowerMockito.when(request.getHeader("X-Forwarded-For")).thenReturn(""); + PowerMockito.when(request.getHeader("X-Real-IP")).thenReturn(""); + PowerMockito.when(request.getRemoteAddr()).thenReturn("127.0.0.3"); + Assert.assertEquals("127.0.0.3",MicroServiceUtil.getRealIp(request)); + + } +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtilTest.java new file mode 100644 index 0000000..11e5907 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RegExpTestUtilTest.java @@ -0,0 +1,96 @@ +/** + * 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.junit.Assert; +import org.junit.Test; +import org.onap.msb.apiroute.wrapper.util.RegExpTestUtil; + +public class RegExpTestUtilTest { + + @Test + public void test_HostRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.hostRegExpTest("127.0.0.1:8080")); + Assert.assertFalse(RegExpTestUtil.hostRegExpTest("0.0.0.1:89")); + } + + + + @Test + public void test_IpRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.ipRegExpTest("127.0.0.1")); + Assert.assertFalse(RegExpTestUtil.ipRegExpTest("127.0.0.1.5")); + } + + + + @Test + public void test_PortRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.portRegExpTest("80")); + Assert.assertFalse(RegExpTestUtil.portRegExpTest("898989")); + } + + + @Test + public void test_VersionRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.versionRegExpTest("v1")); + Assert.assertFalse(RegExpTestUtil.versionRegExpTest("23")); + } + + + + @Test + public void test_urlRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.urlRegExpTest("/test")); + Assert.assertTrue(RegExpTestUtil.urlRegExpTest("/")); + Assert.assertFalse(RegExpTestUtil.urlRegExpTest("test")); + } + + + @Test + public void test_apiRouteUrlRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.apiRouteUrlRegExpTest("/api/test/v1")); + Assert.assertFalse(RegExpTestUtil.apiRouteUrlRegExpTest("/test")); + } + + + + @Test + public void test_iuiRouteUrlRegExpTest(){ + Assert.assertTrue(RegExpTestUtil.iuiRouteUrlRegExpTest("/iui/test")); + Assert.assertFalse(RegExpTestUtil.iuiRouteUrlRegExpTest("/test")); + } + + @Test + public void test_apiServiceNameMatch4URL(){ + String[] apiServiceNameArray={"testApiName","v1"}; + Assert.assertArrayEquals(apiServiceNameArray, RegExpTestUtil.apiServiceNameMatch4URL("/api/testApiName/v1")); + + String[] apiServiceNameArray_noversion={"testApiName",""}; + Assert.assertArrayEquals(apiServiceNameArray_noversion, RegExpTestUtil.apiServiceNameMatch4URL("/api/testApiName")); + + Assert.assertNull(RegExpTestUtil.apiServiceNameMatch4URL("/apiw/name/v1")); + } + + @Test + public void test_iuiServiceNameMatch4URL(){ + String iuiServiceName="testIuiName"; + Assert.assertEquals(iuiServiceName, RegExpTestUtil.iuiServiceNameMatch4URL("/iui/testIuiName")); + + Assert.assertNull(RegExpTestUtil.iuiServiceNameMatch4URL("/api/name/v1")); + } + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RouteUtilTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RouteUtilTest.java new file mode 100644 index 0000000..7ddab84 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/RouteUtilTest.java @@ -0,0 +1,373 @@ +/** + * 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.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +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; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ConfigUtil.class}) +public class RouteUtilTest { + + @Test + public void test_getPrefixedKey() { + Assert.assertEquals("msb:routing:test:v1", RouteUtil.getPrefixedKey("", "test", "v1")); + Assert.assertEquals("msb:5656:test:v1", RouteUtil.getPrefixedKey("5656", "test", "v1")); + + } + + @Test + public void test_getPrefixedKey4Host() { + Assert.assertEquals("msb:host:test:v1", RouteUtil.getPrefixedKey4Host("test", "v1")); + + } + + + + @Test + public void test_checkRouteWay() { + try { + RouteUtil.checkRouteWay("ipp"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + + } + + @Test + public void test_checkServiceNameAndVersion() { + try { + RouteUtil.checkServiceNameAndVersion("","v1"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + + try { + RouteUtil.checkServiceNameAndVersion("test","ve1"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkServiceStatus() { + try { + RouteUtil.checkServiceStatus("2"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkRouterInfoFormat() { + RouteInfo routeInfo=new RouteInfo(); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,""); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat_ip() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("name"); + microServiceInfo.setProtocol("REST"); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88.22","8080")); + microServiceInfo.setNodes(nodeSet); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,""); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat_port() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("name"); + microServiceInfo.setProtocol("REST"); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("10.74.148.88.22","808770")); + microServiceInfo.setNodes(nodeSet); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,""); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat_version() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("name"); + microServiceInfo.setProtocol("REST"); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("","8089")); + microServiceInfo.setNodes(nodeSet); + microServiceInfo.setVersion("cv2"); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,"10.74.55.36"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat_url() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("name"); + microServiceInfo.setProtocol("REST"); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("","8089")); + microServiceInfo.setNodes(nodeSet); + microServiceInfo.setVersion("v2"); + microServiceInfo.setUrl("url"); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,"10.74.55.36"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkMicroServiceInfoFormat_protocol() { + MicroServiceFullInfo microServiceInfo=new MicroServiceFullInfo(); + microServiceInfo.setServiceName("name"); + microServiceInfo.setProtocol("REST2"); + Set nodeSet = new HashSet<>(); + nodeSet.add(new Node("","8089")); + microServiceInfo.setNodes(nodeSet); + microServiceInfo.setVersion("v2"); + microServiceInfo.setUrl("/url"); + + try { + RouteUtil.checkMicroServiceInfoFormat(microServiceInfo,"10.74.55.36"); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_getAPIRedisPrefixedKey() { + Assert.assertEquals("msb:20081:api:testApi:v1", RouteUtil.getAPIRedisPrefixedKey("testApi", "v1", "testHost","20081","ip")); + Assert.assertEquals("msb:routing:api:testApi:v1", RouteUtil.getAPIRedisPrefixedKey("testApi", "v1", "testHost","","ip")); + Assert.assertEquals("msb:host:testHost:api:testApi:v1", RouteUtil.getAPIRedisPrefixedKey("testApi", "v1", "testHost","20081","domain")); + } + + @Test + public void test_getRedisPrefixedKey() { + Assert.assertEquals("msb:20081:custom:/testName/v1", RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE,"/testName/v1", "testHost","20081","ip")); + Assert.assertEquals("msb:routing:custom:/testName/v1", RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE,"/testName/v1", "testHost","","ip")); + Assert.assertEquals("msb:host:testHost:custom:/testName/v1", RouteUtil.getRedisPrefixedKey(RouteUtil.CUSTOMROUTE,"/testName/v1", "testHost","20081","domain")); + + Assert.assertEquals("msb:20081:iui:testName", RouteUtil.getRedisPrefixedKey(RouteUtil.IUIROUTE,"testName", "testHost","20081","ip")); + Assert.assertEquals("msb:routing:iui:testName", RouteUtil.getRedisPrefixedKey(RouteUtil.IUIROUTE,"testName", "testHost","","ip")); + Assert.assertEquals("msb:host:testHost:iui:testName", RouteUtil.getRedisPrefixedKey(RouteUtil.IUIROUTE,"testName", "testHost","20081","domain")); + } + + @Test + public void test_getMutiRedisKey() { + Assert.assertEquals("msb:[^h]*:api:*", RouteUtil.getMutiRedisKey(RouteUtil.APIROUTE,"ip")); + Assert.assertEquals("msb:[^h]*:iui:*", RouteUtil.getMutiRedisKey(RouteUtil.IUIROUTE,"ip")); + Assert.assertEquals("msb:[^h]*:custom:*", RouteUtil.getMutiRedisKey(RouteUtil.CUSTOMROUTE,"ip")); + + Assert.assertEquals("msb:host:*:api:*", RouteUtil.getMutiRedisKey(RouteUtil.APIROUTE,"domain")); + Assert.assertEquals("msb:host:*:iui:*", RouteUtil.getMutiRedisKey(RouteUtil.IUIROUTE,"domain")); + Assert.assertEquals("msb:host:*:custom:*", RouteUtil.getMutiRedisKey(RouteUtil.CUSTOMROUTE,"domain")); + } + + @Test + public void test_getRouteNameByns() { + Assert.assertEquals("serviceName", RouteUtil.getRouteNameByns("serviceName","")); + Assert.assertEquals("serviceName", RouteUtil.getRouteNameByns("serviceName-ns","ns")); + Assert.assertEquals("serviceName-ns", RouteUtil.getRouteNameByns("serviceName-ns-ns","ns")); + Assert.assertEquals("serviceName", RouteUtil.getRouteNameByns("serviceName","default")); + } + + @Test + public void test_getVisualRangeByRouter(){ + Assert.assertEquals("0", RouteUtil.getVisualRangeByRouter("0|1")); + Assert.assertEquals("1", RouteUtil.getVisualRangeByRouter("1")); + Assert.assertEquals("0", RouteUtil.getVisualRangeByRouter("0")); + + + } + + @Test + public void test_getVisualRangeByRouter_muti(){ + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("lab1:val,visualRange:0|1"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertEquals("0", RouteUtil.getVisualRangeByRouter("0|1")); + } + + @Test + public void test_checkRouterInfoFormat_url() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkRouterInfoFormat_visualRangeRange() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + routeInfo.setVisualRange("2"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + + @Test + public void test_checkRouterInfoFormat_controlRangeMatches() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + routeInfo.setVisualRange("0"); + routeInfo.setControl("3"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkRouterInfoFormat_statusRangeMatches() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + routeInfo.setVisualRange("0"); + routeInfo.setControl("0"); + routeInfo.setStatus("3"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + + @Test + public void test_checkRouterInfoFormat_useOwnUpstreamRangeMatches() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88","8080")}); + routeInfo.setVisualRange("0"); + routeInfo.setControl("0"); + routeInfo.setStatus("0"); + routeInfo.setUseOwnUpstream("3"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + @Test + public void test_checkRouterInfoFormat_ip() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88.6","8080")}); + routeInfo.setVisualRange("0"); + routeInfo.setControl("0"); + routeInfo.setStatus("0"); + routeInfo.setUseOwnUpstream("1"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + + @Test + public void test_checkRouterInfoFormat_port() { + RouteInfo routeInfo=new RouteInfo(); + routeInfo.setServiceName("name"); + routeInfo.setUrl("/url"); + routeInfo.setServers( new RouteServer[]{new RouteServer("10.74.148.88.6","757577")}); + routeInfo.setVisualRange("0"); + routeInfo.setControl("0"); + routeInfo.setStatus("0"); + routeInfo.setUseOwnUpstream("1"); + + try { + RouteUtil.checkRouterInfoFormat(routeInfo); + } catch (Exception e) { + Assert.assertTrue(e instanceof UnprocessableEntityException); + } + } + + + + + + + + +} diff --git a/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ServiceFilterTest.java b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ServiceFilterTest.java new file mode 100644 index 0000000..e7c6531 --- /dev/null +++ b/apiroute/apiroute-service/src/test/java/org/onap/msb/apiroute/wrapper/util/ServiceFilterTest.java @@ -0,0 +1,210 @@ +package org.onap.msb.apiroute.wrapper.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.msb.apiroute.api.MicroServiceFullInfo; +import org.onap.msb.apiroute.api.Node; +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.util.ConfigUtil; +import org.onap.msb.apiroute.wrapper.util.ServiceFilter; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.orbitz.consul.model.health.ImmutableNode; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ConfigUtil.class}) +public class ServiceFilterTest { + + + + @Test + public void test_isNeedNotifyByNameSpace() { + + PowerMockito.mockStatic(System.class); + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("all"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("test")); // namespaceMatches:all + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("default"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace("test"));// namespaceMatches:default + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace(""));// namespaceMatches:default + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("default"));// namespaceMatches:default + + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("!default"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("test"));// namespaceMatches:!default + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace(""));// namespaceMatches:!default + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("ns|ns2"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns2")); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns3")); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace("")); + + + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("!ns&!ns2"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns")); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns2")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNameSpace("ns3")); + + } + + /* + * @Test public void test_isNeedNotifyByVisualRange(){ + * + * Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByVisualRange("0")); + * Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByVisualRange("1")); + * Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByVisualRange("0|1")); } + */ + + @Test + public void test_isNeedNotifyByProtocol() { + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByProtocol("HTTP")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByProtocol("UI")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByProtocol("REST")); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByProtocol("TCP")); + } + + @Test + public void test_isNeedNotifyByNetwork_plane_typeMatches() { + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("network_plane_type:network"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNetwork_plane_typeMatches("net")); + Assert.assertTrue(ServiceFilter.getInstance() + .isNeedNotifyByNetwork_plane_typeMatches("network")); + + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("network_plane_type:net1|net2"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByNetwork_plane_typeMatches("net")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNetwork_plane_typeMatches("net1")); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByNetwork_plane_typeMatches("net2")); + + } + + @Test + public void test_isNeedNotifyByRouteLabels() { + Map labelMap = new HashMap(); + labelMap.put("lab1", "val1"); + + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("lab1:val,visualRange:1"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertFalse(ServiceFilter.getInstance().isNeedNotifyByRouteLabels(labelMap)); + + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn("lab1:val1"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + Assert.assertTrue(ServiceFilter.getInstance().isNeedNotifyByRouteLabels(labelMap)); + + } + + @Test + public void test_isFilterService() { + PowerMockito.mockStatic(System.class); + PowerMockito.when(System.getenv("NAMESPACE")).thenReturn("ns1"); + ConfigUtil.getInstance().initRouteNameSpaceMatches(); + + PowerMockito.when(System.getenv("ROUTE_LABELS")).thenReturn( + "visualRange:0,network_plane_type:net,customLabel:custom|custom2"); + ConfigUtil.getInstance().initRouteLabelsMatches(); + + List tagList = new ArrayList(); + tagList.add("\"base\":{\"protocol\":\"REST\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + Assert.assertTrue(ServiceFilter.getInstance().isFilterService(tagList)); + + tagList.clear(); + tagList.add("\"base\":{\"protocol\":\"TCP\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + Assert.assertFalse(ServiceFilter.getInstance().isFilterService(tagList)); + + tagList.clear(); + tagList.add("\"base\":{\"protocol\":\"UI\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns2\"}"); + Assert.assertFalse(ServiceFilter.getInstance().isFilterService(tagList)); + + tagList.clear(); + tagList.add("\"base\":{\"protocol\":\"UI\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"1\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + Assert.assertFalse(ServiceFilter.getInstance().isFilterService(tagList)); + + tagList.clear(); + tagList.add("\"base\":{\"protocol\":\"UI\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net2\",\"customLabel\":\"custom\"}"); + Assert.assertFalse(ServiceFilter.getInstance().isFilterService(tagList)); + + tagList.clear(); + tagList.add("\"base\":{\"protocol\":\"UI\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom3\"}"); + Assert.assertFalse(ServiceFilter.getInstance().isFilterService(tagList)); + + } + + @Test + public void test_transMicroServiceInfoFromConsul() { + List tagList = new ArrayList(); + tagList.add("\"base\":{\"protocol\":\"REST\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"); + tagList + .add("\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"); + tagList.add("\"ns\":{\"namespace\":\"ns1\"}"); + + Service service = + ImmutableService.builder().id("id").port(8686).address("10.74.165.246").service("msbtest") + .addAllTags(tagList).createIndex(0).modifyIndex(0).build(); + ServiceHealth serviceHealth = + ImmutableServiceHealth.builder().service(service) + .node(ImmutableNode.builder().node("server").address("192.168.1.98").build()).build(); + List serviceHealthList = new ArrayList(); + serviceHealthList.add(serviceHealth); + + Map serviceMap= ServiceFilter.getInstance().transMicroServiceInfoFromConsul(serviceHealthList); + Assert.assertTrue(serviceMap.containsKey("v1")); + + MicroServiceFullInfo microService=new MicroServiceFullInfo(); + microService.setServiceName("msbtest"); + microService.setVersion("v1"); + microService.setUrl("/api/msbtest/v1"); + microService.setProtocol("REST"); + microService.setVisualRange("0"); + microService.setNamespace("ns1"); + + Set nodes=new HashSet(); + nodes.add(new Node("10.74.165.246","8686")); + microService.setNodes(nodes); + + + + Assert.assertEquals(microService,serviceMap.get("v1")); + + + } + + + +} diff --git a/apiroute/apiroute-service/src/test/resources/ext/initApiGatewayConfig/initApiGatewayConfig.json b/apiroute/apiroute-service/src/test/resources/ext/initApiGatewayConfig/initApiGatewayConfig.json new file mode 100644 index 0000000..67580e1 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initApiGatewayConfig/initApiGatewayConfig.json @@ -0,0 +1,3 @@ +{ + "port" : "80" +} diff --git a/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json new file mode 100644 index 0000000..80826f2 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json @@ -0,0 +1,12 @@ +{ + "namespace":"all", + "predefineLabels": + { + "visualRange" : "0", + "network_plane_type":"net" + }, + "customLabels": + { + "custom-key":"custom-value" + } +} diff --git a/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json.sample b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json.sample new file mode 100644 index 0000000..1ffdbc1 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/initRouteLabelsMatches.json.sample @@ -0,0 +1,12 @@ +{ + "namespace":"all", + "predefineLabels": + { + "visualRange" : "0", + "network_plane_type":"" + }, + "customLabels": + { + "customLabel":"" + } +} diff --git a/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/readme.txt b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/readme.txt new file mode 100644 index 0000000..3e95c5c --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initRouteLabels/readme.txt @@ -0,0 +1,17 @@ +Apigateway can synchronized service informations from the service discovery by configuring filter tag¡£ +Synchronization filter configuration file path£ºapiroute\ext\initRouteLabels\initVisualRangeMatches.json, +{ + "namespace":"", + "routeLabels": + { + "visualRange" : "0", + "network_plane_type":"" + } +} +namespaceΪÃüÁî¿Õ¼ä¹ýÂËÌõ¼þ£¬ÖµÎª¿ÕÔòºöÂÔ´ËÏî¹ýÂË£¬·ñÔòÖ»ÓзþÎñnamespaceÊôÐÔÓëÌõ¼þÒ»ÖµķþÎñ²Å½øÐÐÏÂÒ»²½µÄ×Ô¶¨Òå±êÇ©Æ¥Åä¡£ +routeLabelsΪ×Ô¶¨Òå±êÇ©£¬Óû§¿É×Ô¶¨Òå¼üÖµ¶ÔÆ¥ÅäÌõ¼þ£¬Ö§³Ö¶àÏîÖµ£¬ÒÔ|·Ö¸ô¡£ÈÎÒ»¸ö±êÇ©µÄÖµÂú×㼴ͬ²½ +µ±Í¬²½·þÎñÐÅϢʱʹÓÃvisualRangeÕâ¸ö±êǩɸѡ£¬È¡Öµ·¶Î§ ϵͳ¼ä:0£¨Ä¬ÈÏ£© ϵͳÄÚ:1£¬ÆäÖÐϵͳ¼ä½«¶Ô·þÎñ·ÓÉ·ÃÎÊ×ö¼øȨ´¦Àí¡£ + +Èç¹ûÊÇdocker²¿ÊðÊ×Ñ¡ÔÚapigatewayËùÔÚÈÝÆ÷ÅäÖÃenv»·¾³±äÁ¿»ñÈ¡£º +±äÁ¿Ãû£ºNAMESPACE +±äÁ¿Ãû£ºROUTE_LABELS ±äÁ¿Öµ¸ñʽ£ºvisualRange£º0; network_plane_type:xx|yy diff --git a/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/initRouteWay.json b/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/initRouteWay.json new file mode 100644 index 0000000..b6ebf27 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/initRouteWay.json @@ -0,0 +1,3 @@ +{ + "routeWay":"ip" +} \ No newline at end of file diff --git a/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/readme.txt b/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/readme.txt new file mode 100644 index 0000000..c219550 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initRouteWay/readme.txt @@ -0,0 +1,5 @@ +Apigateway ·ÓÉ·½Ê½£ºip/domain; ĬÈÏΪip + +Èç¹ûÊÇdocker²¿ÊðÊ×Ñ¡ÔÚapigatewayËùÔÚÈÝÆ÷ÅäÖÃenv»·¾³±äÁ¿»ñÈ¡£º +±äÁ¿Ãû£ºROUTE_WAY ±äÁ¿¿ÉÑ¡Öµ£ºip/domain + diff --git a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/msb.json b/apiroute/apiroute-service/src/test/resources/ext/initServices/msb.json similarity index 62% rename from msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/msb.json rename to apiroute/apiroute-service/src/test/resources/ext/initServices/msb.json index 5df59e2..43b795d 100644 --- a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/msb.json +++ b/apiroute/apiroute-service/src/test/resources/ext/initServices/msb.json @@ -1,53 +1,44 @@ -[{ - "serviceName" : "microservices", - "version" : "v1", - "url" : "/api/microservices/v1", - "apiJson" : "/api/microservices/v1/swagger.json", - "apiJsonType" : "1", - "metricsUrl" : "/admin/metrics", - "control" : "1", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8086", - "weight" : 0 - } - ] - }, -{ - "serviceName" : "microservices", - "url" : "/iui/microservices", - "control" : "1", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8086", - "weight" : 0 - } - ] - }, - { - "serviceName" : "/winery-topologymodeler", - "url" : "/winery-topologymodeler", - "control" : "0", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8202", - "weight" : 0 - } - ] - }, - { - "serviceName" : "/winery", - "url" : "/winery", - "control" : "0", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8202", - "weight" : 0 - } - ] - } -] +[{ + "serviceName" : "microservices", + "version" : "v1", + "url" : "/api/microservices/v1", + "apiJson" : "/api/microservices/v1/swagger.json", + "apiJsonType" : "1", + "metricsUrl" : "/admin/metrics", + "control" : "1", + "status" : "1", + "host":"msb", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8066", + "weight" : 0 + } + ] + }, +{ + "serviceName" : "microservices", + "url" : "/iui/microservices", + "control" : "1", + "status" : "1", + "host":"msb", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8066", + "weight" : 0 + } + ] + }, + { + "serviceName" : "/custom", + "url" : "/custom", + "control" : "1", + "status" : "1", + "host":"msb", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8066", + "weight" : 0 + } + ] + } +] diff --git a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/readme.txt b/apiroute/apiroute-service/src/test/resources/ext/initServices/readme.txt similarity index 65% rename from msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/readme.txt rename to apiroute/apiroute-service/src/test/resources/ext/initServices/readme.txt index 2df5d10..59ef5e4 100644 --- a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initServices/readme.txt +++ b/apiroute/apiroute-service/src/test/resources/ext/initServices/readme.txt @@ -1,82 +1,63 @@ -==== - Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. - - 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. - - Author: Zhaoxing Meng - email: meng.zhaoxing1@zte.com.cn -==== - -########################## initialize default routeInfo to redis ########################## - -#when msb is starting, it will automatically read all json files under this folder, and initializes to redis. -#If the routeInfo is exist, it will be ignored, otherwise it will be saved. - - -# JSON File content must be routeInfo format array like below examples: - -# optional: -# apiJsonType: 1:user-defined json type 0:pre-defined json type -# control: 0:default 1:readonly 2:hidden -# status: 0:disabled 1:enabled -# Tip��control��status��weight are non-mandatory - -[ -##########################apiRoute example########################## - -{ - "serviceName" : "microservices", - "version" : "v1", - "url" : "/api/microservices/v1", - "apiJson" : "/api/microservices/v1/swagger.json", - "apiJsonType" : "1", - "metricsUrl" : "/admin/metrics", - "control" : "1", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8086", - "weight" : 0 - } - ] - }, - -##########################iuiRoute example########################## - -{ - "serviceName" : "microservices", - "url" : "/iui/microservices", - "control" : "1", - "status" : "1", - "servers" : [{ - "ip" : "127.0.0.1", - "port" : "8086", - "weight" : 0 - } - ] - }, - -##########################customRoute example########################## - { - "serviceName" : "/test", - "url" : "/test", - "control" : "0", - "status" : "1", - "servers" : [{ - "ip" : "10.74.56.36", - "port" : "8989", - "weight" : 0 - } - ] - } +########################## initialize default routeInfo to redis ########################## + +#when msb is starting, it will automatically read all json files under this folder, and initializes to redis. +#If the routeInfo is exist, it will be ignored, otherwise it will be saved. + + +# JSON File content must be routeInfo format array like below examples: + +# optional: +# apiJsonType: 1:user-defined json type 0:pre-defined json type +# control: 0:default 1:readonly 2:hidden +# status: 0:disabled 1:enabled +# Tip£ºcontrol¡¢status¡¢weight are non-mandatory + +[ +##########################apiRoute example########################## + +{ + "serviceName" : "microservices", + "version" : "v1", + "url" : "/api/microservices/v1", + "apiJson" : "/api/microservices/v1/swagger.json", + "apiJsonType" : "1", + "metricsUrl" : "/admin/metrics", + "control" : "1", + "status" : "1", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8086", + "weight" : 0 + } + ] + }, + +##########################iuiRoute example########################## + +{ + "serviceName" : "microservices", + "url" : "/iui/microservices", + "control" : "1", + "status" : "1", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8086", + "weight" : 0 + } + ] + }, + +##########################customRoute example########################## + { + "serviceName" : "/test", + "url" : "/test", + "control" : "0", + "status" : "1", + "servers" : [{ + "ip" : "10.74.56.36", + "port" : "8989", + "weight" : 0 + } + ] + } ] \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initSwaggerJson/api-doc1.json b/apiroute/apiroute-service/src/test/resources/ext/initSwaggerJson/api-doc1.json similarity index 100% rename from msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initSwaggerJson/api-doc1.json rename to apiroute/apiroute-service/src/test/resources/ext/initSwaggerJson/api-doc1.json diff --git a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initSwaggerJson/api-doc2.json b/apiroute/apiroute-service/src/test/resources/ext/initSwaggerJson/api-doc2.json similarity index 100% rename from msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/ext/initSwaggerJson/api-doc2.json rename to apiroute/apiroute-service/src/test/resources/ext/initSwaggerJson/api-doc2.json diff --git a/apiroute/apiroute-service/src/test/resources/ext/initUrlRootPath/initUrlRootPath.json b/apiroute/apiroute-service/src/test/resources/ext/initUrlRootPath/initUrlRootPath.json new file mode 100644 index 0000000..9668592 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/initUrlRootPath/initUrlRootPath.json @@ -0,0 +1,4 @@ +{ + "iuiRootPath" : "iui", + "apiRootPath" : "api" +} diff --git a/apiroute/apiroute-service/src/test/resources/ext/redisConf/redis.properties b/apiroute/apiroute-service/src/test/resources/ext/redisConf/redis.properties new file mode 100644 index 0000000..3703748 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/ext/redisConf/redis.properties @@ -0,0 +1,18 @@ +redis.host=127.0.0.1 +redis.port=6379 +#connectionTimeout +redis.connectionTimeout=2000 +#redis dbIndex,defaule:0 +redis.db_index=0 + +#--------------redis pool config-------------- +#maxTotal +redis.pool.maxTotal=500 +#maxIdle +redis.pool.maxIdle=100 +#maxWaitMillis:ms +redis.pool.maxWaitMillis=15000 +#testOnBorrow +redis.pool.testOnBorrow=false +#testOnReturn +redis.pool.testOnReturn=true diff --git a/apiroute/apiroute-service/src/test/resources/org/onap/msb/apiroute/wrapper/consulextend/util/serviceslist.json b/apiroute/apiroute-service/src/test/resources/org/onap/msb/apiroute/wrapper/consulextend/util/serviceslist.json new file mode 100644 index 0000000..5139ca8 --- /dev/null +++ b/apiroute/apiroute-service/src/test/resources/org/onap/msb/apiroute/wrapper/consulextend/util/serviceslist.json @@ -0,0 +1 @@ +{"aaa-aaa":["\"ns\":{\"namespace\":\"aaa\"}","\"base\":{\"version\":\"v1\",\"protocol\":\"UI\",\"url\":\"/iui\",\"enable_ssl\":\"false\",\"is_manual\":\"true\",\"status\":\"1\"}","\"lb\":{\"lb_policy\":\"\"}","\"labels\":{\"visualRange\":\"1\"}"],"apigateway-default":["\"base\":{\"url\":\"/api/microservices/v1\",\"protocol\":\"REST\",\"version\":\"v1\"}","\"labels\":{\"visualRange\":\"1\"}","\"metadata\":{\"routeWay\":\"ip\"}","\"ns\":{\"namespace\":\"default\"}"],"authen":["\"lb\":{\"lb_policy\":\"\"}","\"labels\":{\"visualRange\":\"1\"}","\"base\":{\"version\":\"v1\",\"protocol\":\"HTTP\",\"url\":\"/authen/v1\",\"enable_ssl\":\"false\",\"is_manual\":\"false\",\"status\":\"1\",\"ha_role\":\"active\"}"],"author":["\"base\":{\"version\":\"v1\",\"protocol\":\"HTTP\",\"url\":\"/author/v1\",\"enable_ssl\":\"false\",\"is_manual\":\"false\",\"status\":\"1\",\"ha_role\":\"active\"}","\"lb\":{\"lb_policy\":\"\"}","\"labels\":{\"visualRange\":\"1\"}"],"bbb-bbb":["\"ns\":{\"namespace\":\"bbb\"}","\"base\":{\"version\":\"v1\",\"protocol\":\"HTTP\",\"url\":\"/iui/component\",\"enable_ssl\":\"false\",\"is_manual\":\"true\",\"status\":\"1\"}","\"lb\":{\"lb_policy\":\"\"}","\"labels\":{\"visualRange\":\"1\"}"],"br-engine":["\"base\":{\"version\":\"v1\",\"protocol\":\"HTTP\",\"url\":\"/br-engine/v1\",\"enable_ssl\":\"false\",\"is_manual\":\"false\",\"status\":\"1\",\"ha_role\":\"active\"}","\"lb\":{\"lb_policy\":\"\"}","\"labels\":{\"visualRange\":\"0|1\"}"]} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-standalone/pom.xml b/apiroute/apiroute-standalone/pom.xml similarity index 79% rename from msb-core/apiroute/apiroute-standalone/pom.xml rename to apiroute/apiroute-standalone/pom.xml index eac7c60..d304385 100644 --- a/msb-core/apiroute/apiroute-standalone/pom.xml +++ b/apiroute/apiroute-standalone/pom.xml @@ -1,57 +1,54 @@ - org.openo.common-services.microservice-bus + org.onap.msb.apigateway.apiroute apiroute-parent - 1.1.0-SNAPSHOT + 0.0.1-SNAPSHOT 4.0.0 + org.onap.msb.apigateway.apiroute apiroute-standalone - common-services-microservice-bus/msb-core/apiroute/apiroute-standalone + onap/msb/apigateway/apiroute/apiroute-standalone pom - 1.1.0-SNAPSHOT + 0.0.1-SNAPSHOT - apiroute-standalone + apiroute target/assembly/ - org.openo.common-services.microservice-bus + org.onap.msb.apigateway.apiroute apiroute-service ${project.version} true - + - - + + maven-resources-plugin - copy-resources + copy-resources process-resources copy-resources @@ -59,14 +56,14 @@ ${outputdir} true - + - src/assembly/resource/ + src/assembly/resources/ false **/* - + true @@ -77,7 +74,7 @@ org.apache.maven.plugins maven-dependency-plugin 2.8 - + copy-jar @@ -87,19 +84,19 @@ - org.openo.common-services.microservice-bus + org.onap.msb.apigateway.apiroute apiroute-service jar true ${outputdir}/apiroute/ apiroute-service.jar - + - + org.apache.maven.plugins maven-antrun-plugin @@ -116,7 +113,6 @@ - @@ -126,3 +122,4 @@ + diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/conf/apiroute.yml b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/conf/apiroute.yml new file mode 100644 index 0000000..04c3531 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/conf/apiroute.yml @@ -0,0 +1,47 @@ +defaultWorkspace: ../apiroute-works + +defaultName: ${DW_DEFAULT_NAME:-Stranger} + + +# use the discover config if you want to monitor a discover service and register microservices change +discoverInfo: + ip: 127.0.0.1 + port: 10081 + enabled: true + + +# use the simple server factory if you only want to run on a single port +server: + type: simple + rootPath: '/api/microservices/v1/*' + applicationContextPath: / + adminContextPath: /admin + connector: + type: http + port: 8066 + +# Logging settings. +logging: + + # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL. + level: ALL + + # Logger-specific levels. + loggers: + + # Sets the level for 'com.example.app' to DEBUG. + com.example: DEBUG + + appenders: + - type: console + threshold: WARN + timeZone: UTC + logFormat: "%d{yyyy-MM-dd HH:mm:ss SSS} %-5p [%c][%t] - %m%n" + - type: file + threshold: INFO + logFormat: "%d{yyyy-MM-dd HH:mm:ss SSS} %-5p [%c][%t] - %m%n" + currentLogFilename: ../apiroute-works/logs/msb-apiroute.log + archivedLogFilenamePattern: ../apiroute-works/logs/zip/msb-apiroute-%d{yyyy-MM-dd}.log.gz + archivedFileCount: 7 + timeZone: UTC + diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initApiGatewayConfig/initApiGatewayConfig.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initApiGatewayConfig/initApiGatewayConfig.json new file mode 100644 index 0000000..67580e1 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initApiGatewayConfig/initApiGatewayConfig.json @@ -0,0 +1,3 @@ +{ + "port" : "80" +} diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json new file mode 100644 index 0000000..44fb07e --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json @@ -0,0 +1,7 @@ +{ + "namespace":"all", + "predefineLabels": + { + "visualRange" : "0" + } +} diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json.sample b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json.sample new file mode 100644 index 0000000..6743912 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/initRouteLabelsMatches.json.sample @@ -0,0 +1,12 @@ +{ + "namespace":"all", + "predefineLabels": + { + "visualRange" : "0", + "network_plane_type":"" + }, + "customLabels": + { + "custom-key":"custom-value" + } +} diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/readme.txt b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/readme.txt new file mode 100644 index 0000000..3e95c5c --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteLabels/readme.txt @@ -0,0 +1,17 @@ +Apigateway can synchronized service informations from the service discovery by configuring filter tag¡£ +Synchronization filter configuration file path£ºapiroute\ext\initRouteLabels\initVisualRangeMatches.json, +{ + "namespace":"", + "routeLabels": + { + "visualRange" : "0", + "network_plane_type":"" + } +} +namespaceΪÃüÁî¿Õ¼ä¹ýÂËÌõ¼þ£¬ÖµÎª¿ÕÔòºöÂÔ´ËÏî¹ýÂË£¬·ñÔòÖ»ÓзþÎñnamespaceÊôÐÔÓëÌõ¼þÒ»ÖµķþÎñ²Å½øÐÐÏÂÒ»²½µÄ×Ô¶¨Òå±êÇ©Æ¥Åä¡£ +routeLabelsΪ×Ô¶¨Òå±êÇ©£¬Óû§¿É×Ô¶¨Òå¼üÖµ¶ÔÆ¥ÅäÌõ¼þ£¬Ö§³Ö¶àÏîÖµ£¬ÒÔ|·Ö¸ô¡£ÈÎÒ»¸ö±êÇ©µÄÖµÂú×㼴ͬ²½ +µ±Í¬²½·þÎñÐÅϢʱʹÓÃvisualRangeÕâ¸ö±êǩɸѡ£¬È¡Öµ·¶Î§ ϵͳ¼ä:0£¨Ä¬ÈÏ£© ϵͳÄÚ:1£¬ÆäÖÐϵͳ¼ä½«¶Ô·þÎñ·ÓÉ·ÃÎÊ×ö¼øȨ´¦Àí¡£ + +Èç¹ûÊÇdocker²¿ÊðÊ×Ñ¡ÔÚapigatewayËùÔÚÈÝÆ÷ÅäÖÃenv»·¾³±äÁ¿»ñÈ¡£º +±äÁ¿Ãû£ºNAMESPACE +±äÁ¿Ãû£ºROUTE_LABELS ±äÁ¿Öµ¸ñʽ£ºvisualRange£º0; network_plane_type:xx|yy diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/initRouteWay.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/initRouteWay.json new file mode 100644 index 0000000..b6ebf27 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/initRouteWay.json @@ -0,0 +1,3 @@ +{ + "routeWay":"ip" +} \ No newline at end of file diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/readme.txt b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/readme.txt new file mode 100644 index 0000000..c219550 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initRouteWay/readme.txt @@ -0,0 +1,5 @@ +Apigateway ·ÓÉ·½Ê½£ºip/domain; ĬÈÏΪip + +Èç¹ûÊÇdocker²¿ÊðÊ×Ñ¡ÔÚapigatewayËùÔÚÈÝÆ÷ÅäÖÃenv»·¾³±äÁ¿»ñÈ¡£º +±äÁ¿Ãû£ºROUTE_WAY ±äÁ¿¿ÉÑ¡Öµ£ºip/domain + diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/msb.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/msb.json new file mode 100644 index 0000000..c5d526a --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/msb.json @@ -0,0 +1,31 @@ +[{ + "serviceName" : "microservices", + "version" : "v1", + "url" : "/api/microservices/v1", + "apiJson" : "/api/microservices/v1/swagger.json", + "apiJsonType" : "1", + "metricsUrl" : "/admin/metrics", + "control" : "1", + "status" : "1", + "host":"msb", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8066", + "weight" : 0 + } + ] + }, + { + "serviceName" : "microservices", + "url" : "/iui/microservices", + "control" : "1", + "status" : "1", + "host":"msb", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8066", + "weight" : 0 + } + ] + } +] diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/readme.txt b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/readme.txt new file mode 100644 index 0000000..59ef5e4 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initServices/readme.txt @@ -0,0 +1,63 @@ +########################## initialize default routeInfo to redis ########################## + +#when msb is starting, it will automatically read all json files under this folder, and initializes to redis. +#If the routeInfo is exist, it will be ignored, otherwise it will be saved. + + +# JSON File content must be routeInfo format array like below examples: + +# optional: +# apiJsonType: 1:user-defined json type 0:pre-defined json type +# control: 0:default 1:readonly 2:hidden +# status: 0:disabled 1:enabled +# Tip£ºcontrol¡¢status¡¢weight are non-mandatory + +[ +##########################apiRoute example########################## + +{ + "serviceName" : "microservices", + "version" : "v1", + "url" : "/api/microservices/v1", + "apiJson" : "/api/microservices/v1/swagger.json", + "apiJsonType" : "1", + "metricsUrl" : "/admin/metrics", + "control" : "1", + "status" : "1", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8086", + "weight" : 0 + } + ] + }, + +##########################iuiRoute example########################## + +{ + "serviceName" : "microservices", + "url" : "/iui/microservices", + "control" : "1", + "status" : "1", + "servers" : [{ + "ip" : "127.0.0.1", + "port" : "8086", + "weight" : 0 + } + ] + }, + +##########################customRoute example########################## + { + "serviceName" : "/test", + "url" : "/test", + "control" : "0", + "status" : "1", + "servers" : [{ + "ip" : "10.74.56.36", + "port" : "8989", + "weight" : 0 + } + ] + } +] \ No newline at end of file diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc1.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc1.json new file mode 100644 index 0000000..7c63d7e --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc1.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"version":"1.0.0","title":"Local API Test"},"basePath":"/service","tags":[{"name":"ApiRoute"}],"paths":{"/apiRoute":{"get":{"tags":["ApiRoute"],"summary":"get all ApiRoute ","description":"","operationId":"getApiRoutes","produces":["application/json"],"parameters":[],"responses":{"200":{"description":"successful operation","schema":{"type":"array","items":{"$ref":"#/definitions/ApiRouteInfo"}}}}},"post":{"tags":["ApiRoute"],"summary":"add one ApiRoute ","description":"","operationId":"addApiRoute","produces":["application/json"],"parameters":[{"in":"body","name":"body","description":"ApiRoute Instance Info","required":true,"schema":{"$ref":"#/definitions/ApiRouteInfo"}}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteInfo"}},"500":{"description":"add ApiRoute error "}}}},"/apiRoute/type/{type}/{routeName}/version/{version}":{"get":{"tags":["ApiRoute"],"summary":"get one ApiRoute ","description":"","operationId":"getApiRoute","produces":["application/json"],"parameters":[{"name":"type","in":"path","description":"Route type","required":true,"type":"string","enum":["iui","api"]},{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteInfo"}},"500":{"description":"get ApiRoute error "}}},"delete":{"tags":["ApiRoute"],"summary":"delete one ApiRoute by routeName and version","description":"","operationId":"deleteApiRoute","produces":["application/json"],"parameters":[{"name":"type","in":"path","description":"Route type","required":true,"type":"string","enum":["iui","api"]},{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteResult"}},"500":{"description":"delete ApiRoute error "}}}},"/apiRoute/{routeName}/version/{version}":{"put":{"tags":["ApiRoute"],"summary":"update one ApiRoute by routeName and version","description":"","operationId":"updateApiRoute","produces":["application/json"],"parameters":[{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"},{"in":"body","name":"body","description":"ApiRoute Instance Info","required":true,"schema":{"$ref":"#/definitions/ApiRouteInfo"}}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteResult"}},"500":{"description":"update ApiRoute error "}}}}},"definitions":{"ApiRouteLifeCycle":{"type":"object","properties":{"installPath":{"type":"string"},"startScript":{"type":"string"},"stopScript":{"type":"string"}}},"ApiRouteServer":{"type":"object","properties":{"ip":{"type":"string"},"weight":{"type":"integer","format":"int32"}}},"ApiRouteResult":{"type":"object","properties":{"result":{"type":"string"},"info":{"type":"string"}}},"ApiRouteInfo":{"type":"object","properties":{"routeName":{"type":"string"},"version":{"type":"string"},"url":{"type":"string"},"apiJson":{"type":"string"},"type":{"type":"string"},"servers":{"type":"array","items":{"$ref":"#/definitions/ApiRouteServer"}},"lifeCycle":{"$ref":"#/definitions/ApiRouteLifeCycle"}}}}} \ No newline at end of file diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc2.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc2.json new file mode 100644 index 0000000..eb7c8cd --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initSwaggerJson/api-doc2.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"version":"1.0.0","title":"Local API Test2"},"basePath":"/service","tags":[{"name":"ApiRoute"}],"paths":{"/apiRoute":{"get":{"tags":["ApiRoute"],"summary":"get all ApiRoute ","description":"","operationId":"getApiRoutes","produces":["application/json"],"parameters":[],"responses":{"200":{"description":"successful operation","schema":{"type":"array","items":{"$ref":"#/definitions/ApiRouteInfo"}}}}},"post":{"tags":["ApiRoute"],"summary":"add one ApiRoute ","description":"","operationId":"addApiRoute","produces":["application/json"],"parameters":[{"in":"body","name":"body","description":"ApiRoute Instance Info","required":true,"schema":{"$ref":"#/definitions/ApiRouteInfo"}}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteInfo"}},"500":{"description":"add ApiRoute error "}}}},"/apiRoute/type/{type}/{routeName}/version/{version}":{"get":{"tags":["ApiRoute"],"summary":"get one ApiRoute ","description":"","operationId":"getApiRoute","produces":["application/json"],"parameters":[{"name":"type","in":"path","description":"Route type","required":true,"type":"string","enum":["iui","api"]},{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteInfo"}},"500":{"description":"get ApiRoute error "}}},"delete":{"tags":["ApiRoute"],"summary":"delete one ApiRoute by routeName and version","description":"","operationId":"deleteApiRoute","produces":["application/json"],"parameters":[{"name":"type","in":"path","description":"Route type","required":true,"type":"string","enum":["iui","api"]},{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteResult"}},"500":{"description":"delete ApiRoute error "}}}},"/apiRoute/{routeName}/version/{version}":{"put":{"tags":["ApiRoute"],"summary":"update one ApiRoute by routeName and version","description":"","operationId":"updateApiRoute","produces":["application/json"],"parameters":[{"name":"routeName","in":"path","description":"ApiRoute routeName","required":true,"type":"string"},{"name":"version","in":"path","description":"ApiRoute version","required":true,"type":"string"},{"in":"body","name":"body","description":"ApiRoute Instance Info","required":true,"schema":{"$ref":"#/definitions/ApiRouteInfo"}}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiRouteResult"}},"500":{"description":"update ApiRoute error "}}}}},"definitions":{"ApiRouteLifeCycle":{"type":"object","properties":{"installPath":{"type":"string"},"startScript":{"type":"string"},"stopScript":{"type":"string"}}},"ApiRouteServer":{"type":"object","properties":{"ip":{"type":"string"},"weight":{"type":"integer","format":"int32"}}},"ApiRouteResult":{"type":"object","properties":{"result":{"type":"string"},"info":{"type":"string"}}},"ApiRouteInfo":{"type":"object","properties":{"routeName":{"type":"string"},"version":{"type":"string"},"url":{"type":"string"},"apiJson":{"type":"string"},"type":{"type":"string"},"servers":{"type":"array","items":{"$ref":"#/definitions/ApiRouteServer"}},"lifeCycle":{"$ref":"#/definitions/ApiRouteLifeCycle"}}}}} \ No newline at end of file diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initUrlRootPath/initUrlRootPath.json b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initUrlRootPath/initUrlRootPath.json new file mode 100644 index 0000000..9668592 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/initUrlRootPath/initUrlRootPath.json @@ -0,0 +1,4 @@ +{ + "iuiRootPath" : "iui", + "apiRootPath" : "api" +} diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/redisConf/redis.properties b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/redisConf/redis.properties new file mode 100644 index 0000000..939e35b --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/ext/redisConf/redis.properties @@ -0,0 +1,18 @@ +redis.host=127.0.0.1 +redis.port=6379 +#connectionTimeout +redis.connectionTimeout=2000 +#redis dbIndex,defaule:0 +redis.db_index=0 + +#--------------redis pool config-------------- +#maxTotal +redis.pool.maxTotal=50 +#maxIdle +redis.pool.maxIdle=30 +#maxWaitMillis:ms +redis.pool.maxWaitMillis=5000 +#testOnBorrow +redis.pool.testOnBorrow=false +#testOnReturn +redis.pool.testOnReturn=true diff --git a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/run.sh b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/run.sh similarity index 50% rename from msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/run.sh rename to apiroute/apiroute-standalone/src/assembly/resources/apiroute/run.sh index 4094bb9..fad6b20 100644 --- a/msb-core/apiroute/apiroute-standalone/src/assembly/resource/apiroute/run.sh +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/run.sh @@ -1,12 +1,11 @@ -#!/bin/bash # -# Copyright 2016 ZTE Corporation. +# 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 +# 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, @@ -14,20 +13,33 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Author: Zhaoxing Meng -# email: meng.zhaoxing1@zte.com.cn -# -#JAVA_HOME="/home/conductortest/jdk1.7/jdk/linux" + +#!/bin/sh DIRNAME=`dirname $0` RUNHOME=`cd $DIRNAME/; pwd` echo @RUNHOME@ $RUNHOME -#JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::") -echo @JAVA_HOME@ $JAVA_HOME +if [ -f "$RUNHOME/setenv.sh" ]; then + . "$RUNHOME/setenv.sh" +else +echo "can not found $RUNHOME/setenv.sh" +fi + +echo ================== ENV_INFO ============================================= +echo @RUNHOME@ $RUNHOME +echo @JAVA_HOME@ $JAVA_HOME +echo @Main_Class@ $Main_Class +echo @APP_INFO@ $APP_INFO +echo @Main_JAR@ $Main_JAR +echo @Main_Conf@ $Main_Conf +echo ========================================================================== + +echo start $APP_INFO ... + JAVA="$JAVA_HOME/bin/java" -echo @JAVA@ $JAVA + JAVA_VERSION=`$JAVA -version 2>&1 |awk 'NR==1{ sub(/"/,""); print substr($3,1,3)}'` echo @JAVA_VERSION@ $JAVA_VERSION if [ $JAVA_VERSION = "1.8" ] @@ -36,11 +48,23 @@ then else JAVA_OPTS="-Xms16m -Xmx128m -XX:+UseSerialGC -XX:MaxPermSize=64m -XX:NewRatio=2" fi -port=8779 + +JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$RUNHOME/../apiroute-works/logs/dump-msb-$(date +%Y%m%d%H%M%S).hprof" +port=8777 #JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=$port,server=y,suspend=n" + +CLASS_PATH="$RUNHOME/:$RUNHOME/$Main_JAR" + +echo ================== RUN_INFO ============================================= +echo @JAVA_HOME@ $JAVA_HOME +echo @JAVA@ $JAVA echo @JAVA_OPTS@ $JAVA_OPTS +echo @CLASS_PATH@ $CLASS_PATH +echo @EXT_DIRS@ $EXT_DIRS +echo ========================================================================== + +echo @JAVA@ $JAVA +echo @JAVA_CMD@ +"$JAVA" $JAVA_OPTS -classpath "$CLASS_PATH" $Main_Class server "$RUNHOME/$Main_Conf" -class_path="$RUNHOME/:$RUNHOME/apiroute-service.jar" -echo @class_path@ $class_path -"$JAVA" $JAVA_OPTS -classpath "$class_path" org.openo.msb.ApiRouteApp server "$RUNHOME/conf/apiroute.yml" diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/setenv.sh b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/setenv.sh new file mode 100644 index 0000000..131b734 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/setenv.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +Main_Class="org.onap.msb.apiroute.ApiRouteApp" +Main_JAR="apiroute-service.jar" +Main_Conf="conf/apiroute.yml" +APP_INFO="msb-apiroute-service" + +if [ -f "/etc/timezone" ]; then + export TZ=`cat /etc/timezone` +fi \ No newline at end of file diff --git a/apiroute/apiroute-standalone/src/assembly/resources/apiroute/stop.sh b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/stop.sh new file mode 100644 index 0000000..3e7d3a1 --- /dev/null +++ b/apiroute/apiroute-standalone/src/assembly/resources/apiroute/stop.sh @@ -0,0 +1,59 @@ +# +# 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. +# + +#!/bin/sh + +DIRNAME=`dirname $0` +RUNHOME=`cd $DIRNAME/; pwd` +echo @RUNHOME@ $RUNHOME + + +if [ -f "$RUNHOME/setenv.sh" ]; then + . "$RUNHOME/setenv.sh" +else +echo "can not found $RUNHOME/setenv.sh" +fi + + +echo ================== ENV_INFO ============================================= +echo RUNHOME=$RUNHOME +echo JAVA_BASE=$JAVA_BASE +echo Main_Class=$Main_Class +echo APP_INFO=$APP_INFO +echo ========================================================================== + + +cd $RUNHOME; pwd + +function save_app_pid(){ + app_id=`ps -ef | grep $Main_Class| grep $RUNHOME | grep -v grep | awk '{print $2}'` + echo @app_id@ $app_id +} + +function kill_app_process(){ + ps -p $app_id + if [ $? == 0 ]; then + kill -9 $app_id + fi +} + +save_app_pid; +echo @C_CMD@ kill -9 $app_id +kill_app_process; + + + + diff --git a/msb-parent/msbparent/pom.xml b/apiroute/pom.xml similarity index 63% rename from msb-parent/msbparent/pom.xml rename to apiroute/pom.xml index 868de97..4ace2ce 100644 --- a/msb-parent/msbparent/pom.xml +++ b/apiroute/pom.xml @@ -1,66 +1,94 @@ - 4.0.0 - - org.openo.common-services.microservice-bus - msbparent-lite - 1.1.0-SNAPSHOT - ../msbparent-lite + org.onap.msb.apigateway + msb-apigateway-parent + 0.0.1-SNAPSHOT - - msbparent + 4.0.0 + org.onap.msb.apigateway.apiroute + apiroute-parent + onap/msb/apigateway/apiroute pom - common-services-microservice-bus/msb-parent/msbparent + 0.0.1-SNAPSHOT + + + apiroute-service + apiroute-standalone + + + + UTF-8 + UTF-8 - - scm:git:ssh://gerrit.zte.com.cn:29418/paas/wisdom/modeldesign-parent.git - scm:git:ssh://gerrit.zte.com.cn:29418/paas/wisdom/modeldesign-parent.git - HEAD + + + 1.7 + 1.7 + ${maven.compiler.source} + ${maven.compiler.target} - + + 1.8 + 3.0.0 + 2.6.1 + 3.3 + 2.6 + 2.10.3 + 3.4 + 2.5.2 + 2.18.1 - + + 2.16 + ${maven.compile.plugin.version} + 1.4 0.8.0 - 1.5.3 + 1.5.3 2.7.3 1.16.4 4.11 9.2.9.v20150224 - 2.5.1 + 2.7.9 2.16 - 1.7.12 + 1.7.12 1.1.3 4.5 - 1.5.5 + 1.5.5 + 1.17.10.01 + 0.13.8 + 4.1.2 + 2.4.3 + 0.4.0 + 1.3.2 - + + commons-io + commons-io + ${commons-io.version} + junit @@ -68,19 +96,26 @@ ${junit.version} test - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito - ${powermock.version} - test - + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.powermock + powermock-api-mockito + ${powermock.version} + test + + + com.fiftyonred + mock-jedis + ${mock-jedis.version} + test + @@ -95,11 +130,12 @@ ${dropwizard.version} + io.dropwizard dropwizard-client ${dropwizard.version} - + io.swagger @@ -112,13 +148,13 @@ redis.clients jedis ${jedis.version} - + org.projectlombok lombok ${lombok.version} - + org.glassfish.jersey.media jersey-media-multipart @@ -135,7 +171,7 @@ ${jersey.version} - + com.fasterxml.jackson.core jackson-core @@ -144,7 +180,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson-version} + 2.7.9.1 com.fasterxml.jackson.core @@ -167,7 +203,7 @@ ${jackson-version} - + org.eclipse.jetty jetty-io @@ -223,89 +259,51 @@ jetty-server ${jetty.version} - + org.slf4j slf4j-api ${slf4j.version} - + ch.qos.logback logback-classic ${logback.version} - + + ch.qos.logback logback-core ${logback.version} - + + org.apache.httpcomponents httpclient ${httpclient.version} - - - + + com.orbitz.consul + consul-client + ${consul-client.version} + - - - - org.apache.maven.plugins - maven-surefire-report-plugin - 2.19.1 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.7 - - - xml - html - - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.5 - - - org.apache.maven.plugins - maven-pmd-plugin - 3.6 - - true - utf-8 - 100 - 1.8 - - - - + + org.apache.httpcomponents + httpasyncclient + ${httpasyncclient.version} + + + org.immutables + value + ${immutables.value.version} + + + + diff --git a/build4docker.sh b/build4docker.sh new file mode 100644 index 0000000..0045272 --- /dev/null +++ b/build4docker.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# 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. +# + + +DIRNAME=`dirname $0` +RUNHOME=`cd $DIRNAME/; pwd` +echo @RUNHOME@ $RUNHOME + +echo @JAVA_HOME@ $JAVA_HOME + +#build +mvn clean install -Dmaven.test.skip=true + +#cooy +RELEASE_BASE_DIR=$RUNHOME/release +echo @RELEASE_BASE_DIR@ $RELEASE_BASE_DIR + +RELEASE_DIR=${RELEASE_BASE_DIR}/msb-apigateway +rm -rf $RELEASE_DIR +mkdir $RELEASE_DIR -p + +DOCKER_RUN_NAME=msb_apigateway +DOCKER_IMAGE_NAME=msb_apigateway +DOCKER_RELEASE_VERSION=latest + +cp -r $RUNHOME/distributions/msb-apigateway/target/version/* ${RELEASE_DIR} +cp $RUNHOME/ci/build_docker_image.sh ${RELEASE_DIR} +#build docker image +cd ${RELEASE_DIR} +chmod 777 build_docker_image.sh + + +docker rm -f ${DOCKER_RUN_NAME} +docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_RELEASE_VERSION} + +./build_docker_image.sh -n=${DOCKER_IMAGE_NAME} -v=${DOCKER_RELEASE_VERSION} -d=./docker + +#docker run + +docker run -d --net=host --name ${DOCKER_RUN_NAME} ${DOCKER_IMAGE_NAME}:${DOCKER_RELEASE_VERSION} +docker ps |grep ${DOCKER_RUN_NAME} diff --git a/ci/build_docker_image.sh b/ci/build_docker_image.sh new file mode 100644 index 0000000..7b6b546 --- /dev/null +++ b/ci/build_docker_image.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +for i in "$@" +do +case $i in + -n=*|--name=*) + NAME="${i#*=}" + shift + ;; + -v=*|--version=*) + VERSION="${i#*=}" + shift + ;; + -d=*|--dir=*) + DIR="${i#*=}" + shift + ;; +esac +done + +if [[ ${NAME} && ${VERSION} && ${DIR} ]]; then + echo "assign the x to all files and dirs under current dir.." + chmod +x -R . + echo "begin to build image ${NAME}.." + docker build --no-cache -t ${NAME}:${VERSION} . >/dev/null || { echo -e "\nBuild docker image failed!";exit 1; } + docker rmi $(docker images | grep "^" | awk '{print $3}') &>/dev/null + docker save -o ${NAME}.tar ${NAME}:${VERSION} >/dev/null || { rm -f ${NAME}.tar &>/dev/null;echo -e "\nSave docker image failed!";exit 1; } + if [ ! -d ${DIR} ]; then + mkdir -p ${DIR} + fi + mv ${NAME}.tar ${DIR}/${NAME}.tar &>/dev/null + echo "build completes!" +else + echo "not all -n and -v and -d are provided!" + exit 1 +fi diff --git a/distributions/msb-apigateway/pom.xml b/distributions/msb-apigateway/pom.xml new file mode 100644 index 0000000..0cb4239 --- /dev/null +++ b/distributions/msb-apigateway/pom.xml @@ -0,0 +1,191 @@ + + + + org.onap.msb.apigateway.distributions + distributions-parent + 0.0.1-SNAPSHOT + + 4.0.0 + org.onap.msb.apigateway.distributions + msb-apigateway + 0.0.1-SNAPSHOT + onap/msb/apigateway/distributions/msb-apigateway + pom + + + msb-apigateway + target/version + + + + + linux + + true + + + + org.onap.msb.apigateway.apiroute + apiroute-standalone + zip + ${project.version} + true + + + + + org.onap.msb.apigateway + redis-ext + tar.gz + ${classifier.linux64} + ${project.version} + true + + + + org.onap.msb.apigateway + openresty-ext + tar.gz + ${classifier.linux64} + ${project.version} + true + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpacktolinux64 + + unpack + + prepare-package + + + + org.onap.msb.apigateway.apiroute + apiroute-standalone + zip + + + org.onap.msb.apigateway + redis-ext + tar.gz + ${classifier.linux64} + + + org.onap.msb.apigateway + openresty-ext + tar.gz + ${classifier.linux64} + + + **/*.bat,**/*.cmd,**/*.exe + ${linux64outputdir} + false + true + true + + + + + + + maven-resources-plugin + + + copy-msb-resources-linux + prepare-package + + copy-resources + + + ${linux64outputdir} + true + + + src/assembly/resources/ + false + + **/* + + + **/*.bat + + + + true + + + + copy-resources-dockerfile + process-resources + + copy-resources + + + ${version.output} + true + + + ${dockerFileDir} + false + + **/* + + + + true + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + distribution + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msb-core/distributions/standalone/src/assembly/resource/stop.sh b/distributions/msb-apigateway/src/assembly/resources/shutdown.sh similarity index 76% rename from msb-core/distributions/standalone/src/assembly/resource/stop.sh rename to distributions/msb-apigateway/src/assembly/resources/shutdown.sh index b7c570b..b36bb43 100644 --- a/msb-core/distributions/standalone/src/assembly/resource/stop.sh +++ b/distributions/msb-apigateway/src/assembly/resources/shutdown.sh @@ -1,12 +1,11 @@ -#!/bin/sh # -# Copyright 2016 ZTE Corporation. +# 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 +# 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, @@ -14,26 +13,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Author: Zhaoxing Meng -# email: meng.zhaoxing1@zte.com.cn -# +#!/bin/sh DIRNAME=`dirname $0` RUNHOME=`cd $DIRNAME/; pwd` echo @RUNHOME@ $RUNHOME + echo "### Stopping openresty..."; # nohup ./startup.sh >>./nohup.log 2>&1 & cd ./openresty ./stop.sh & cd $RUNHOME -echo "### Stopping external API gateway..."; -# nohup ./startup.sh >>./nohup.log 2>&1 & -cd ./eag -./stop.sh & -cd $RUNHOME - echo "\n\n### Stopping apiroute" cd ./apiroute ./stop.sh & diff --git a/msb-core/distributions/standalone/src/assembly/resource/startup.sh b/distributions/msb-apigateway/src/assembly/resources/startup.sh similarity index 74% rename from msb-core/distributions/standalone/src/assembly/resource/startup.sh rename to distributions/msb-apigateway/src/assembly/resources/startup.sh index aa4117d..5a19128 100644 --- a/msb-core/distributions/standalone/src/assembly/resource/startup.sh +++ b/distributions/msb-apigateway/src/assembly/resources/startup.sh @@ -1,12 +1,11 @@ -#!/bin/sh # -# Copyright 2016 ZTE Corporation. +# 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 +# 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, @@ -14,41 +13,32 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Author: Zhaoxing Meng -# email: meng.zhaoxing1@zte.com.cn -# + +#!/bin/sh DIRNAME=`dirname $0` RUNHOME=`cd $DIRNAME/; pwd` echo @RUNHOME@ $RUNHOME echo "### Starting redis"; -#nohup ./wso2bps/bin/wso2server.sh >>./OpenTOSCA/nohup.log 2>&1 & cd ./redis ./run.sh & cd $RUNHOME - -echo "\n\n### Starting apiroute" -cd ./apiroute -./run.sh & -cd $RUNHOME - - echo "### Starting openresty..."; # nohup ./startup.sh >>./nohup.log 2>&1 & cd ./openresty ./run.sh & cd $RUNHOME -echo "### Starting external API gateway..."; -# nohup ./startup.sh >>./nohup.log 2>&1 & -cd ./eag -./run.sh & +echo "\n\n### Starting apiroute" +cd ./apiroute +./run.sh cd $RUNHOME + echo "Startup will be finished in background..."; echo " + Run 'tail ./apiroute-works/logs/application.log -f' to see what's happening"; echo " + Wait a minute"; echo " + Open 'http://' in your browser to access the microservice bus -stem"; +stem"; \ No newline at end of file diff --git a/distributions/msb-apigateway/src/assembly/resources/startup4docker.sh b/distributions/msb-apigateway/src/assembly/resources/startup4docker.sh new file mode 100644 index 0000000..b1dcb78 --- /dev/null +++ b/distributions/msb-apigateway/src/assembly/resources/startup4docker.sh @@ -0,0 +1,36 @@ +# +# 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. +# + +#!/bin/sh +DIRNAME=`dirname $0` +RUNHOME=`cd $DIRNAME/; pwd` +echo @RUNHOME@ $RUNHOME + + + +echo "### Starting redis"; +cd ./redis +./run.sh +cd $RUNHOME + +echo "\n\n### Starting openresty"; +cd ./openresty +./run.sh +cd $RUNHOME + +echo "\n\n### Starting apiroute" +cd ./apiroute +./run.sh \ No newline at end of file diff --git a/distributions/msb-apigateway/src/main/docker/Dockerfile b/distributions/msb-apigateway/src/main/docker/Dockerfile new file mode 100644 index 0000000..14e0b15 --- /dev/null +++ b/distributions/msb-apigateway/src/main/docker/Dockerfile @@ -0,0 +1,6 @@ +FROM openjdk:8.0.72 +ADD msb-apigateway*.tar.gz /opt/application + +ENV LD_LIBRARY_PATH /lib64 +WORKDIR /opt/application/msb-apigateway +ENTRYPOINT exec $PWD/startup4docker.sh \ No newline at end of file diff --git a/distributions/pom.xml b/distributions/pom.xml new file mode 100644 index 0000000..90a70b3 --- /dev/null +++ b/distributions/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + org.onap.msb.apigateway + msb-apigateway-parent + 0.0.1-SNAPSHOT + + + org.onap.msb.apigateway.distributions + distributions-parent + 0.0.1-SNAPSHOT + onap/msb/apigateway/distributions + pom + + msb-apigateway + + + + + target/version + src/main/docker + src/main/blueprint + + + + diff --git a/msb-core/apiroute/apiroute-service/pom.xml b/msb-core/apiroute/apiroute-service/pom.xml deleted file mode 100644 index 48e613c..0000000 --- a/msb-core/apiroute/apiroute-service/pom.xml +++ /dev/null @@ -1,165 +0,0 @@ - - - - - org.openo.common-services.microservice-bus - apiroute-parent - 1.1.0-SNAPSHOT - - 4.0.0 - apiroute-service - common-services-microservice-bus/msb-core/apiroute/apiroute-service - jar - 1.1.0-SNAPSHOT - - - - - io.dropwizard - dropwizard-core - - - io.dropwizard - dropwizard-assets - - - io.dropwizard - dropwizard-client - - - io.swagger - swagger-jersey2-jaxrs - compile - - - - redis.clients - jedis - - - org.projectlombok - lombok - - - net.sf.json-lib - json-lib - 2.4 - jdk15 - - - junit - junit - test - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.4 - - - - true - - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.3 - - true - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - package - - shade - - - - - - org.openo.msb.ApiRouteApp - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - - src/main/java - - **/*.properties - - - - src/main/resources - - - - diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java deleted file mode 100644 index e5a6394..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ApiRouteApp.java +++ /dev/null @@ -1,549 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb; - -import io.dropwizard.Application; -import io.dropwizard.assets.AssetsBundle; -import io.dropwizard.jetty.HttpConnectorFactory; -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 java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URL; -import java.util.List; - -import net.sf.json.JSONObject; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.ApiRouteInfo; -import org.openo.msb.api.ConsulInfo; -import org.openo.msb.api.CustomRouteInfo; -import org.openo.msb.api.DiscoverInfo; -import org.openo.msb.api.IuiRouteInfo; -import org.openo.msb.api.RouteServer; -import org.openo.msb.api.exception.ExtendedNotFoundException; -import org.openo.msb.health.ApiRouteHealthCheck; -import org.openo.msb.resources.ApiRouteResource; -import org.openo.msb.resources.CustomRouteResource; -import org.openo.msb.resources.IuiRouteResource; -import org.openo.msb.resources.MetricsResource; -import org.openo.msb.resources.MicroServiceResource; -import org.openo.msb.resources.ServiceAccessResource; -import org.openo.msb.wrapper.ApiRouteServiceWrapper; -import org.openo.msb.wrapper.CustomRouteServiceWrapper; -import org.openo.msb.wrapper.IuiRouteServiceWrapper; -import org.openo.msb.wrapper.serviceListener.MicroServiceChangeListener; -import org.openo.msb.wrapper.util.FileUtil; -import org.openo.msb.wrapper.util.JacksonJsonUtil; -import org.openo.msb.wrapper.util.JedisUtil; -import org.openo.msb.wrapper.util.MetricsUtil; -import org.openo.msb.wrapper.util.MicroServiceDB; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.annotation.JsonInclude; - -public class ApiRouteApp extends Application { - - private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteApp.class); - - public static void main(String[] args) throws Exception { - new ApiRouteApp().run(args); - - } - - private ApiRouteAppConfig config; - - @Override - public String getName() { - return " MicroService Bus "; - } - - @Override - public void initialize(Bootstrap bootstrap) { - - - } - - @Override - public void run(ApiRouteAppConfig configuration, Environment environment) { - - initRootPath(); - - - new AssetsBundle("/iui-metrics", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/metrics", - "index.html", "iui-metrics").run(environment); - - new AssetsBundle("/iui-route", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices", "index.html", - "iui-microservices").run(environment); - - new AssetsBundle("/api-doc", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/api-doc", - "index.html", "api-doc").run(environment); - - new AssetsBundle("/ext", "/"+RouteUtil.IUI_ROOT_PATH+"/microservices/ext", - "index.html", "ext").run(environment); - - - - - final ApiRouteHealthCheck healthCheck = - new ApiRouteHealthCheck(configuration.getDefaultWorkspace()); - environment.healthChecks().register("template", healthCheck); - environment.jersey().register(new ApiRouteResource()); - environment.jersey().register(new IuiRouteResource()); - environment.jersey().register(new MetricsResource()); - environment.jersey().register(new CustomRouteResource()); - environment.jersey().register(new ServiceAccessResource()); - environment.jersey().register(new MicroServiceResource()); - - config = configuration; - - initSwaggerConfig(environment, configuration); - initRedisConfig(configuration); - checkRedisConnect(); - initMetricsConfig(configuration); - initVisualRangeMatches(); - - registerServiceChangeListener(); - - - } - - private void initMetricsConfig(ApiRouteAppConfig configuration) { - - SimpleServerFactory simpleServerFactory = - (SimpleServerFactory) configuration.getServerFactory(); - HttpConnectorFactory httpConnectorFactory = - (HttpConnectorFactory) simpleServerFactory.getConnector(); - MetricsUtil.adminContextPath = - "http://127.0.0.1:" + httpConnectorFactory.getPort() - + simpleServerFactory.getAdminContextPath() + "/metrics"; - } - - 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("MicroService Bus rest API"); - config.setVersion("1.0.0"); - config.setResourcePackage("org.openo.msb.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.info("getApplicationContextPath: " + basePath); - config.setBasePath(basePath); - config.setScan(true); - } - - - private void initRootPath(){ - try { - - URL urlRootPath = ApiRouteApp.class.getResource("/ext/initUrlRootPath/initUrlRootPath.json"); - if (urlRootPath != null) { - String path = urlRootPath.getPath(); - - LOGGER.info("read initUrlRootPath:" + path); - - String fileContent = FileUtil.readFile(path); - JSONObject jsonObj = JSONObject.fromObject(fileContent); - RouteUtil.IUI_ROOT_PATH=jsonObj.get("iuiRootPath").toString(); - RouteUtil.API_ROOT_PATH=jsonObj.get("apiRootPath").toString(); - } - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error("read initUrlRootPath Files throw exception", e); - } - - } - private void initRedisConfig(ApiRouteAppConfig configuration) { - - String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); - String jarPath = path.substring(0, path.lastIndexOf("/")); - - LOGGER.info("jarpath: " + jarPath); - LOGGER.info("getDefaultWorkspace " + configuration.getDefaultWorkspace()); - - String confDir = - jarPath + "/" + configuration.getDefaultWorkspace() + "/" - + configuration.getPropertiesDir(); - String propertiesPath = confDir + "/" + configuration.getPropertiesName(); - - JedisUtil.propertiesPath = propertiesPath; - - LOGGER.info("propertiesPath: " + propertiesPath); - LOGGER.info("confDir: " + confDir); - - try { - File dirFile = new File(confDir); - - if (!dirFile.exists()) { - dirFile.mkdirs(); - } - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.info("create RedisConfig confDir error: " + confDir + e.getMessage()); - } - - - try { - File propertiesFile = new File(propertiesPath); - if (!propertiesFile.exists()) { - - - propertiesFile.createNewFile(); - - BufferedWriter output = new BufferedWriter(new FileWriter(propertiesFile)); - StringBuilder contentBuilder = new StringBuilder(); - contentBuilder.append("redis.host=127.0.0.1\n").append("redis.port=6379\n") - .append("#connectionTimeout\n").append("redis.connectionTimeout=2000\n") - .append("#redis dbIndex,defaule:0\n") - .append("redis.db_index=0\n\n") - .append("#--------------redis pool config--------------\n") - .append("#maxTotal\n").append("redis.pool.maxTotal=100\n") - .append("#maxIdle\n").append("redis.pool.maxIdle=20\n") - .append("#maxWaitMillis:ms\n") - .append("redis.pool.maxWaitMillis=1000\n") - .append("#testOnBorrow\n") - .append("redis.pool.testOnBorrow=false\n") - .append("#testOnReturn\n") - .append("redis.pool.testOnReturn=true\n") - .append("#nginx Port\n").append("server.port=10080\n"); - - output.write(contentBuilder.toString()); - output.close(); - - } - } catch (IOException e) { - // TODO Auto-generated catch block - LOGGER.info("create RedisConfig File error: " + propertiesPath + e.getMessage()); - } - } - - - private void checkRedisConnect() { - - new Thread(new Runnable() { - public void run() { - int n = 0; - while (true) { - if (ApiRouteServiceWrapper.checkRedisConnect() == false) { - n++; - System.out.println(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) { - System.out.println("Initial Route Configuration fail,timeout exit"); - LOGGER.error("Initial Route Configuration——redis connection fail,timeout exit..."); - break; - } - } else { - System.out.println("starting to initial Route Configuration"); - // initRouteInfoFromConfig(); - initRouteInfoFromJson(); - System.out.println("starting to initial consul Configuration"); - runConsulClientApp(); - - break; - } - } - - } - }).start(); - } - - - - - /** - * @Title: initVisualRangeMatches - * @Description: TODO(According to the environment variable or a JSON file configuration initialization VisualRange filter conditions) - * @return: void - */ - private void initVisualRangeMatches(){ - try { - if(System.getenv("APIGATEWAY_VISUAL_RANGE")==null) - { - - URL visualRangePath = ApiRouteApp.class.getResource("/ext/initVisualRange/initVisualRangeMatches.json"); - if (visualRangePath != null) { - String path = visualRangePath.getPath(); - - LOGGER.info("read initVisualRangeMatches:" + path); - - String fileContent = FileUtil.readFile(path); - JSONObject jsonObj = JSONObject.fromObject(fileContent); - String visualRangeArray=jsonObj.get("visualRange").toString(); - - - RouteUtil.visualRangeMatches=StringUtils.split(visualRangeArray, ","); - - - - } - } - else{ - RouteUtil.visualRangeMatches=StringUtils.split(System.getenv("APIGATEWAY_VISUAL_RANGE"), ","); - } - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error("read initVisualRangeMatches Files or env(APIGATEWAY_VISUAL_RANGE) throw exception", e); - } - } - - /** - * @Title: initRouteInfoFromJson - * @Description: TODO(按照JSON文件配置初始化route数据) - * @return: void - */ - private void initRouteInfoFromJson() { - - URL apiDocsPath = ApiRouteApp.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) { - try { - List routeList = - (List) JacksonJsonUtil.jsonToListBean(fileContent); - for (ApiRouteInfo route : routeList) { - String url = route.getUrl(); - - if (RegExpTestUtil.urlRegExpTest(route.getServiceName())) { - - try{ - CustomRouteInfo dbCustomRoute = - CustomRouteServiceWrapper.getInstance().getCustomRouteInstance( - route.getServiceName()); - } - 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()); - - - CustomRouteServiceWrapper.getInstance().saveCustomRouteInstance( - customRouteInfo, ""); - - - } - } else { - - if (RegExpTestUtil.apiRouteUrlRegExpTest(url) || url.startsWith("/api/microservices/")) { - - - try{ - ApiRouteInfo dbApiRoute = - ApiRouteServiceWrapper.getInstance().getApiRouteInstance( - route.getServiceName(), route.getVersion()); - } - catch(ExtendedNotFoundException e){ - LOGGER.info("initapiRoute: ServiceName--" + route.getServiceName()); - ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(route, ""); - } - - - } else if (RegExpTestUtil.iuiRouteUrlRegExpTest(url) || url.equals("/iui/microservices")) { - - try{ - IuiRouteInfo dbIuiRoute = - IuiRouteServiceWrapper.getInstance().getIuiRouteInstance( - route.getServiceName()); - } - 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()); - - if(url.equals("/iui/microservices")){ - iuiRouteInfo.setUrl("/"+RouteUtil.IUI_ROOT_PATH+"/microservices"); - } - else{ - iuiRouteInfo.setUrl(route.getUrl()); - } - - IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); - - } - - } 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); - } - - } - - - - /** - * The listener registration service changes - */ - private void registerServiceChangeListener() { - MicroServiceDB.getInstance().addServiceChangeListener(new MicroServiceChangeListener()); - } - - // Open the consul to monitor subscription service - private void runConsulClientApp() { - DiscoverInfo config_discoverInfo = config.getDiscoverInfo(); - - ConsulInfo config_consulInfo=config.getConsulInfo(); - - RouteUtil.discoverInfo.setEnabled(config_discoverInfo.isEnabled()); - - if (config_discoverInfo.isEnabled()) { - try{ - if(System.getenv("SDCLIENT_SVC_PORT")==null) - { - //yml - RouteUtil.discoverInfo.setIp(config_discoverInfo.getIp()); - RouteUtil.discoverInfo.setPort(config_discoverInfo.getPort()); - - } - else{ - - String discoverAddress=System.getenv("SDCLIENT_SVC_PORT").split("//")[1]; - String sdIP=discoverAddress.split(":")[0]; - int sdPort=Integer - .parseInt(discoverAddress.split(":")[1]); - - RouteUtil.discoverInfo.setIp(sdIP); - RouteUtil.discoverInfo.setPort(sdPort); - - config_consulInfo.setIp(sdIP); - config_consulInfo.setPort(sdPort); - - - } - - - - //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"); - - RouteServer[] servers=new RouteServer[1]; - servers[0]=new RouteServer(RouteUtil.discoverInfo.getIp(),String.valueOf(RouteUtil.discoverInfo.getPort())); - discoverApiService.setServers(servers); - - ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(discoverApiService, ""); - - //iui - IuiRouteInfo discoverIUIService=new IuiRouteInfo(); - discoverIUIService.setServiceName("msdiscover"); - discoverIUIService.setUrl("/iui/microservices"); - discoverIUIService.setServers(servers); - IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(discoverIUIService); - - - - ConsulClientApp consulClientApp = new ConsulClientApp(config_consulInfo.getIp(), config_consulInfo.getPort()); - // Monitor service change - consulClientApp.startServiceListen(); - LOGGER.info("start monitor consul service--" +config_consulInfo.getIp() + ":" - + config_consulInfo.getPort()); - } - catch(Exception e){ - LOGGER.error("start monitor consul service fail:"+e.getMessage()); - } - } - - - } - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java deleted file mode 100644 index 4d83a6d..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/ConsulClientApp.java +++ /dev/null @@ -1,451 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.MicroServiceFullInfo; -import org.openo.msb.api.MicroServiceInfo; -import org.openo.msb.api.Node; -import org.openo.msb.wrapper.MicroServiceWrapper; -import org.openo.msb.wrapper.consul.CatalogClient; -import org.openo.msb.wrapper.consul.Consul; -import org.openo.msb.wrapper.consul.HealthClient; -import org.openo.msb.wrapper.consul.cache.CatalogCache; -import org.openo.msb.wrapper.consul.cache.ConsulCache; -import org.openo.msb.wrapper.consul.cache.ConsulCache4Map; -import org.openo.msb.wrapper.consul.cache.HealthCache; -import org.openo.msb.wrapper.consul.cache.ServiceCache; -import org.openo.msb.wrapper.consul.model.catalog.CatalogService; -import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; -import org.openo.msb.wrapper.consul.model.health.Service; -import org.openo.msb.wrapper.consul.model.health.ServiceHealth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ConsulClientApp { - - private final Consul consul; - private final CatalogClient catalogClient; - private final HealthClient healthClient; - private AtomicReference> cacheList = new AtomicReference>( - new ArrayList()); - - - private static final Logger LOGGER = LoggerFactory.getLogger(ConsulClientApp.class); - - public ConsulClientApp(String ip, int port) { - URL url = null; - try { - url = new URL("http", ip, port, ""); - } catch (MalformedURLException e1) { - // TODO Auto-generated catch block - LOGGER.error("start ConsulClientApp throw exception", e1); - throw new RuntimeException(e1); - } - this.consul = Consul.builder().withUrl(url).build(); // connect to Consul on localhost - this.catalogClient = consul.catalogClient(); - this.healthClient = consul.healthClient(); - } - - public Consul getConsul() { - return consul; - } - - public CatalogClient getCatalogClient() { - return catalogClient; - } - - private void stopNodeListen(String serviceName) { - try { - - ListIterator cacheListLit = cacheList.get().listIterator(); - while (cacheListLit.hasNext()) { - HealthCache cache = (HealthCache) cacheListLit.next(); - if (cache.getServiceName().equals(serviceName)) { - - cache.stop(); - cacheListLit.remove(); - LOGGER.info(cache.getServiceName() + " NodeListen stoped"); - break; - } - } - - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error("stop Node:[" + serviceName + "] Listen throw exception", e); - } - - - } - - /** - * @Title startServiceListen - * @Description TODO(Open the consul registration services to monitor) - * @return void - */ - public void startServiceListen() { - final ServiceCache serviceCache = ServiceCache.newCache(catalogClient, 30); - serviceCache.addListener(new ConsulCache4Map.Listener>>() { - @Override - public void notify(List oldValues, List newValues) { - // do Something with updated server List - LOGGER.info("--new service notify--"); - - List deRegisterServiceList = getDiffrent(oldValues, newValues); - - - for (ServiceInfo serviceInfo : deRegisterServiceList) { - try { - - MicroServiceWrapper.getInstance().deleteMicroService( - serviceInfo.getServiceName(), serviceInfo.getVersion()); - - - stopNodeListen(serviceInfo.getServiceName()); - LOGGER.info("Cancel MicroServiceInfo and stop node listen successs:" - + serviceInfo.getServiceName()); - } catch (Exception e) { - LOGGER.error("Cancel MicroServiceInfo and stop node listen FAIL : ", e); - - } - - } - - - List registerServiceList = getDiffrent(newValues, oldValues); - for (ServiceInfo serviceInfo : registerServiceList) { - - // if (deRegisterServiceList.contains(serviceInfo)) continue; - - - LOGGER.info(" new serviceName:" + serviceInfo.getServiceName() + " version:" - + serviceInfo.getVersion()); - // Open Node to monitor new registration service - startHealthNodeListen(serviceInfo.getServiceName(), serviceInfo.getVersion()); - - } - - - } - - }); - - try { - LOGGER.info("start...consul ... service..Listening."); - serviceCache.start(); - - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error("start...service..Listen throw exception", e); - } - } - - - /** - * @Title startHealthNodeListen - * @Description TODO(Open a service node changes to monitor, only to return to health service) - * @param serviceName - * @return - * @return HealthCache - */ - private HealthCache startHealthNodeListen(final String serviceName, final String version) { - final HealthCache healthCache = HealthCache.newCache(healthClient, serviceName, 30); - healthCache.addListener(new HealthCache.Listener() { - @Override - public void notify(Map newValues) { - // do Something with updated server map - LOGGER.info(serviceName + "--new node notify--"); - - if (newValues.isEmpty()) { - LOGGER.info(serviceName + "--nodeList is Empty--"); - - - MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version); - - // try { - // healthCache.stop(); - // } catch (Exception e) { - // LOGGER.equals(serviceName+"-- stop Node error:"+e.getMessage()); - // } - - } else { - - MicroServiceInfo microServiceInfo = new MicroServiceInfo(); - HashSet nodes = new HashSet(); - String url = ""; - String version = "", visualRange = "", protocol = "",lb_policy=""; - - for (Map.Entry entry : newValues.entrySet()) { - String nodeName = entry.getKey().toString(); - ServiceHealth value = (ServiceHealth) entry.getValue(); - - Node node = new Node(); - Service service = value.getService(); - node.setIp(service.getAddress()); - node.setPort(String.valueOf(service.getPort())); - - - try { - List tagList = service.getTags(); - for (String tag : tagList) { - if (tag.startsWith("url")) { - if (tag.split(":").length == 2) { - url = tag.split(":")[1]; - } else { - url = ""; - } - - - continue; - } - if (tag.startsWith("version")) { - if (tag.split(":").length == 2) { - version = tag.split(":")[1]; - } else { - version = ""; - } - continue; - } - if (tag.startsWith("protocol")) { - protocol = tag.split(":")[1]; - continue; - } - if (tag.startsWith("visualRange")) { - visualRange = tag.split(":")[1]; - continue; - } - - if (tag.startsWith("lb_policy")) { - lb_policy = tag.split(":")[1]; - continue; - } - - } - - - } catch (Exception e) { - LOGGER.error(serviceName + " read tag throw exception", e); - System.out.println(serviceName + " read tag throw exception"); - } - - nodes.add(node); - } - - microServiceInfo.setNodes(nodes); - microServiceInfo.setProtocol(protocol); - microServiceInfo.setUrl(url); - microServiceInfo.setServiceName(serviceName); - microServiceInfo.setLb_policy(lb_policy); - if (!visualRange.isEmpty()) { - microServiceInfo.setVisualRange(visualRange); - } - microServiceInfo.setVersion(version); - - try { - MicroServiceFullInfo microServiceFullInfo = - MicroServiceWrapper.getInstance().saveMicroServiceInstance( - microServiceInfo, false, "", ""); - LOGGER.info("register MicroServiceInfo successs:" - + microServiceFullInfo.getServiceName()); - } catch (Exception e) { - LOGGER.error("register MicroServiceInfo FAIL : " + serviceName, e); - - } - } - } - }); - try { - LOGGER.info(serviceName + " Node Listen start"); - cacheList.get().add(healthCache); - healthCache.start(); - - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error(serviceName + " Node Listen start throw exception", e); - } - - return healthCache; - } - - /** - * @Title startNodeListen - * @Description TODO(Open a service node changes to monitor) - * @param serviceName - * @return - * @return CatalogCache - */ - @Deprecated - private CatalogCache startNodeListen(final String serviceName) { - final CatalogCache catalogCache = CatalogCache.newCache(catalogClient, serviceName, 30); - catalogCache.addListener(new ConsulCache.Listener() { - @Override - public void notify(Map newValues) { - // do Something with updated server map - System.out.println(serviceName + "--new node notify--"); - LOGGER.info(serviceName + "--new node notify--"); - - if (newValues.isEmpty()) { - System.out.println(serviceName + "-- nodeList is Empty--"); - LOGGER.info(serviceName + "--nodeList is Empty-stop service[" + serviceName - + "] listen-"); - try { - catalogCache.stop(); - } catch (Exception e) { - LOGGER.equals(serviceName + "-- stop Node error:" + e.getMessage()); - } - - } else { - - MicroServiceInfo microServiceInfo = new MicroServiceInfo(); - HashSet nodes = new HashSet(); - String url = ""; - String version = "", visualRange = "", protocol = ""; - - for (Map.Entry entry : newValues.entrySet()) { - String nodeName = entry.getKey().toString(); - CatalogService value = (CatalogService) entry.getValue(); - - Node node = new Node(); - node.setIp(value.getServiceAddress()); - node.setPort(String.valueOf(value.getServicePort())); - - - try { - List tagList = value.getServiceTags(); - for (String tag : tagList) { - if (tag.startsWith("url")) { - if (tag.split(":").length == 2) { - url = tag.split(":")[1]; - } else { - url = ""; - } - - - continue; - } - if (tag.startsWith("version")) { - if (tag.split(":").length == 2) { - version = tag.split(":")[1]; - } else { - version = ""; - } - continue; - } - if (tag.startsWith("protocol")) { - protocol = tag.split(":")[1]; - continue; - } - if (tag.startsWith("visualRange")) { - visualRange = tag.split(":")[1]; - continue; - } - if (tag.startsWith("ttl")) { - int ttl = Integer.parseInt(tag.split(":")[1]); - node.setTtl(ttl); - continue; - } - } - - - } catch (Exception e) { - LOGGER.error(serviceName + " read tag throw exception", e); - System.out.println(serviceName + " read tag throw exception"); - } - - nodes.add(node); - - - System.out.println(nodeName + ":" + value.getServiceAddress() + " " - + value.getServicePort() + " " + value.getServiceTags()); - } - - microServiceInfo.setNodes(nodes); - microServiceInfo.setProtocol(protocol); - microServiceInfo.setUrl(url); - microServiceInfo.setServiceName(serviceName); - if (!visualRange.isEmpty()) { - microServiceInfo.setVisualRange(visualRange); - } - microServiceInfo.setVersion(version); - - try { - MicroServiceFullInfo microServiceFullInfo = - MicroServiceWrapper.getInstance().saveMicroServiceInstance( - microServiceInfo, false, "", ""); - LOGGER.info("register MicroServiceInfo successs:" + microServiceFullInfo); - System.out.println("register MicroServiceInfo successs:" + serviceName); - } catch (Exception e) { - LOGGER.error("register MicroServiceInfo FAIL : ", e); - - } - } - } - }); - try { - System.out.println(serviceName + " Node Listen start"); - LOGGER.info(serviceName + " Node Listen start"); - catalogCache.start(); - - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error(serviceName + " Node Listen start throw exception", e); - } - - return catalogCache; - } - - - /** - * @Title getDiffrent - * @Description TODO(Extract the list1 and list2 different data sets) - * @param list1 - * @param list2 - * @return - * @return List - */ - private List getDiffrent(List list1, List list2) { - - List diff = new ArrayList(); - - - - for (ServiceInfo serviceInfo : list1) { - if (!list2.contains(serviceInfo)) { - diff.add(serviceInfo); - } - } - - return diff; - } - - public static void main(String[] args) { - ConsulClientApp consulTest = new ConsulClientApp("127.0.0.1", 10081); - consulTest.startServiceListen(); - - - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java deleted file mode 100644 index fcde8d7..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ApiRouteInfo.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import io.swagger.annotations.ApiModelProperty; - -import java.io.Serializable; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - - -public class ApiRouteInfo implements Serializable{ - private static final long serialVersionUID = 1L; - @ApiModelProperty(required = true) - private String serviceName; - - @ApiModelProperty(example = "v1", required = true) - private String version; - - @ApiModelProperty(value = "Target Service URL,start with /",example = "/test", required = true) - private String url; - - 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=""; - - @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"; - - @ApiModelProperty(required = true) - private RouteServer servers[]; - - - - 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 getApiJson() { - return apiJson; - } - public void setApiJson(String apiJson) { - this.apiJson = apiJson; - } - - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } - public RouteServer[] getServers() { - return servers; - } - public void setServers(RouteServer[] servers) { - this.servers = servers; - } - - - 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; - } - 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; - } - - - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java deleted file mode 100644 index 4550b61..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ConsulInfo.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import java.io.Serializable; - -public class ConsulInfo implements Serializable{ - private static final long serialVersionUID = 1L; - private String ip; - private int port; - - 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; - } - -} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java deleted file mode 100644 index 0d84857..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/CustomRouteInfo.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import io.swagger.annotations.ApiModelProperty; - -import java.io.Serializable; - -public class CustomRouteInfo implements Serializable{ - - 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"; - - @ApiModelProperty(required = true) - private RouteServer servers[]; - - 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; - } - - public void setServers(RouteServer[] servers) { - this.servers = servers; - } - - 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; - } - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java deleted file mode 100644 index 64676d3..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/IuiRouteInfo.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import io.swagger.annotations.ApiModelProperty; - -import java.io.Serializable; - - -public class IuiRouteInfo implements Serializable{ - 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"; - - @ApiModelProperty(required = true) - private RouteServer servers[]; - - 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; - } - - public void setServers(RouteServer[] servers) { - this.servers = servers; - } - - 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; - } - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java deleted file mode 100644 index 981dfe6..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MetricsInfo.java +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - - - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import com.fasterxml.jackson.annotation.JsonProperty; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MetricsInfo{ - private Gauges gauges; - private Timers timers; -} - -@Data -@NoArgsConstructor -@AllArgsConstructor -class Gauges { - - @JsonProperty("jvm.attribute.uptime") - private JVMMetrics jvm_attribute_uptime; - - @JsonProperty("jvm.memory.pools.Eden-Space.usage") - private JVMMetrics jvm_memory_pools_Eden_Space_usage; - - @JsonProperty("jvm.memory.pools.PS-Eden-Space.usage") - private JVMMetrics jvm_memory_pools_PS_Eden_Space_usage; - - @JsonProperty("jvm.memory.pools.Perm-Gen.usage") - private JVMMetrics jvm_memory_pools_Perm_Gen_usage; - - @JsonProperty("jvm.memory.pools.PS-Perm-Gen.usage") - private JVMMetrics jvm_memory_pools_PS_Perm_Gen_usage; - - @JsonProperty("jvm.memory.pools.Survivor-Space.usage") - private JVMMetrics jvm_memory_pools_Survivor_Space_usage; - - @JsonProperty("jvm.memory.pools.PS-Survivor-Space.usage") - private JVMMetrics jvm_memory_pools_PS_Survivor_Space_usage; - - @JsonProperty("jvm.memory.pools.Tenured-Gen.usage") - private JVMMetrics jvm_memory_pools_Tenured_Gen_usage; - - @JsonProperty("jvm.memory.pools.PS-Old-Gen.usage") - private JVMMetrics jvm_memory_pools_PS_Old_Gen_usage; - - @JsonProperty("jvm.memory.pools.Code-Cache.usage") - private JVMMetrics jvm_memory_pools_Code_Cache_usage; - - @JsonProperty("jvm.memory.heap.init") - private JVMMetrics jvm_memory_heap_init; - - @JsonProperty("jvm.memory.non-heap.init") - private JVMMetrics jvm_memory_non_heap_init; - - @JsonProperty("jvm.memory.heap.used") - private JVMMetrics jvm_memory_heap_used; - - @JsonProperty("jvm.memory.non-heap.used") - private JVMMetrics jvm_memory_non_heap_used; - - @JsonProperty("jvm.memory.heap.max") - private JVMMetrics jvm_memory_heap_max; - - @JsonProperty("jvm.threads.runnable.count") - private JVMMetrics jvm_threads_runnable_count; - - @JsonProperty("jvm.threads.timed_waiting.count") - private JVMMetrics jvm_threads_timed_waiting_count; - - @JsonProperty("jvm.threads.waiting.count") - private JVMMetrics jvm_threads_waiting_count; - - @JsonProperty("jvm.threads.blocked.count") - private JVMMetrics jvm_threads_blocked_count; - - @JsonProperty("jvm.threads.count") - private JVMMetrics jvm_threads_count; - - - -} - -@Data -@NoArgsConstructor -@AllArgsConstructor -class Timers{ - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.addApiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_addApiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.deleteApiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_deleteApiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiDocs") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiDocs; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getApiRoutes") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getApiRoutes; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.getServerIP") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_getServerIP; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.ApiRouteResource.updateApiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_ApiRouteResource_updateApiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.addIuiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_addIuiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.deleteIuiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_deleteIuiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.getIuiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_getIuiRoute; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.getIuiRoutes") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_getIuiRoutes; - - @JsonProperty("com.zte.ums.nfv.eco.hsif.msb.resources.IuiRouteResource.updateIuiRoute") - private HttpMetrics com_zte_ums_nfv_eco_hsif_msb_resources_IuiRouteResource_updateIuiRoute; - - @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.get-requests") - private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_get_requests; - - @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.post-requests") - private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_post_requests; - - @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.put-requests") - private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_put_requests; - - @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.delete-requests") - private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_delete_requests; - - @JsonProperty("io.dropwizard.jetty.MutableServletContextHandler.other-requests") - private HttpMetrics io_dropwizard_jetty_MutableServletContextHandler_other_requests; - -} - -@Data -@NoArgsConstructor -@AllArgsConstructor -class JVMMetrics{ - private double value; -} - -@Data -@NoArgsConstructor -@AllArgsConstructor -class HttpMetrics{ - private int count; - private double max; - private double mean; - private double min; - private double p50; - private double p75; - private double p95; - private double p98; - private double p99; - private double p999; - private double stddev; - private double m15_rate; - private double m1_rate; - private double m5_rate; - private double mean_rate; - private String duration_units; - private String rate_units; -} - - diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java deleted file mode 100644 index 3817395..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceFullInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import java.io.Serializable; -import java.util.Set; - -public class MicroServiceFullInfo extends Service implements Serializable { - private static final long serialVersionUID = 1L; - - private Set nodes; - - private String status = "1"; //0:disable 1:enable - - public Set getNodes() { - return nodes; - } - - public void setNodes(Set nodes) { - this.nodes = nodes; - } - - public String getStatus() { - return status; - } - public void setStatus(String status) { - this.status = status; - } - - -} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java deleted file mode 100644 index 725df2e..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/MicroServiceInfo.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import java.io.Serializable; -import java.util.Set; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class MicroServiceInfo extends Service implements Serializable { - private static final long serialVersionUID = 1L; - - private Set nodes; - - public Set getNodes() { - return nodes; - } - - public void setNodes(Set nodes) { - this.nodes = nodes; - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java deleted file mode 100644 index c1a5d68..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/NodeInfo.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import java.util.Date; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -public class NodeInfo extends Node { - - private static final long serialVersionUID = 8955786461351557306L; - - private String nodeId; - - - - @JsonSerialize(using = CustomDateSerializer.class) - private Date expiration; - - @JsonSerialize(using = CustomDateSerializer.class) - private Date created_at; - - @JsonSerialize(using = CustomDateSerializer.class) - private Date updated_at; - - public Date getExpiration() { - return expiration; - } - - public void setExpiration(Date expiration) { - this.expiration = expiration; - } - - public Date getCreated_at() { - return created_at; - } - - public void setCreated_at(Date created_at) { - this.created_at = created_at; - } - - public Date getUpdated_at() { - return updated_at; - } - - public void setUpdated_at(Date updated_at) { - this.updated_at = updated_at; - } - - public String getNodeId() { - return nodeId; - } - - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java deleted file mode 100644 index 6e19a71..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/Service.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import io.swagger.annotations.ApiModelProperty; - -import java.io.Serializable; -import java.util.Set; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class Service 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=""; - - @ApiModelProperty(required = true) - private Set nodes; - - public Set getNodes() { - return nodes; - } - - public void setNodes(Set nodes) { - this.nodes = nodes; - } - - 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; - } - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java deleted file mode 100644 index 58f907a..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/api/ServiceAccessInfo.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.api; - -import java.io.Serializable; - -import com.fasterxml.jackson.annotation.JsonInclude; - -public class ServiceAccessInfo implements Serializable { - private static final long serialVersionUID = 1L; - // (api|iui|custom|p2p) - private String serviceType; - - private String serviceName; - @JsonInclude(JsonInclude.Include.NON_NULL) - private String version; - - private String accessAddr; - - /** - * @return the serviceType - */ - public String getServiceType() { - return serviceType; - } - - /** - * @param serviceType the serviceType to set - */ - public void setServiceType(String serviceType) { - this.serviceType = serviceType; - } - - /** - * @return the serviceName - */ - public String getServiceName() { - return serviceName; - } - - /** - * @param serviceName the serviceName to set - */ - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - /** - * @return the version - */ - public String getVersion() { - return version; - } - - /** - * @param version the version to set - */ - public void setVersion(String version) { - this.version = version; - } - - /** - * @return the accessAddr - */ - public String getAccessAddr() { - return accessAddr; - } - - /** - * @param accessAddr the accessAddr to set - */ - public void setAccessAddr(String accessAddr) { - this.accessAddr = accessAddr; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java deleted file mode 100644 index def36e2..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/MetricsResource.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.resources; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.apache.http.impl.client.CloseableHttpClient; -import org.openo.msb.api.MetricsInfo; -import org.openo.msb.wrapper.MetricsServiceWrapper; - -import com.codahale.metrics.annotation.Timed; - -@Path("/metrics") -@Api(tags = { "metrics" }) -@Produces(MediaType.APPLICATION_JSON) -public class MetricsResource { - - - @GET - @Path("/") - @ApiOperation(value = "get Metrics Info ", response = MetricsInfo.class) - @Produces(MediaType.APPLICATION_JSON) - @Timed - public MetricsInfo getMetricsInfo() { - return MetricsServiceWrapper.getMetricsInfo(); - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java deleted file mode 100644 index 65da72b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/resources/ServiceAccessResource.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.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.util.List; - -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -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.MediaType; - -import org.openo.msb.api.ServiceAccessInfo; -import org.openo.msb.wrapper.ServiceAccessWrapper; - -import com.codahale.metrics.annotation.Timed; - - -@Path("/serviceaccess") -@Api(tags = {"ServiceAccess"}) -@Produces(MediaType.APPLICATION_JSON) -public class ServiceAccessResource { - - @GET - @Path("/{serviceName}") - @ApiOperation(value = "get the msb access address of the service ", response = ServiceAccessInfo.class) - @ApiResponses(value = {@ApiResponse(code = 500, message = "get access address error ")}) - @Produces(MediaType.APPLICATION_JSON) - @Timed - public List getApiRoute( - @ApiParam(value = "serviceName") @PathParam("serviceName") String serviceName, - @ApiParam(value = "service type", allowableValues = "api,iui,custom,p2p") @QueryParam("type") String serviceType, - @ApiParam(value = "version") @QueryParam("version") @DefaultValue("") String version, - @ApiParam(hidden = true) @HeaderParam("Host") String host) { - - host=host.split(":")[0]; - - return ServiceAccessWrapper.getInstance().getApiRouteAccessAddr(serviceType, serviceName, - version, host); - - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java deleted file mode 100644 index 3d6672b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ApiRouteServiceWrapper.java +++ /dev/null @@ -1,565 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.ApiRouteInfo; -import org.openo.msb.api.DiscoverInfo; -import org.openo.msb.api.RouteServer; -import org.openo.msb.api.exception.ExtendedInternalServerErrorException; -import org.openo.msb.api.exception.ExtendedNotFoundException; -import org.openo.msb.api.exception.ExtendedNotSupportedException; -import org.openo.msb.wrapper.util.JedisUtil; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; - - -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 ApiRouteInfo[] getAllApiRouteInstances() { - - - Jedis jedis = null; - ApiRouteInfo[] apiRouteList = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - - String routekey = - RouteUtil - .getPrefixedKey("", RouteUtil.APIROUTE, "*", RouteUtil.ROUTE_PATH_INFO); - Set routeSet = jedis.keys(routekey); - apiRouteList = new ApiRouteInfo[routeSet.size()]; - - int i = 0; - for (String routePath : routeSet) { - String[] routePathArray = routePath.split(":"); - ApiRouteInfo apiRoute = - getApiRouteInstance(routePathArray[3], routePathArray[4], jedis); - apiRouteList[i] = apiRoute; - i++; - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return apiRouteList; - } - - - - public static boolean checkRedisConnect() { - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis != null) { - return true; - } - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return false; - } - - - public ApiRouteInfo getApiRouteInstance(String serviceName, String version) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException("version (" + version - + ") is not a valid format"); - } - } - - - ApiRouteInfo apiRouteInfo = null; - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - apiRouteInfo = getApiRouteInstance(serviceName, version, jedis); - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - if (null == apiRouteInfo) { - String errInfo = - "ApiRouteInfo not found: serviceName-" + serviceName + " ,version-" + version; - LOGGER.warn(errInfo); - throw new ExtendedNotFoundException(errInfo); - - } - - return apiRouteInfo; - - } - - public ApiRouteInfo getApiRouteInstance(String serviceName, String version, Jedis jedis) - throws Exception { - if ("null".equals(version)) { - version = ""; - } - - ApiRouteInfo apiRouteInfo = null; - - - - String routekey = - RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, - RouteUtil.ROUTE_PATH_INFO); - Map infomap = jedis.hgetAll(routekey); - if (!infomap.isEmpty()) { - apiRouteInfo = new ApiRouteInfo(); - apiRouteInfo.setServiceName(serviceName); - apiRouteInfo.setVersion(version); - apiRouteInfo.setUrl(infomap.get("url")); - apiRouteInfo.setMetricsUrl(infomap.get("metricsUrl")); - apiRouteInfo.setApiJson(infomap.get("apijson")); - apiRouteInfo.setApiJsonType(infomap.get("apiJsonType")); - apiRouteInfo.setControl(infomap.get("control")); - apiRouteInfo.setStatus(infomap.get("status")); - apiRouteInfo.setVisualRange(infomap.get("visualRange")); - apiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); - - - - String serviceLBkey = - RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, - RouteUtil.ROUTE_PATH_LOADBALANCE); - Set serviceLBset = jedis.keys(serviceLBkey + ":*"); - int serverNum = serviceLBset.size(); - RouteServer[] apiRouteServerList = new RouteServer[serverNum]; - int i = 0; - for (String serviceInfo : serviceLBset) { - Map serviceLBmap = jedis.hgetAll(serviceInfo); - RouteServer server = new RouteServer(); - server.setIp(serviceLBmap.get("ip")); - server.setPort(serviceLBmap.get("port")); - server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); - apiRouteServerList[i] = server; - i++; - } - - apiRouteInfo.setServers(apiRouteServerList); - - - } - - - return apiRouteInfo; - } - - - public synchronized ApiRouteInfo updateApiRouteInstance(String serviceName, String version, - ApiRouteInfo apiRouteInfo, String serverPort) { - - if ("null".equals(version)) { - version = ""; - } - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException("version (" + version - + ") is not a valid format"); - } - } - - - - - try { - - - if (serviceName.equals(apiRouteInfo.getServiceName()) - && version.equals(apiRouteInfo.getVersion())) { - - deleteApiRoute(serviceName, version, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", - serverPort); - - } else { - - deleteApiRoute(serviceName, version, "*", serverPort); - } - - - saveApiRouteInstance(apiRouteInfo, serverPort); - - - } catch (ExtendedNotSupportedException e) { - throw e; - } catch (Exception e) { - LOGGER.error("update ApiRoute throw exception", e); - throw new ExtendedInternalServerErrorException("update apiRouteInfo throw exception" - + e.getMessage()); - - } - - return apiRouteInfo; - - } - - - public synchronized ApiRouteInfo updateApiRouteStatus(String serviceName, String version, - String status) { - - if ("null".equals(version)) { - version = ""; - } - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException("version (" + version - + ") is not a valid format"); - } - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { - throw new ExtendedNotSupportedException( - "save ApiRouteInfo Status FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - ApiRouteInfo new_apiRouteInfo = getApiRouteInstance(serviceName, version); - - - - String serviceInfokey = - RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version, - RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("status", status); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new Exception("fetch from jedis pool failed,null object!"); - } - - jedis.hmset(serviceInfokey, serviceInfoMap); - new_apiRouteInfo.setStatus(status); - - - } catch (Exception e) { - LOGGER.error("update ApiRoute status throw exception", e); - throw new ExtendedInternalServerErrorException("update ApiRoute status throw exception" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return new_apiRouteInfo; - } - - - - public synchronized ApiRouteInfo saveApiRouteInstance(ApiRouteInfo apiRouteInfo, - String serverPort) { - - - - if (StringUtils.isBlank(apiRouteInfo.getServiceName()) - || apiRouteInfo.getServers().length == 0) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL: Some required fields are empty"); - } - - if (StringUtils.isNotBlank(apiRouteInfo.getVersion())) { - if (!RegExpTestUtil.versionRegExpTest(apiRouteInfo.getVersion())) { - throw new ExtendedNotSupportedException("version (" + apiRouteInfo.getVersion() - + ") is not a valid format"); - } - } - - if (StringUtils.isNotBlank(apiRouteInfo.getUrl())) { - if (!RegExpTestUtil.urlRegExpTest(apiRouteInfo.getUrl())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:url is not a valid format(url must be begin with /)"); - - } - } - - if (!RouteUtil.contain(RouteUtil.visualRangeRange, apiRouteInfo.getVisualRange())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:VisualRange is wrong,value range:(" - + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.controlRangeMatches, apiRouteInfo.getControl())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:control is wrong,value range:(" - + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, apiRouteInfo.getStatus())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, apiRouteInfo.getUseOwnUpstream())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" - + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); - } - - - RouteServer[] serverList = apiRouteInfo.getServers(); - for (int i = 0; i < serverList.length; i++) { - RouteServer server = serverList[i]; - if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { - throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:IP(" - + server.getIp() + ")is not a valid ip address"); - } - - if (!RegExpTestUtil.portRegExpTest(server.getPort())) { - throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:Port(" - + server.getPort() + ")is not a valid Port address"); - } - } - - - String serviceInfokey = - RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, - apiRouteInfo.getServiceName().trim(), apiRouteInfo.getVersion().trim(), - RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("url", "/".equals(apiRouteInfo.getUrl().trim()) ? "" : apiRouteInfo - .getUrl().trim()); - serviceInfoMap.put("apijson", apiRouteInfo.getApiJson()); - serviceInfoMap.put("apiJsonType", apiRouteInfo.getApiJsonType()); - serviceInfoMap.put("metricsUrl", apiRouteInfo.getMetricsUrl()); - serviceInfoMap.put("control", apiRouteInfo.getControl()); - serviceInfoMap.put("status", apiRouteInfo.getStatus()); - serviceInfoMap.put("visualRange", apiRouteInfo.getVisualRange()); - serviceInfoMap.put("useOwnUpstream", apiRouteInfo.getUseOwnUpstream()); - - - String serviceLBkey = - RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, - apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(), - RouteUtil.ROUTE_PATH_LOADBALANCE); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - - - for (int i = 0; i < serverList.length; i++) { - Map servermap = new HashMap(); - RouteServer server = serverList[i]; - - servermap.put("ip", server.getIp()); - servermap.put("port", server.getPort()); - servermap.put("weight", Integer.toString(server.getWeight())); - - jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return apiRouteInfo; - } - - - - - public synchronized void deleteApiRoute(String serviceName, String version, String delKey, - String serverPort) { - - if ("null".equals(version)) { - version = ""; - } - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException("version (" + version - + ") is not a valid format"); - } - } - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - - String routekey = - RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, serviceName, version, - delKey); - Set infoSet = jedis.keys(routekey); - - if (infoSet.isEmpty()) { - LOGGER.warn("delete ApiRoute FAIL:serviceName-" - + serviceName + ",version:" + version + " not fond "); - } - else{ - - String[] paths = new String[infoSet.size()]; - infoSet.toArray(paths); - jedis.del(paths); - } - - - } catch (ExtendedNotFoundException e) { - throw e; - } catch (Exception e) { - LOGGER.error("delete ApiRoute throw exception", e); - throw new ExtendedInternalServerErrorException("delete ApiRoute throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - - } - - - public String[] getAllApiDocs() { - URL apiDocsPath = ApiRouteServiceWrapper.class.getResource("/ext/initSwaggerJson"); - if (apiDocsPath != null) { - String path = apiDocsPath.getPath(); - - try { - return 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[] readfile(String filepath) throws FileNotFoundException, IOException { - File file = new File(filepath); - if (file.isDirectory()) { - String[] filelist = file.list(); - return filelist; - } - return null; - } - - public String getApiGatewayPort() { - // return JedisUtil.serverIp+":"+JedisUtil.serverPort; - return System.getenv("APIGATEWAY_EXPOSE_PORT") == null ? String - .valueOf(JedisUtil.serverPort) : System.getenv("APIGATEWAY_EXPOSE_PORT"); - - } - - public DiscoverInfo getServiceDiscoverInfo() { - return RouteUtil.discoverInfo; - - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java deleted file mode 100644 index 14f5523..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/CustomRouteServiceWrapper.java +++ /dev/null @@ -1,415 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.CustomRouteInfo; -import org.openo.msb.api.RouteServer; -import org.openo.msb.api.exception.ExtendedInternalServerErrorException; -import org.openo.msb.api.exception.ExtendedNotFoundException; -import org.openo.msb.api.exception.ExtendedNotSupportedException; -import org.openo.msb.wrapper.util.JedisUtil; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; - -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; - } - - - - public CustomRouteInfo[] getAllCustomRouteInstances() { - - - Jedis jedis = null; - CustomRouteInfo[] customRouteList = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - String routekey = - RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, "*", - RouteUtil.ROUTE_PATH_INFO); - Set routeSet = jedis.keys(routekey); - customRouteList = new CustomRouteInfo[routeSet.size()]; - - int i = 0; - for (String routePath : routeSet) { - String[] routePathArray = routePath.split(":"); - CustomRouteInfo customRoute = getCustomRouteInstance(routePathArray[3], jedis); - customRouteList[i] = customRoute; - i++; - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return customRouteList; - } - - - - public CustomRouteInfo getCustomRouteInstance(String serviceName) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - CustomRouteInfo customRouteInfo; - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - customRouteInfo = getCustomRouteInstance(serviceName, jedis); - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - if (null == customRouteInfo) { - String errInfo = "customRouteInfo not found: serviceName-" + serviceName; - LOGGER.warn(errInfo); - throw new ExtendedNotFoundException(errInfo); - - } - - return customRouteInfo; - - } - - public CustomRouteInfo getCustomRouteInstance(String serviceName, Jedis jedis) throws Exception { - - - CustomRouteInfo customRouteInfo = null; - - - String routekey = - RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, - RouteUtil.ROUTE_PATH_INFO); - Map infomap = jedis.hgetAll(routekey); - if (!infomap.isEmpty()) { - customRouteInfo = new CustomRouteInfo(); - customRouteInfo.setServiceName(serviceName); - customRouteInfo.setUrl(infomap.get("url")); - customRouteInfo.setControl(infomap.get("control")); - customRouteInfo.setStatus(infomap.get("status")); - customRouteInfo.setVisualRange(infomap.get("visualRange")); - customRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); - - - String serviceLBkey = - RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, - RouteUtil.ROUTE_PATH_LOADBALANCE); - Set serviceLBset = jedis.keys(serviceLBkey + ":*"); - int serverNum = serviceLBset.size(); - RouteServer[] CustomRouteServerList = new RouteServer[serverNum]; - int i = 0; - for (String serviceInfo : serviceLBset) { - Map serviceLBmap = jedis.hgetAll(serviceInfo); - RouteServer server = new RouteServer(); - server.setIp(serviceLBmap.get("ip")); - server.setPort(serviceLBmap.get("port")); - server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); - CustomRouteServerList[i] = server; - i++; - } - - customRouteInfo.setServers(CustomRouteServerList); - } - - - return customRouteInfo; - } - - public synchronized CustomRouteInfo updateCustomRouteInstance(String serviceName, - CustomRouteInfo customRouteInfo, String serverPort) { - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - try { - - if (serviceName.equals(customRouteInfo.getServiceName())) { - deleteCustomRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", serverPort); - } else { - deleteCustomRoute(serviceName, "*", serverPort); - } - - - saveCustomRouteInstance(customRouteInfo, serverPort); - - - - } catch (ExtendedNotSupportedException e) { - throw e; - } catch (Exception e) { - LOGGER.error("updateCustomRoute throw exception", e); - throw new ExtendedInternalServerErrorException("update CustomRoute throw exception" - + e.getMessage()); - - } - - return customRouteInfo; - - } - - public synchronized CustomRouteInfo updateCustomRouteStatus(String serviceName, String status) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo Status FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - CustomRouteInfo new_customRouteInfo = getCustomRouteInstance(serviceName); - - - - String serviceInfokey = - RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName, - RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("status", status); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - new_customRouteInfo.setStatus(status); - - } catch (Exception e) { - - LOGGER.error("update CustomRoute status throw exception", e); - throw new ExtendedInternalServerErrorException( - "update CustomRoute status throw exception" + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return new_customRouteInfo; - } - - public synchronized CustomRouteInfo saveCustomRouteInstance(CustomRouteInfo customRouteInfo, - String serverPort) { - - if (StringUtils.isBlank(customRouteInfo.getServiceName()) - || customRouteInfo.getServers().length == 0) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL: Some required fields are empty"); - } - - - if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getServiceName())) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL: ServiceName is not a valid format(ServiceName must be begin with /)"); - - } - - if (StringUtils.isNotBlank(customRouteInfo.getUrl())){ - if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getUrl())) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL:url is not a valid format(url must be begin with /)"); - - } - } - - if (!RouteUtil.contain(RouteUtil.visualRangeRange, customRouteInfo.getVisualRange())) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL:VisualRange is wrong,value range:(" - + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.controlRangeMatches, customRouteInfo.getControl())) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL:control is wrong,value range:(" - + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, customRouteInfo.getStatus())) { - throw new ExtendedNotSupportedException( - "save CustomRouteInfo FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, customRouteInfo.getUseOwnUpstream())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" - + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); - } - - RouteServer[] serverList = customRouteInfo.getServers(); - for (int i = 0; i < serverList.length; i++) { - RouteServer server = serverList[i]; - if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { - throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:IP(" - + server.getIp() + ")is not a valid ip address"); - } - - if (!RegExpTestUtil.portRegExpTest(server.getPort())) { - throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:Port(" - + server.getPort() + ")is not a valid Port address"); - } - } - - - String serviceInfokey = - RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, - customRouteInfo.getServiceName().trim(), RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("url", "/".equals(customRouteInfo.getUrl().trim()) - ? "" - : customRouteInfo.getUrl().trim()); - serviceInfoMap.put("control", customRouteInfo.getControl()); - serviceInfoMap.put("status", customRouteInfo.getStatus()); - serviceInfoMap.put("visualRange", customRouteInfo.getVisualRange()); - serviceInfoMap.put("useOwnUpstream", customRouteInfo.getUseOwnUpstream()); - - - - String serviceLBkey = - RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, - customRouteInfo.getServiceName(), RouteUtil.ROUTE_PATH_LOADBALANCE); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - - - for (int i = 0; i < serverList.length; i++) { - Map servermap = new HashMap(); - RouteServer server = serverList[i]; - - servermap.put("ip", server.getIp()); - servermap.put("port", server.getPort()); - servermap.put("weight", Integer.toString(server.getWeight())); - - jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis);; - } - - return customRouteInfo; - } - - - - public synchronized void deleteCustomRoute(String serviceName, String delKey, String serverPort) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - Jedis jedis = null; - - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - String routekey = - RouteUtil - .getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, serviceName, delKey); - Set infoSet = jedis.keys(routekey); - - if (infoSet.isEmpty()) { - LOGGER.warn("delete CustomRoute FAIL:serviceName-" - + serviceName + " not fond "); - } - else{ - - String[] paths = new String[infoSet.size()]; - infoSet.toArray(paths); - jedis.del(paths); - } - - } catch (ExtendedNotFoundException e) { - throw e; - } catch (Exception e) { - - LOGGER.error("delete CustomRoute throw exception", e); - throw new ExtendedInternalServerErrorException("delete CustomRoute throw exception:" - + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java deleted file mode 100644 index b85b5ad..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/IuiRouteServiceWrapper.java +++ /dev/null @@ -1,392 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.IuiRouteInfo; -import org.openo.msb.api.RouteServer; -import org.openo.msb.api.exception.ExtendedInternalServerErrorException; -import org.openo.msb.api.exception.ExtendedNotFoundException; -import org.openo.msb.api.exception.ExtendedNotSupportedException; -import org.openo.msb.wrapper.util.JedisUtil; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; - -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; - } - - public IuiRouteInfo[] getAllIuiRouteInstances() { - - - Jedis jedis = null; - IuiRouteInfo[] iuiRouteList = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - String routekey = - RouteUtil - .getPrefixedKey("", RouteUtil.IUIROUTE, "*", RouteUtil.ROUTE_PATH_INFO); - Set routeSet = jedis.keys(routekey); - iuiRouteList = new IuiRouteInfo[routeSet.size()]; - - int i = 0; - for (String routePath : routeSet) { - String[] routePathArray = routePath.split(":"); - IuiRouteInfo iuiRoute = getIuiRouteInstance(routePathArray[3], jedis); - iuiRouteList[i] = iuiRoute; - i++; - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return iuiRouteList; - } - - - public IuiRouteInfo getIuiRouteInstance(String serviceName) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - IuiRouteInfo iuiRouteInfo = null; - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - iuiRouteInfo = getIuiRouteInstance(serviceName, jedis); - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - if (null == iuiRouteInfo) { - String errInfo = "iuiRouteInfo not found: serviceName-" + serviceName; - LOGGER.warn(errInfo); - throw new ExtendedNotFoundException(errInfo); - - } - - return iuiRouteInfo; - - } - - public IuiRouteInfo getIuiRouteInstance(String serviceName, Jedis jedis) throws Exception { - - - IuiRouteInfo iuiRouteInfo = null; - - - String routekey = - RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, - RouteUtil.ROUTE_PATH_INFO); - Map infomap = jedis.hgetAll(routekey); - if (!infomap.isEmpty()) { - iuiRouteInfo = new IuiRouteInfo(); - iuiRouteInfo.setServiceName(serviceName); - iuiRouteInfo.setUrl(infomap.get("url")); - iuiRouteInfo.setControl(infomap.get("control")); - iuiRouteInfo.setStatus(infomap.get("status")); - iuiRouteInfo.setVisualRange(infomap.get("visualRange")); - iuiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream")); - - - String serviceLBkey = - RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, - RouteUtil.ROUTE_PATH_LOADBALANCE); - Set serviceLBset = jedis.keys(serviceLBkey + ":*"); - int serverNum = serviceLBset.size(); - RouteServer[] iuiRouteServerList = new RouteServer[serverNum]; - int i = 0; - for (String serviceInfo : serviceLBset) { - Map serviceLBmap = jedis.hgetAll(serviceInfo); - RouteServer server = new RouteServer(); - server.setIp(serviceLBmap.get("ip")); - server.setPort(serviceLBmap.get("port")); - server.setWeight(Integer.parseInt(serviceLBmap.get("weight"))); - iuiRouteServerList[i] = server; - i++; - } - - iuiRouteInfo.setServers(iuiRouteServerList); - } - - - return iuiRouteInfo; - } - - public synchronized IuiRouteInfo updateIuiRouteInstance(String serviceName, - IuiRouteInfo iuiRouteInfo) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - try { - if (serviceName.equals(iuiRouteInfo.getServiceName())) { - deleteIuiRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*"); - - } else { - deleteIuiRoute(serviceName, "*"); - } - saveIuiRouteInstance(iuiRouteInfo); - - } catch (ExtendedNotSupportedException e) { - throw e; - } catch (Exception e) { - LOGGER.error("updateIuiRoute throw exception", e); - throw new ExtendedInternalServerErrorException("update IuiRouteInfo throw exception" - + e.getMessage()); - } - - return iuiRouteInfo; - - } - - public synchronized IuiRouteInfo updateIuiRouteStatus(String serviceName, String status) { - - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) { - throw new ExtendedNotSupportedException( - "save IuiRouteInfo Status FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - IuiRouteInfo new_iuiRouteInfo = getIuiRouteInstance(serviceName); - - String serviceInfokey = - RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, - RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("status", status); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - new_iuiRouteInfo.setStatus(status); - - } catch (Exception e) { - LOGGER.error("update IuiRoute status throw exception", e); - throw new ExtendedInternalServerErrorException( - "update IuiRouteInfo status throw exception" + e.getMessage()); - - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return new_iuiRouteInfo; - } - - public synchronized IuiRouteInfo saveIuiRouteInstance(IuiRouteInfo iuiRouteInfo) { - - if (StringUtils.isBlank(iuiRouteInfo.getServiceName()) - || iuiRouteInfo.getServers().length == 0) { - throw new ExtendedNotSupportedException( - "save iuiRouteInfo FAIL: Some required fields are empty"); - } - - if (StringUtils.isNotBlank(iuiRouteInfo.getUrl())){ - if (!RegExpTestUtil.urlRegExpTest(iuiRouteInfo.getUrl())) { - throw new ExtendedNotSupportedException( - "save iuiRouteInfo FAIL:url is not a valid format(url must be begin with /)"); - - } - } - - if (!RouteUtil.contain(RouteUtil.visualRangeRange, iuiRouteInfo.getVisualRange())) { - throw new ExtendedNotSupportedException( - "save iuiRouteInfo FAIL:VisualRange is wrong,value range:(" - + RouteUtil.show(RouteUtil.visualRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.controlRangeMatches, iuiRouteInfo.getControl())) { - throw new ExtendedNotSupportedException( - "save iuiRouteInfo FAIL:control is wrong,value range:(" - + RouteUtil.show(RouteUtil.controlRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.statusRangeMatches, iuiRouteInfo.getStatus())) { - throw new ExtendedNotSupportedException( - "save iuiRouteInfo FAIL:status is wrong,value range:(" - + RouteUtil.show(RouteUtil.statusRangeMatches) + ")"); - } - - if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, iuiRouteInfo.getUseOwnUpstream())) { - throw new ExtendedNotSupportedException( - "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:(" - + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")"); - } - - RouteServer[] serverList = iuiRouteInfo.getServers(); - for (int i = 0; i < serverList.length; i++) { - RouteServer server = serverList[i]; - if (!RegExpTestUtil.ipRegExpTest(server.getIp())) { - throw new ExtendedNotSupportedException("save iuiRouteInfo FAIL:IP(" - + server.getIp() + ")is not a valid ip address"); - } - - if (!RegExpTestUtil.portRegExpTest(server.getPort())) { - throw new ExtendedNotSupportedException("save iuiRouteInfo FAIL:Port(" - + server.getPort() + ")is not a valid Port address"); - } - } - - - String serviceInfokey = - RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, iuiRouteInfo.getServiceName().trim(), - RouteUtil.ROUTE_PATH_INFO); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("url", "/".equals(iuiRouteInfo.getUrl().trim()) ? "" : iuiRouteInfo - .getUrl().trim()); - serviceInfoMap.put("control", iuiRouteInfo.getControl()); - serviceInfoMap.put("status", iuiRouteInfo.getStatus()); - serviceInfoMap.put("visualRange", iuiRouteInfo.getVisualRange()); - serviceInfoMap.put("useOwnUpstream", iuiRouteInfo.getUseOwnUpstream()); - - - String serviceLBkey = - RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, iuiRouteInfo.getServiceName(), - RouteUtil.ROUTE_PATH_LOADBALANCE); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - - for (int i = 0; i < serverList.length; i++) { - Map servermap = new HashMap(); - RouteServer server = serverList[i]; - - servermap.put("ip", server.getIp()); - servermap.put("port", server.getPort()); - servermap.put("weight", Integer.toString(server.getWeight())); - - jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap); - } - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new ExtendedInternalServerErrorException("call redis throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis);; - } - - return iuiRouteInfo; - } - - - - public synchronized void deleteIuiRoute(String serviceName, String delKey) { - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new ExtendedInternalServerErrorException( - "fetch from jedis pool failed,null object!"); - } - - String routekey = RouteUtil.getPrefixedKey("", RouteUtil.IUIROUTE, serviceName, delKey); - Set infoSet = jedis.keys(routekey); - - if (infoSet.isEmpty()) { - LOGGER.warn("delete IuiRoute FAIL:serviceName-" - + serviceName + " not fond "); - } - else{ - - String[] paths = new String[infoSet.size()]; - infoSet.toArray(paths); - jedis.del(paths); - } - - - } catch (ExtendedNotFoundException e) { - throw e; - } catch (Exception e) { - LOGGER.error("delete IuiRoute throw exception", e); - throw new ExtendedInternalServerErrorException("delete IuiRoute throw exception:" - + e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - - } - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java deleted file mode 100644 index edab97b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MetricsServiceWrapper.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.io.IOException; - -import org.apache.http.ParseException; -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.openo.msb.api.MetricsInfo; -import org.openo.msb.wrapper.util.MetricsUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class MetricsServiceWrapper { - - private static final Logger LOGGER = LoggerFactory - .getLogger(MetricsServiceWrapper.class); - - public static MetricsInfo getMetricsInfo() { - - String metricsUrl = MetricsUtil.adminContextPath; - String metricsJson = sendGetRequest(metricsUrl); - - metricsJson = metricsJson.replace("E_", "");//.replaceAll("(?![0-9])(\\.)(?![0-9])", "_").replace("-", "_") - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, - false); - MetricsInfo metricsInfo = new MetricsInfo(); - try { - metricsInfo = mapper.readValue(metricsJson, MetricsInfo.class); - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.error("Jackson readValue to metricsInfo throw exception", e); - } - - return metricsInfo; - } - - public static String sendGetRequest(String url) { - CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpGet httpGet = new HttpGet(url); - - try { - CloseableHttpResponse res = httpClient.execute(httpGet); - try { - if (res.getStatusLine().getStatusCode() == MetricsUtil.SC_OK) { - return EntityUtils.toString(res.getEntity()); - } - } finally { - res.close(); - } - } catch (ParseException e) { - LOGGER.error("HttpClient throw ParseException:" + url, e); - } catch (IOException e) { - LOGGER.error("HttpClient throw IOException:" + url, e); - } - finally{ - try { - httpClient.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - LOGGER.error("HttpClient Close throw IOException", e); - } - } - - return null; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java deleted file mode 100644 index 0099481..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/MicroServiceWrapper.java +++ /dev/null @@ -1,515 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.MicroServiceFullInfo; -import org.openo.msb.api.MicroServiceInfo; -import org.openo.msb.api.Node; -import org.openo.msb.api.NodeInfo; -import org.openo.msb.api.exception.ExtendedInternalServerErrorException; -import org.openo.msb.api.exception.ExtendedNotFoundException; -import org.openo.msb.api.exception.ExtendedNotSupportedException; -import org.openo.msb.wrapper.util.MicroServiceDB; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.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 MicroServiceFullInfo[] getAllMicroServiceInstances(){ - - try { - return MicroServiceDB.getInstance().getAllMicroServiceInstances(); - - } catch (Exception e) { - throw new ExtendedInternalServerErrorException(e.getMessage()); - } - - } - - /** - * @Title: getMicroServiceInstance - * @Description: (getMicroServiceInstance) - * @param: @param serviceName - * @param: @param version - * @param: @return - * @return: ApiRouteInfo - */ - public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException("serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException("version (" + version - + ") is not a valid format"); - } - } - - MicroServiceFullInfo microServiceInfo; - try { - microServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort); - - } catch (Exception e) { - throw new ExtendedInternalServerErrorException(e.getMessage()); - } - - if (null == microServiceInfo) { - String errInfo = - "microservice not found: serviceName-" + serviceName + ",version-" + version; - LOGGER.warn(errInfo); - throw new ExtendedNotFoundException(errInfo); - - } - - return microServiceInfo; - } - - - - /** - * @Title: updateMicroServiceInstance - * @Description: updateMicroServiceInstance - * @param: serviceName - * @param: version - * @param: microServiceInfo - * @return: RouteResult - */ - public synchronized MicroServiceFullInfo updateMicroServiceInstance(String serviceName, - String version, MicroServiceInfo microServiceInfo) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - try { - - - MicroServiceFullInfo oldService= getMicroServiceInstance(serviceName,version,""); - - // Delete the original record - MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); - // Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(oldService, "DELETE",""); - // Save the new record - MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,""); - - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD",""); - MicroServiceFullInfo newMicroServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance( - microServiceInfo.getServiceName(), microServiceInfo.getVersion(),""); - return newMicroServiceInfo; - } catch (Exception e) { - LOGGER.error("update MicroService throw exception", e); - throw new ExtendedInternalServerErrorException(e.getMessage()); - } - - - } - - public synchronized MicroServiceFullInfo updateMicroServiceNode(String serviceName, - String version, String ip,String port, int ttl) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException( - "update MicroService Node FAIL:serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException( - "update MicroService Node FAIL:version is not a valid format"); - } - } - - if (!RegExpTestUtil.ipRegExpTest(ip)) { - throw new ExtendedNotSupportedException("update MicroService Node FAIL:ip(" + ip - + ")is not a valid IP address"); - } - - if (!RegExpTestUtil.portRegExpTest(port)) { - throw new ExtendedNotSupportedException("update MicroService Node FAIL:port(" + port - + ")is not a valid Port address"); - } - - try { - - MicroServiceDB.getInstance().updateMicroServiceNode2Redis(serviceName, version, ip,port,ttl); - - MicroServiceFullInfo newMicroServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); - - 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()); - } - } - - /** - * @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("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException( - "update MicroService status FAIL:serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException( - "update MicroService status FAIL:version is not a valid format"); - } - } - - if(!"0".equals(status) && !"2".equals(status) && !"1".equals(status)){ - - throw new ExtendedNotSupportedException("update MicroService status FAIL:status is wrong"); - } - - - try { - - MicroServiceDB.getInstance().updateMicroServiceStatus(serviceName, version, status); - - MicroServiceFullInfo newMicroServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); - - // Notify the listeners - MicroServiceDB.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( - MicroServiceInfo microServiceInfo, boolean createOrUpdate,String requestIP,String serverPort) { - - if (StringUtils.isBlank(microServiceInfo.getServiceName()) - || StringUtils.isBlank(microServiceInfo.getProtocol()) - || microServiceInfo.getNodes().size() == 0) { - throw new ExtendedNotSupportedException( - "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 ExtendedNotSupportedException("register MicroServiceInfo FAIL:IP(" - + node.getIp() + ")is not a valid ip address"); - } - - if (!RegExpTestUtil.portRegExpTest(node.getPort())) { - throw new ExtendedNotSupportedException("register MicroServiceInfo FAIL:Port(" - + node.getPort() + ")is not a valid Port address"); - } - } - - if (StringUtils.isNotBlank(microServiceInfo.getVersion())) { - if (!RegExpTestUtil.versionRegExpTest(microServiceInfo.getVersion())) { - throw new ExtendedNotSupportedException( - "register MicroServiceInfo FAIL:version is not a valid format"); - - } - } - - if (StringUtils.isNotBlank(microServiceInfo.getUrl().trim())) { - if (!RegExpTestUtil.urlRegExpTest(microServiceInfo.getUrl())) { - throw new ExtendedNotSupportedException( - "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 ExtendedNotSupportedException( - "register MicroServiceInfo FAIL:Protocol is wrong,value range:(" - + RouteUtil.PROTOCOL_LIST + ")"); - } - - - try { - - - - if (createOrUpdate == false) { - //After the first remove added - MicroServiceDB.getInstance().deleteMicroService( - microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort); - - //Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",serverPort); - - } - - //Save the new record - MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort); - //Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD",serverPort); - - - - MicroServiceFullInfo newMicroServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance( - microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort); - - - - return newMicroServiceInfo; - - } catch (ExtendedNotSupportedException e) { - throw e; - } catch (Exception e) { - throw new ExtendedInternalServerErrorException(e.getMessage()); - } - - } - - - public synchronized void deleteMicroService(String serviceName, String version) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:version is not a valid format"); - - } - } - - try { - - MicroServiceFullInfo microServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); - - if (microServiceInfo == null) { - LOGGER.warn("serviceName-"+ serviceName + ",version-" + version + " not fond "); - return; - } - - MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); - //Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",""); - - } catch (Exception e) { - LOGGER.error("delete MicroServiceInfo throw exception", e); - throw new ExtendedInternalServerErrorException(e.getMessage()); - - } - - LOGGER.info("delete MicroServiceInfo success:serviceName-" - + serviceName + ",version-" + version ); - - } - - - public synchronized void deleteMicroService(String serviceName, String version,String serverPort) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:version is not a valid format"); - - } - } - - try { - - MicroServiceFullInfo microServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort); - - if (microServiceInfo == null) { - throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-" - + serviceName + ",version-" + version + " not fond "); - } - - MicroServiceDB.getInstance().deleteMicroService(serviceName, version,serverPort); - //Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",serverPort); - } catch (ExtendedNotFoundException e) { - throw e; - } catch (Exception e) { - LOGGER.error("delete MicroServiceInfo throw exception", e); - throw new ExtendedInternalServerErrorException(e.getMessage()); - - } - - LOGGER.info("delete MicroServiceInfo success:serviceName-" - + serviceName + ",version-" + version ); - - } - - public synchronized void deleteMicroServiceInstance(String serviceName, String version, - String ip,String port) { - if("null".equals(version)) { - version=""; - } - serviceName=serviceName.replace("*", "/"); - - if (StringUtils.isBlank(serviceName)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:serviceName can't be empty"); - } - - if (StringUtils.isNotBlank(version)) { - if (!RegExpTestUtil.versionRegExpTest(version)) { - throw new ExtendedNotSupportedException( - "delete MicroServiceInfo FAIL:version is not a valid format"); - } - } - - if (!RegExpTestUtil.ipRegExpTest(ip)) { - throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:IP(" + ip - + ")is not a valid IP address"); - } - - if (!RegExpTestUtil.portRegExpTest(port)) { - throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:Port(" + port - + ")is not a valid Port address"); - } - - - try { - MicroServiceFullInfo microServiceInfo = - MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,""); - - if (microServiceInfo == null) { - throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-" - + serviceName + ",version-" + version + " not fond "); - } - - Set 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 - MicroServiceDB.getInstance().deleteMicroService(serviceName, version,""); - //Notify the listeners - MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",""); - } else { - //delete Node - MicroServiceDB.getInstance().deleteNode(serviceName, version, ip,port); - MicroServiceDB.getInstance().noticeUpdateApiListener(serviceName, version,microServiceInfo,""); - } - - break; - } - } - - if (!ifFindBNode) { - throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL: node-" + ip+":"+port - + " not fond "); - } - - - } catch (ExtendedNotFoundException e) { - throw e; - } catch (Exception e) { - LOGGER.error("deleteApiRoute throw exception", e); - throw new ExtendedInternalServerErrorException(e.getMessage()); - - } - - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java deleted file mode 100644 index 23a02a1..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/ServiceAccessWrapper.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.openo.msb.api.ServiceAccessInfo; -import org.openo.msb.wrapper.util.JedisUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; - -public class ServiceAccessWrapper { - private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAccessWrapper.class); - - private static ServiceAccessWrapper instance = new ServiceAccessWrapper(); - - private ServiceAccessWrapper() {} - - public static ServiceAccessWrapper getInstance() { - return instance; - } - - public ServiceAccessInfo getApiServiceAccessAddr(String serviceName, String version, String host) { - - ServiceAccessInfo apiRouteAccessInfo = null; - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new Exception("fetch from jedis pool failed,null object!"); - } - - if ("null".equals(version)) { - version = ""; - } - - String routekey = - RouteUtil.getPrefixedKey("",RouteUtil.APIROUTE, serviceName, version, - RouteUtil.ROUTE_PATH_INFO); - Boolean isExist = jedis.exists(routekey); - if (isExist) { - apiRouteAccessInfo = new ServiceAccessInfo(); - apiRouteAccessInfo.setServiceName(serviceName); - apiRouteAccessInfo.setVersion(version); - String accessAddr = "http://" + host + "/api/" + serviceName + "/" + version; - apiRouteAccessInfo.setAccessAddr(accessAddr); - } - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - return apiRouteAccessInfo; - - } - - public List getApiRouteAccessAddr(String serviceType, String serviceName, - String version, String host) { - List serviceList = new ArrayList(); - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new Exception("fetch from jedis pool failed,null object!"); - } - - String keyPattern = this.getRedisSearchPattern(serviceType, serviceName, version); - Set infoKeys = jedis.keys(keyPattern); - Pattern pattern = this.getKeyPattern(); - for (Iterator iterator = infoKeys.iterator(); iterator.hasNext();) { - String infoKey = (String) iterator.next(); - Matcher matcher = pattern.matcher(infoKey); - if (matcher.matches()) { - ServiceAccessInfo serviceAccessInfo = new ServiceAccessInfo(); - serviceAccessInfo.setServiceType(matcher.group("servicetype")); - serviceAccessInfo.setServiceName(matcher.group("servicename")); - serviceAccessInfo.setVersion(matcher.group("version")); - this.buildServiceAccessAddr(serviceAccessInfo, host, infoKey, jedis); - serviceList.add(serviceAccessInfo); - } - } - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - return serviceList; - - } - - private void buildServiceAccessAddr(ServiceAccessInfo serviceAccessInfo, String host, - String infoKey, Jedis jedis) { - String serviceType = serviceAccessInfo.getServiceType(); - StringBuffer accessAddr = new StringBuffer(); - switch (serviceType) { - case RouteUtil.APIROUTE: - accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) - .append("/").append(serviceAccessInfo.getServiceType()).append("/") - .append(serviceAccessInfo.getServiceName()).append("/") - .append(serviceAccessInfo.getVersion()); - serviceAccessInfo.setAccessAddr(accessAddr.toString()); - break; - case RouteUtil.IUIROUTE: - accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) - .append("/").append(serviceAccessInfo.getServiceType()).append("/") - .append(serviceAccessInfo.getServiceName()); - serviceAccessInfo.setAccessAddr(accessAddr.toString()); - break; - case RouteUtil.CUSTOMROUTE: - accessAddr.append("http://").append(host).append(":").append(JedisUtil.serverPort) - .append(serviceAccessInfo.getServiceName()); - serviceAccessInfo.setAccessAddr(accessAddr.toString()); - break; - case RouteUtil.P2PROUTE: - accessAddr.append(jedis.hget(infoKey, "url")); - serviceAccessInfo.setAccessAddr(accessAddr.toString()); - break; - default: - serviceAccessInfo.setAccessAddr("not supported now"); - break; - } - } - - private String getRedisSearchPattern(String serviceType, String serviceName, String version) { - StringBuffer sb = new StringBuffer(); - sb.append(RouteUtil.ROUTE_PATH); - if (null != serviceType && !"".equals(serviceType)) { - sb.append(":").append(serviceType); - } else { - sb.append(":").append("*"); - } - sb.append(":").append(serviceName); - if (null != version && !"".equals(version)) { - sb.append(":"); - sb.append(version); - sb.append(":"); - } else { - sb.append(":*"); - } - sb.append(RouteUtil.ROUTE_PATH_INFO); - return sb.toString(); - } - - private Pattern getKeyPattern() { - String pStr = - "conductor:routing:(?api|iui|custom|p2p):(?[^:]+)(:(?[^:]*))?:info"; - return Pattern.compile(pStr); - } -} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java deleted file mode 100644 index 67115a8..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul; - -import static org.openo.msb.wrapper.consul.util.ClientUtil.response; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MediaType; - -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.ConsulResponse; -import org.openo.msb.wrapper.consul.model.catalog.CatalogNode; -import org.openo.msb.wrapper.consul.model.catalog.CatalogService; -import org.openo.msb.wrapper.consul.model.health.Node; -import org.openo.msb.wrapper.consul.option.CatalogOptions; -import org.openo.msb.wrapper.consul.option.QueryOptions; - -/** - * HTTP Client for /v1/catalog/ endpoints or api/catalog/v1 by openresty - */ -public class CatalogClient { - - private static final GenericType> TYPE_STRING_LIST = new GenericType>() {}; - private static final GenericType> TYPE_NODE_LIST = new GenericType>() {}; - private static final GenericType>> TYPE_SERVICES_MAP = new GenericType>>() {}; - private static final GenericType> TYPE_CATALOG_SERVICE_LIST = new GenericType>() {}; - private static final GenericType TYPE_CATALOG_NODE = new GenericType() {}; - - private final WebTarget webTarget; - - /** - * Constructs an instance of this class. - * - * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. - */ - CatalogClient(WebTarget webTarget) { - this.webTarget = webTarget; - } - - /** - * Retrieves all datacenters. - * - * GET /v1/catalog/datacenters - * - * @return A list of datacenter names. - */ - public List getDatacenters() { - return webTarget.path("datacenters").request() - .accept(MediaType.APPLICATION_JSON_TYPE).get(TYPE_STRING_LIST); - } - - /** - * Retrieves all nodes. - * - * GET /v1/catalog/nodes - * - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. - */ - public ConsulResponse> getNodes() { - return getNodes(null, QueryOptions.BLANK); - } - - /** - * Retrieves all nodes for a given datacenter. - * - * GET /v1/catalog/nodes?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. - */ - public ConsulResponse> getNodes(CatalogOptions catalogOptions) { - return getNodes(catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/nodes - * - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. - */ - public ConsulResponse> getNodes(QueryOptions queryOptions) { - return getNodes(null, queryOptions); - } - - /** - * Retrieves all nodes for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/nodes?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. - */ - public ConsulResponse> getNodes(CatalogOptions catalogOptions, QueryOptions queryOptions) { - return response(webTarget.path("nodes"), catalogOptions, queryOptions, TYPE_NODE_LIST); - } - - /** - * Retrieves all services for a given datacenter. - * - * GET /v1/catalog/services?dc={datacenter} - * - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. - */ - public ConsulResponse>> getServices() { - return getServices(null, QueryOptions.BLANK); - } - - /** - * Retrieves all services for a given datacenter. - * - * GET /v1/catalog/services?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. - */ - public ConsulResponse>> getServices(CatalogOptions catalogOptions) { - return getServices(catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/services?dc={datacenter} - * - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. - */ - public ConsulResponse>> getServices(QueryOptions queryOptions) { - return getServices(null, queryOptions); - } - - /** - * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.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 org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. - */ - public ConsulResponse>> getServices(CatalogOptions catalogOptions, QueryOptions queryOptions) { - return response(webTarget.path("services"), catalogOptions, queryOptions, TYPE_SERVICES_MAP); - } - - public void getService(QueryOptions queryOptions, ConsulResponseCallback>> callback) { - response(webTarget.path("services"), CatalogOptions.BLANK, - queryOptions, TYPE_SERVICES_MAP, callback); - } - - /** - * Retrieves a single service. - * - * GET /v1/catalog/service/{service} - * - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing - * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse> getService(String service) { - return getService(service, null, QueryOptions.BLANK); - } - - /** - * Retrieves a single service for a given datacenter. - * - * GET /v1/catalog/service/{service}?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing - * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse> getService(String service, CatalogOptions catalogOptions) { - return getService(service, catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves a single service with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/service/{service} - * - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing - * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse> getService(String service, QueryOptions queryOptions) { - return getService(service, null, queryOptions); - } - - public void getService(String service, QueryOptions queryOptions, ConsulResponseCallback> callback) { - - response(webTarget.path("service").path(service), CatalogOptions.BLANK, - queryOptions, TYPE_CATALOG_SERVICE_LIST, callback); - } - - - - /** - * Retrieves a single service for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/service/{service}?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing - * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse> getService(String service, CatalogOptions catalogOptions, - QueryOptions queryOptions) { - return response(webTarget.path("service").path(service), catalogOptions, queryOptions, - TYPE_CATALOG_SERVICE_LIST); - } - - /** - * Retrieves a single node. - * - * GET /v1/catalog/node/{node} - * - * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse getNode(String node) { - return getNode(node, null, QueryOptions.BLANK); - } - - /** - * Retrieves a single node for a given datacenter. - * - * GET /v1/catalog/node/{node}?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse getNode(String node, CatalogOptions catalogOptions) { - return getNode(node, catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves a single node with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/node/{node} - * - * @param queryOptions The Query Options to use. - * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse getNode(String node, QueryOptions queryOptions) { - return getNode(node, null, queryOptions); - } - - /** - * Retrieves a single node for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/catalog/node/{node}?dc={datacenter} - * - * @param catalogOptions Catalog specific options to use. - * @param queryOptions The Query Options to use. - * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. - */ - public ConsulResponse getNode(String node, CatalogOptions catalogOptions, QueryOptions queryOptions) { - return response(webTarget.path("node").path(node), catalogOptions, queryOptions, - TYPE_CATALOG_NODE); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java deleted file mode 100644 index 46cfc00..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java +++ /dev/null @@ -1,314 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul; - -import java.net.MalformedURLException; -import java.net.URL; - -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; - -import org.openo.msb.wrapper.consul.util.Jackson; -import org.openo.msb.wrapper.consul.util.ObjectMapperContextResolver; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.guava.GuavaModule; -import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; -import com.google.common.net.HostAndPort; - -/** - * Client for interacting with the Consul HTTP API. - * - * @author rfast - */ -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 final CatalogClient catalogClient; - - private final HealthClient healthClient; - - - /** - * Private constructor. - * - * @param url The full URL of a running Consul instance. - * @param builder JAX-RS client builder instance. - */ - private Consul(String url, ClientBuilder builder, ObjectMapper mapper) { - - if (!FluentIterable.from(builder.getConfiguration().getClasses()) - .filter(new Predicate>() { - @Override - public boolean apply(final Class clazz) { - return JacksonJaxbJsonProvider.class.isAssignableFrom(clazz); - } - }).first().isPresent()) { - builder.register(JacksonJaxbJsonProvider.class); - } - final Client client = builder - .register(new ObjectMapperContextResolver(mapper)) - .build(); - - - if(url.endsWith("8500")){ - this.catalogClient = new CatalogClient(client.target(url).path("v1").path("catalog")); - this.healthClient = new HealthClient(client.target(url).path("v1").path("health")); - } - else{ - this.catalogClient = new CatalogClient(client.target(url).path("api").path("catalog").path("v1")); - this.healthClient = new HealthClient(client.target(url).path("api").path("health").path("v1")); - } - - -// agentClient.ping(); - } - - /** - * Creates a new client given a complete URL. - * - * @deprecated Use {@link Consul.Builder} - * - * @param url The Consul API URL. - * @param builder The JAX-RS client builder instance. - * @return A new client. - */ - @Deprecated - public static Consul newClient(String url, ClientBuilder builder, ObjectMapper mapper) { - return new Consul(url, builder, mapper); - } - - /** - * Creates a new client given a host and a port. - * - * @deprecated Use {@link Consul.Builder} - * - * @param host The Consul API hostname or IP. - * @param port The Consul port. - * @param builder The JAX-RS client builder instance. - * @return A new client. - */ - @Deprecated - public static Consul newClient(String host, int port, ClientBuilder builder, ObjectMapper mapper) { - try { - return new Consul(new URL("http", host, port, "").toString(), builder, mapper); - } catch (MalformedURLException e) { - throw new ConsulException("Bad Consul URL", e); - } - } - - /** - * Creates a new client given a host and a port. - * - * @deprecated Use {@link Consul.Builder} - * - * @param host The Consul API hostname or IP. - * @param port The Consul port. - * @return A new client. - */ - @Deprecated - public static Consul newClient(String host, int port) { - return newClient(host, port, ClientBuilder.newBuilder(), Jackson.MAPPER); - } - - /** - * Creates a new client given a host and a port. - * - * @deprecated Use {@link Consul.Builder} - * - * @return A new client. - */ - @Deprecated - public static Consul newClient() { - return newClient(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT); - } - - - /** - * Get the Catalog HTTP client. - *

    - * /v1/catalog - * - * @return The Catalog HTTP client. - */ - public CatalogClient catalogClient() { - return catalogClient; - } - - public HealthClient healthClient() { - return healthClient; - } - /** - * Creates a new {@link Builder} object. - * - * @return A new Consul builder. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builder for {@link Consul} client objects. - */ - public static class Builder { - private URL url; - private Optional sslContext = Optional.absent(); - private ObjectMapper objectMapper = Jackson.MAPPER; - private ClientBuilder clientBuilder = ClientBuilder.newBuilder(); - - { - try { - url = new URL("http", "localhost", 8500, ""); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - - /** - * Constructs a new builder. - */ - Builder() { - - } - - /** - * Sets the URL from a {@link URL} object. - * - * @param url The Consul agent URL. - * @return The builder. - */ - public Builder withUrl(URL url) { - this.url = url; - - return this; - } - - /** - * Sets the URL from a {@link HostAndPort} object. - * - * @param hostAndPort The Consul agent host and port. - * @return The builder. - */ - public Builder withHostAndPort(HostAndPort hostAndPort) { - try { - this.url = new URL("http", hostAndPort.getHostText(), hostAndPort.getPort(), ""); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Sets the URL from a string. - * - * @param url The Consul agent URL. - * @return The builder. - */ - public Builder withUrl(String url) { - try { - this.url = new URL(url); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Sets the {@link SSLContext} for the client. - * - * @param sslContext The SSL context for HTTPS agents. - * @return The builder. - */ - public Builder withSslContext(SSLContext sslContext) { - this.sslContext = Optional.of(sslContext); - - return this; - } - - /** - * Sets the {@link ObjectMapper} for the client. - * - * @param objectMapper The {@link ObjectMapper} to use. - * @return The builder. - */ - public Builder withObjectMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - - objectMapper.registerModule(new GuavaModule()); - - return this; - } - - /** - * Sets the JAX-RS {@link ClientBuilder} to use. - * - * @param clientBuilder The JAX-RS builder. - * @return This builder. - */ - public Builder withClientBuilder(ClientBuilder clientBuilder) { - this.clientBuilder = clientBuilder; - - return this; - } - - /** - * Constructs a new {@link Consul} client. - * - * @return A new Consul client. - */ - public Consul build() { - if (this.sslContext.isPresent()) { - this.clientBuilder.sslContext(this.sslContext.get()); - } - - return new Consul(this.url.toExternalForm(), this.clientBuilder, this.objectMapper); - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java deleted file mode 100644 index a17d68f..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul; - -/** - * Wraps an exception thrown whilst interacting with the Consul API. - */ -public class ConsulException extends RuntimeException { - - /** - * Constructs an instance of this class. - * - * @param message The exception message. - */ - public ConsulException(String message) { - super(message); - } - - /** - * Constructs an instance of this class. - * - * @param message The exception message. - * @param throwable The wrapped {@link java.lang.Throwable} object. - */ - public ConsulException(String message, Throwable throwable) { - super(message, throwable); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java deleted file mode 100644 index 9fde7ee..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java +++ /dev/null @@ -1,262 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul; - -import static org.openo.msb.wrapper.consul.util.ClientUtil.response; - -import java.util.List; - -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; - -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.ConsulResponse; -import org.openo.msb.wrapper.consul.model.health.ServiceHealth; -import org.openo.msb.wrapper.consul.option.CatalogOptions; -import org.openo.msb.wrapper.consul.option.QueryOptions; - -/** - * HTTP Client for /v1/health/ endpoints. - */ -public class HealthClient { - - - private static final GenericType> TYPE_SERVICE_HEALTH_LIST = - new GenericType>() {}; - - private final WebTarget webTarget; - - /** - * Constructs an instance of this class. - * - * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. - */ - HealthClient(WebTarget webTarget) { - this.webTarget = webTarget; - } - - - - /** - * Retrieves the healthchecks for all healthy service instances. - * - * GET /v1/health/service/{service}?passing - * - * @param service The service to query. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getHealthyServiceInstances(String service) { - return getHealthyServiceInstances(service, null, QueryOptions.BLANK); - } - - /** - * Retrieves the healthchecks for all healthy service instances in a given datacenter. - * - * GET /v1/health/service/{service}?dc={datacenter}&passing - * - * @param service The service to query. - * @param catalogOptions The catalog specific options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getHealthyServiceInstances(String service, CatalogOptions catalogOptions) { - return getHealthyServiceInstances(service, catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves the healthchecks for all healthy service instances with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?passing - * - * @param service The service to query. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getHealthyServiceInstances(String service, QueryOptions queryOptions) { - return getHealthyServiceInstances(service, null, queryOptions); - } - - /** - * Retrieves the healthchecks for all healthy service instances in a given datacenter with - * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?dc={datacenter}&passing - * - * @param service The service to query. - * @param catalogOptions The catalog specific options to use. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getHealthyServiceInstances(String service, CatalogOptions catalogOptions, - QueryOptions queryOptions) { - return response(webTarget.path("service").path(service).queryParam("passing", "true"), - catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST); - } - - /** - * Asynchronously retrieves the healthchecks for all healthy service instances in a given - * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?dc={datacenter}&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> callback) { - response(webTarget.path("service").path(service).queryParam("passing", "true"), - catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); - } - - /** - * Asynchronously retrieves the healthchecks for all healthy service instances in a given - * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?dc={datacenter}&passing - * - * Experimental. - * - * @param service The service to query. - * @param queryOptions The Query Options to use. - * @param callback Callback implemented by callee to handle results. - */ - public void getHealthyServiceInstances(String service, QueryOptions queryOptions, - ConsulResponseCallback> callback) { - response(webTarget.path("service").path(service).queryParam("passing", "true"), - CatalogOptions.BLANK, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); - } - - /** - * Retrieves the healthchecks for all nodes. - * - * GET /v1/health/service/{service} - * - * @param service The service to query. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getAllServiceInstances(String service) { - return getAllServiceInstances(service, null, QueryOptions.BLANK); - } - - /** - * Retrieves the healthchecks for all nodes in a given datacenter. - * - * GET /v1/health/service/{service}?dc={datacenter} - * - * @param service The service to query. - * @param catalogOptions The catalog specific options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getAllServiceInstances(String service, CatalogOptions catalogOptions) { - return getAllServiceInstances(service, catalogOptions, QueryOptions.BLANK); - } - - /** - * Retrieves the healthchecks for all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service} - * - * @param service The service to query. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getAllServiceInstances(String service, QueryOptions queryOptions) { - return getAllServiceInstances(service, null, queryOptions); - } - - /** - * Retrieves the healthchecks for all nodes in a given datacenter with - * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?dc={datacenter} - * - * @param service The service to query. - * @param catalogOptions The catalog specific options to use. - * @param queryOptions The Query Options to use. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of - * {@link com.orbitz.consul.model.health.HealthCheck} objects. - */ - public ConsulResponse> getAllServiceInstances(String service, CatalogOptions catalogOptions, - QueryOptions queryOptions) { - return response(webTarget.path("service").path(service), catalogOptions, queryOptions, - TYPE_SERVICE_HEALTH_LIST); - } - - /** - * Asynchronously retrieves the healthchecks for all nodes in a given - * datacenter with {@link org.openo.msb.wrapper.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> callback) { - response(webTarget.path("service").path(service), catalogOptions, queryOptions, - TYPE_SERVICE_HEALTH_LIST, callback); - } - - /** - * Asynchronously retrieves the healthchecks for all nodes in a given - * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. - * - * GET /v1/health/service/{service}?dc={datacenter} - * - * Experimental. - * - * @param service The service to query. - * @param queryOptions The Query Options to use. - * @param callback Callback implemented by callee to handle results. - */ - public void getAllServiceInstances(String service, QueryOptions queryOptions, - ConsulResponseCallback> callback) { - response(webTarget.path("service").path(service), CatalogOptions.BLANK, - queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java deleted file mode 100644 index d823e98..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.async; - -import org.openo.msb.wrapper.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 The Response type. - */ -public interface ConsulResponseCallback { - - /** - * Callback for a successful {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. - * - * @param consulResponse The Consul response. - */ - void onComplete(ConsulResponse consulResponse); - - /** - * Callback for an unsuccessful request. - * - * @param throwable The exception thrown. - */ - void onFailure(Throwable throwable); -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java deleted file mode 100644 index 346ba1d..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.cache; - -import java.math.BigInteger; -import java.util.List; - -import org.openo.msb.wrapper.consul.CatalogClient; -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.catalog.CatalogService; - -import com.google.common.base.Function; - -public class CatalogCache extends ConsulCache{ - - private final String serviceName; - - private CatalogCache(Function keyConversion, - ConsulCache.CallbackConsumer callbackConsumer,String serviceName) { - super(keyConversion, callbackConsumer); - this.serviceName=serviceName; - // TODO Auto-generated constructor stub - } - - - public static CatalogCache newCache( - final CatalogClient catalogClient, - final String serviceName, - final int watchSeconds){ - Function keyExtractor = new Function() { - @Override - public String apply(CatalogService input) { - //return input.getKey().substring(rootPath.length() + 1); - return input.getServiceId(); - } - }; - - final CallbackConsumer callbackConsumer = new CallbackConsumer() { - @Override - public void consume(BigInteger index, ConsulResponseCallback> callback) { - catalogClient.getService(serviceName, watchParams(index, watchSeconds),callback); - } - }; - - - return new CatalogCache(keyExtractor, callbackConsumer,serviceName); - - - } - - public String getServiceName(){ - return this.serviceName; - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java deleted file mode 100644 index 500579a..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java +++ /dev/null @@ -1,245 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.cache; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; - -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.ConsulResponse; -import org.openo.msb.wrapper.consul.option.QueryOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -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 static com.google.common.base.Preconditions.checkState; - -/** - * A cache structure that can provide an up-to-date read-only - * map backed by consul data - * - * @param - */ -public class ConsulCache { - - enum State {latent, starting, started, stopped } - - private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache.class); - - private final AtomicReference latestIndex = new AtomicReference(null); - private final AtomicReference> lastResponse = new AtomicReference>(ImmutableMap.of()); - private final AtomicReference state = new AtomicReference(State.latent); - private final CountDownLatch initLatch = new CountDownLatch(1); - private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); - private final CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList>(); - - private final Function keyConversion; - private final CallbackConsumer callBackConsumer; - private final ConsulResponseCallback> responseCallback; - - ConsulCache( - Function keyConversion, - CallbackConsumer callbackConsumer) { - this(keyConversion, callbackConsumer, 10, TimeUnit.SECONDS); - } - - ConsulCache( - Function keyConversion, - CallbackConsumer callbackConsumer, - final long backoffDelayQty, - final TimeUnit backoffDelayUnit) { - - this.keyConversion = keyConversion; - this.callBackConsumer = callbackConsumer; - - this.responseCallback = new ConsulResponseCallback>() { - @Override - public void onComplete(ConsulResponse> consulResponse) { - - if (!isRunning()) { - return; - } - updateIndex(consulResponse); - ImmutableMap full = convertToMap(consulResponse); - - boolean changed = !full.equals(lastResponse.get()); -// LOGGER.info("node changed:"+changed+"----"+full); - if (changed) { - // changes - lastResponse.set(full); - } - - if (changed) { - for (Listener l : listeners) { - l.notify(full); - } - } - - if (state.compareAndSet(State.starting, State.started)) { - initLatch.countDown(); - } - runCallback(); - } - - @Override - public void onFailure(Throwable throwable) { - - if (!isRunning()) { - return; - } - LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable); - - executorService.schedule(new Runnable() { - @Override - public void run() { - runCallback(); - } - }, backoffDelayQty, backoffDelayUnit); - } - }; - } - - 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); - } - - public ImmutableMap getMap() { - return lastResponse.get(); - } - - @VisibleForTesting - ImmutableMap convertToMap(final ConsulResponse> response) { - if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) { - return ImmutableMap.of(); - } - - final ImmutableMap.Builder builder = ImmutableMap.builder(); - final Set keySet = new HashSet<>(); - for (final V v : response.getResponse()) { - final K key = keyConversion.apply(v); - if (key != null) { - if (!keySet.contains(key)) { - builder.put(key, v); - } else { - System.out.println(key.toString()); - LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString()); - } - } - keySet.add(key); - } - return builder.build(); - } - - private void updateIndex(ConsulResponse> consulResponse) { - if (consulResponse != null && consulResponse.getIndex() != null) { - this.latestIndex.set(consulResponse.getIndex()); - } - } - - protected static QueryOptions watchParams(BigInteger index, 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 - */ - protected interface CallbackConsumer { - void consume(BigInteger index, ConsulResponseCallback> callback); - } - - /** - * Implementers can register a listener to receive - * a new map when it changes - * - * @param - */ - public interface Listener { - void notify(Map newValues); - } - - public boolean addListener(Listener listener) { - boolean added = listeners.add(listener); - if (state.get() == State.started) { - listener.notify(lastResponse.get()); - } - return added; - } - - public boolean removeListener(Listener listener) { - return listeners.remove(listener); - } - - @VisibleForTesting - protected State getState() { - return state.get(); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java deleted file mode 100644 index 349cbdd..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.cache; - - -import static com.google.common.base.Preconditions.checkState; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -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.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.ConsulResponse; -import org.openo.msb.wrapper.consul.model.catalog.CatalogService; -import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; -import org.openo.msb.wrapper.consul.option.QueryOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; - -/** - * A cache structure that can provide an up-to-date read-only - * map backed by consul data - * - * @param - */ -public class ConsulCache4Map { - - enum State {latent, starting, started, stopped } - - private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache4Map.class); - - private final AtomicReference latestIndex = new AtomicReference(null); - private final AtomicReference> lastResponse = new AtomicReference>(ImmutableList.of()); - private final AtomicReference state = new AtomicReference(State.latent); - private final CountDownLatch initLatch = new CountDownLatch(1); - private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); - private final CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList>(); - - private final CallbackConsumer callBackConsumer; - private final ConsulResponseCallback>> responseCallback; - - ConsulCache4Map(CallbackConsumer callbackConsumer) { - this( callbackConsumer, 10, TimeUnit.SECONDS); - } - - ConsulCache4Map( - CallbackConsumer callbackConsumer, - final long backoffDelayQty, - final TimeUnit backoffDelayUnit) { - - this.callBackConsumer = callbackConsumer; - - this.responseCallback = new ConsulResponseCallback>>() { - @Override - public void onComplete(ConsulResponse>> consulResponse) { - - if (!isRunning()) { - return; - } - updateIndex(consulResponse); - ImmutableList full = convertToList(consulResponse); - List oldList=lastResponse.get(); - boolean changed = !full.equals(lastResponse.get()); -// LOGGER.info("service changed:"+changed+"----"+full); - if (changed) { - // changes - lastResponse.set(full); - } - - if (changed) { - for (Listener l : listeners) { - l.notify(oldList,full); - } - } - - if (state.compareAndSet(State.starting, State.started)) { - initLatch.countDown(); - } - runCallback(); - } - - @Override - public void onFailure(Throwable throwable) { - - if (!isRunning()) { - return; - } - LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable); - - executorService.schedule(new Runnable() { - @Override - public void run() { - runCallback(); - } - }, backoffDelayQty, backoffDelayUnit); - } - }; - } - - 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); - } - - public ImmutableList getMap() { - return lastResponse.get(); - } - - @VisibleForTesting - ImmutableList convertToList(final ConsulResponse>> response) { - if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) { - return ImmutableList.of(); - } - - final ImmutableList.Builder builder = ImmutableList.builder(); - final Set keySet = new HashSet<>(); - - for(Map.Entry> entry : response.getResponse().entrySet()) { - - String key = entry.getKey(); - - if (key != null && !"consul".equals(key)) { - if (!keySet.contains(key)) { - ServiceInfo serviceInfo=new ServiceInfo(); - serviceInfo.setServiceName(key); - - List value=entry.getValue(); - for(String tag:value){ - - if(tag.startsWith("version")){ - String version; - if(tag.split(":").length==2) - { - version = tag.split(":")[1]; - } - else{ - version=""; - } - - serviceInfo.setVersion(version); - break; - } - } - - builder.add(serviceInfo); - } else { - System.out.println(key.toString()); - LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString()); - } - } - keySet.add(key); - - } - - - return builder.build(); - } - - private void updateIndex(ConsulResponse>> consulResponse) { - if (consulResponse != null && consulResponse.getIndex() != null) { - this.latestIndex.set(consulResponse.getIndex()); - } - } - - protected static QueryOptions watchParams(BigInteger index, 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 - */ - protected interface CallbackConsumer { - void consume(BigInteger index, ConsulResponseCallback>> callback); - } - - /** - * Implementers can register a listener to receive - * a new map when it changes - * - * @param - */ - public interface Listener { - void notify(List oldValues,List newValues); - } - - public boolean addListener(Listener listener) { - boolean added = listeners.add(listener); - if (state.get() == State.started) { - listener.notify(lastResponse.get(),lastResponse.get()); - } - return added; - } - - public boolean removeListener(Listener listener) { - return listeners.remove(listener); - } - - @VisibleForTesting - protected State getState() { - return state.get(); - } - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java deleted file mode 100644 index cc4d7cb..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.cache; - -import java.math.BigInteger; -import java.util.List; - -import org.openo.msb.wrapper.consul.HealthClient; -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.health.ServiceHealth; - -import com.google.common.base.Function; - -public class HealthCache extends ConsulCache{ - - private final String serviceName; - - private HealthCache(Function keyConversion, - ConsulCache.CallbackConsumer callbackConsumer,String serviceName) { - super(keyConversion, callbackConsumer); - this.serviceName=serviceName; - // TODO Auto-generated constructor stub - } - - - public static HealthCache newCache( - final HealthClient healthClient, - final String serviceName, - final int watchSeconds){ - Function keyExtractor = new Function() { - @Override - public String apply(ServiceHealth input) { - //return input.getKey().substring(rootPath.length() + 1); - return input.getService().getId(); - } - }; - - final CallbackConsumer callbackConsumer = new CallbackConsumer() { - @Override - public void consume(BigInteger index, ConsulResponseCallback> callback) { - healthClient.getHealthyServiceInstances(serviceName, watchParams(index, watchSeconds),callback); - } - }; - - - return new HealthCache(keyExtractor, callbackConsumer,serviceName); - - - } - - public String getServiceName(){ - return this.serviceName; - } - - -} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java deleted file mode 100644 index 5d16e24..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.cache; - -import java.math.BigInteger; -import java.util.List; -import java.util.Map; - -import org.openo.msb.wrapper.consul.CatalogClient; -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; - -public class ServiceCache extends ConsulCache4Map>> { - private ServiceCache( ConsulCache4Map.CallbackConsumer>> callbackConsumer) { - super(callbackConsumer); - // TODO Auto-generated constructor stub - } - - - public static ServiceCache newCache( - final CatalogClient catalogClient, - final int watchSeconds){ - - - final CallbackConsumer>> callbackConsumer = new CallbackConsumer>>() { - @Override - public void consume(BigInteger index, ConsulResponseCallback>> callback) { - catalogClient.getService(watchParams(index, watchSeconds),callback); - } - }; - - - return new ServiceCache(callbackConsumer); - - - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java deleted file mode 100644 index b19f37c..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model; - -import com.google.common.base.Objects; - -import java.math.BigInteger; - -public class ConsulResponse { - - private final T response; - private final long lastContact; - private final boolean knownLeader; - private final BigInteger index; - - public ConsulResponse(T response, long lastContact, boolean knownLeader, BigInteger index) { - this.response = response; - this.lastContact = lastContact; - this.knownLeader = knownLeader; - this.index = index; - } - - public T getResponse() { - return response; - } - - public long getLastContact() { - return lastContact; - } - - public boolean isKnownLeader() { - return knownLeader; - } - - public BigInteger getIndex() { - return index; - } - - @Override - public String toString() { - return "ConsulResponse{" + - "response=" + response + - ", lastContact=" + lastContact + - ", knownLeader=" + knownLeader + - ", index=" + index + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ConsulResponse that = (ConsulResponse) o; - - return Objects.equal(this.response, that.response) && - Objects.equal(this.lastContact, that.lastContact) && - Objects.equal(this.knownLeader, that.knownLeader) && - Objects.equal(this.index, that.index); - } - - @Override - public int hashCode() { - return Objects.hashCode(response, lastContact, knownLeader, index); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java deleted file mode 100644 index 5ffc97b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.catalog; - -import java.util.Map; - -import org.openo.msb.wrapper.consul.model.health.Node; -import org.openo.msb.wrapper.consul.model.health.Service; - -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; - - -@JsonSerialize(as = ImmutableCatalogNode.class) -@JsonDeserialize(as = ImmutableCatalogNode.class) -@JsonIgnoreProperties(ignoreUnknown = true) -public abstract class CatalogNode { - - @JsonProperty("Node") - public abstract Node getNode(); - - @JsonProperty("Services") - public abstract Map getServices(); - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java deleted file mode 100644 index 9d62f02..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.catalog; - -import java.util.List; - -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; - - -@JsonSerialize(as = ImmutableCatalogService.class) -@JsonDeserialize(as = ImmutableCatalogService.class) -@JsonIgnoreProperties(ignoreUnknown = true) -public abstract class CatalogService { - - @JsonProperty("Node") - public abstract String getNode(); - - @JsonProperty("Address") - public abstract String getAddress(); - - @JsonProperty("ServiceName") - public abstract String getServiceName(); - - @JsonProperty("ServiceID") - public abstract String getServiceId(); - - @JsonProperty("ServiceAddress") - public abstract String getServiceAddress(); - - @JsonProperty("ServicePort") - public abstract int getServicePort(); - - @JsonProperty("ServiceTags") - public abstract List getServiceTags(); -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java deleted file mode 100644 index 18830d5..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java +++ /dev/null @@ -1,305 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.catalog; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.Map; - -import javax.annotation.Generated; - -import org.openo.msb.wrapper.consul.model.health.Node; -import org.openo.msb.wrapper.consul.model.health.Service; - -/** - * Immutable implementation of {@link CatalogNode}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableCatalogNode.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "CatalogNode"}) -@JsonIgnoreProperties(ignoreUnknown = true) -public final class ImmutableCatalogNode extends CatalogNode { - private final Node node; - private final ImmutableMap services; - - private ImmutableCatalogNode( - Node node, - ImmutableMap services) { - this.node = node; - this.services = services; - } - - /** - * @return The value of the {@code node} attribute - */ - @JsonProperty(value = "Node") - @Override - public Node getNode() { - return node; - } - - /** - * @return The value of the {@code services} attribute - */ - @JsonProperty(value = "Services") - @Override - public ImmutableMap getServices() { - return services; - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogNode#getNode() node} attribute. - * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. - * @param value A new value for node - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogNode withNode(Node value) { - if (this.node == value) return this; - return new ImmutableCatalogNode(Preconditions.checkNotNull(value, "node"), this.services); - } - - /** - * Copy the current immutable object by replacing the {@link CatalogNode#getServices() services} map with the specified map. - * Nulls are not permitted as keys or values. - * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. - * @param entries The entries to be added to the services map - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogNode withServices(Map entries) { - if (this.services == entries) return this; - ImmutableMap value = ImmutableMap.copyOf(entries); - return new ImmutableCatalogNode(this.node, value); - } - - /** - * This instance is equal to all instances of {@code ImmutableCatalogNode} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableCatalogNode - && equalTo((ImmutableCatalogNode) another); - } - - private boolean equalTo(ImmutableCatalogNode another) { - return node.equals(another.node) - && services.equals(another.services); - } - - /** - * Computes a hash code from attributes: {@code node}, {@code services}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + node.hashCode(); - h = h * 17 + services.hashCode(); - return h; - } - - /** - * Prints the immutable value {@code CatalogNode...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("CatalogNode") - .add("node", node) - .add("services", services) - .toString(); - } - - /** - * Utility type used to correctly read immutable object from JSON representation. - * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonDeserialize - static final class Json extends CatalogNode { - Node node; - Map services; - @JsonProperty(value = "Node") - public void setNode(Node node) { - this.node = node; - } - @JsonProperty(value = "Services") - public void setServices(Map services) { - this.services = services; - } - @Override - public Node getNode() { throw new UnsupportedOperationException(); } - @Override - public Map getServices() { throw new UnsupportedOperationException(); } - } - - /** - * @param json A JSON-bindable data structure - * @return An immutable value type - * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonCreator - static ImmutableCatalogNode fromJson(Json json) { - ImmutableCatalogNode.Builder builder = ImmutableCatalogNode.builder(); - if (json.node != null) { - builder.node(json.node); - } - if (json.services != null) { - builder.putAllServices(json.services); - } - return builder.build(); - } - - /** - * Creates an immutable copy of a {@link CatalogNode} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable CatalogNode instance - */ - public static ImmutableCatalogNode copyOf(CatalogNode instance) { - if (instance instanceof ImmutableCatalogNode) { - return (ImmutableCatalogNode) instance; - } - return ImmutableCatalogNode.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableCatalogNode ImmutableCatalogNode}. - * @return A new ImmutableCatalogNode builder - */ - public static ImmutableCatalogNode.Builder builder() { - return new ImmutableCatalogNode.Builder(); - } - - /** - * Builds instances of type {@link ImmutableCatalogNode ImmutableCatalogNode}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private static final long INIT_BIT_NODE = 0x1L; - private long initBits = 0x1; - - private Node node; - private ImmutableMap.Builder servicesBuilder = ImmutableMap.builder(); - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code CatalogNode} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * Collection elements and entries will be added, not replaced. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(CatalogNode instance) { - Preconditions.checkNotNull(instance, "instance"); - node(instance.getNode()); - putAllServices(instance.getServices()); - return this; - } - - /** - * Initializes the value for the {@link CatalogNode#getNode() node} attribute. - * @param node The value for node - * @return {@code this} builder for use in a chained invocation - */ - public final Builder node(Node node) { - this.node = Preconditions.checkNotNull(node, "node"); - initBits &= ~INIT_BIT_NODE; - return this; - } - - /** - * Put one entry to the {@link CatalogNode#getServices() services} map. - * @param key The key in the services map - * @param value The associated value in the services map - * @return {@code this} builder for use in a chained invocation - */ - public final Builder putServices(String key, Service value) { - servicesBuilder.put(key, value); - return this; - } - - /** - * Put one entry to the {@link CatalogNode#getServices() services} map. Nulls are not permitted - * @param entry The key and value entry - * @return {@code this} builder for use in a chained invocation - */ - public final Builder putServices(Map.Entry entry) { - servicesBuilder.put(entry); - return this; - } - - /** - * Sets or replaces all mappings from the specified map as entries for the {@link CatalogNode#getServices() services} map. Nulls are not permitted - * @param entries The entries that will be added to the services map - * @return {@code this} builder for use in a chained invocation - */ - public final Builder services(Map entries) { - servicesBuilder = ImmutableMap.builder(); - return putAllServices(entries); - } - - /** - * Put all mappings from the specified map as entries to {@link CatalogNode#getServices() services} map. Nulls are not permitted - * @param entries The entries that will be added to the services map - * @return {@code this} builder for use in a chained invocation - */ - public final Builder putAllServices(Map entries) { - servicesBuilder.putAll(entries); - return this; - } - - /** - * Builds a new {@link ImmutableCatalogNode ImmutableCatalogNode}. - * @return An immutable instance of CatalogNode - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableCatalogNode build() throws IllegalStateException { - if (initBits != 0) { - throw new IllegalStateException(formatRequiredAttributesMessage()); - } - return new ImmutableCatalogNode(node, servicesBuilder.build()); - } - - private String formatRequiredAttributesMessage() { - List attributes = Lists.newArrayList(); - if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); - return "Cannot build CatalogNode, some of required attributes are not set " + attributes; - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java deleted file mode 100644 index c16b94f..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java +++ /dev/null @@ -1,625 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.catalog; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import java.util.List; -import javax.annotation.Generated; - -/** - * Immutable implementation of {@link CatalogService}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableCatalogService.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "CatalogService"}) -@JsonIgnoreProperties(ignoreUnknown = true) -public final class ImmutableCatalogService extends CatalogService { - private final String node; - private final String address; - private final String serviceName; - private final String serviceId; - private final String serviceAddress; - private final int servicePort; - private final ImmutableList serviceTags; - - private ImmutableCatalogService( - String node, - String address, - String serviceName, - String serviceId, - String serviceAddress, - int servicePort, - ImmutableList serviceTags) { - this.node = node; - this.address = address; - this.serviceName = serviceName; - this.serviceId = serviceId; - this.serviceAddress = serviceAddress; - this.servicePort = servicePort; - this.serviceTags = serviceTags; - } - - /** - * @return The value of the {@code node} attribute - */ - @JsonProperty(value = "Node") - @Override - public String getNode() { - return node; - } - - /** - * @return The value of the {@code address} attribute - */ - @JsonProperty(value = "Address") - @Override - public String getAddress() { - return address; - } - - /** - * @return The value of the {@code serviceName} attribute - */ - @JsonProperty(value = "ServiceName") - @Override - public String getServiceName() { - return serviceName; - } - - /** - * @return The value of the {@code serviceId} attribute - */ - @JsonProperty(value = "ServiceID") - @Override - public String getServiceId() { - return serviceId; - } - - /** - * @return The value of the {@code serviceAddress} attribute - */ - @JsonProperty(value = "ServiceAddress") - @Override - public String getServiceAddress() { - return serviceAddress; - } - - /** - * @return The value of the {@code servicePort} attribute - */ - @JsonProperty(value = "ServicePort") - @Override - public int getServicePort() { - return servicePort; - } - - /** - * @return The value of the {@code serviceTags} attribute - */ - @JsonProperty(value = "ServiceTags") - @Override - public ImmutableList getServiceTags() { - return serviceTags; - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getNode() node} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for node - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withNode(String value) { - if (this.node.equals(value)) return this; - return new ImmutableCatalogService( - Preconditions.checkNotNull(value, "node"), - this.address, - this.serviceName, - this.serviceId, - this.serviceAddress, - this.servicePort, - this.serviceTags); - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getAddress() address} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for address - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withAddress(String value) { - if (this.address.equals(value)) return this; - return new ImmutableCatalogService( - this.node, - Preconditions.checkNotNull(value, "address"), - this.serviceName, - this.serviceId, - this.serviceAddress, - this.servicePort, - this.serviceTags); - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceName() serviceName} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for serviceName - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withServiceName(String value) { - if (this.serviceName.equals(value)) return this; - return new ImmutableCatalogService( - this.node, - this.address, - Preconditions.checkNotNull(value, "serviceName"), - this.serviceId, - this.serviceAddress, - this.servicePort, - this.serviceTags); - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceId() serviceId} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for serviceId - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withServiceId(String value) { - if (this.serviceId.equals(value)) return this; - return new ImmutableCatalogService( - this.node, - this.address, - this.serviceName, - Preconditions.checkNotNull(value, "serviceId"), - this.serviceAddress, - this.servicePort, - this.serviceTags); - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for serviceAddress - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withServiceAddress(String value) { - if (this.serviceAddress.equals(value)) return this; - return new ImmutableCatalogService( - this.node, - this.address, - this.serviceName, - this.serviceId, - Preconditions.checkNotNull(value, "serviceAddress"), - this.servicePort, - this.serviceTags); - } - - /** - * Copy the current immutable object by setting a value for the {@link CatalogService#getServicePort() servicePort} attribute. - * A value equality check is used to prevent copying of the same value by returning {@code this}. - * @param value A new value for servicePort - * @return A modified copy of the {@code this} object - */ - public final ImmutableCatalogService withServicePort(int value) { - if (this.servicePort == value) return this; - return new ImmutableCatalogService( - this.node, - this.address, - this.serviceName, - this.serviceId, - this.serviceAddress, - value, - this.serviceTags); - } - - /** - * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}. - * @param elements The elements to set - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogService withServiceTags(String... elements) { - ImmutableList newValue = ImmutableList.copyOf(elements); - return new ImmutableCatalogService( - this.node, - this.address, - this.serviceName, - this.serviceId, - this.serviceAddress, - this.servicePort, - newValue); - } - - /** - * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}. - * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. - * @param elements An iterable of serviceTags elements to set - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogService withServiceTags(Iterable elements) { - if (this.serviceTags == elements) return this; - ImmutableList newValue = ImmutableList.copyOf(elements); - return new ImmutableCatalogService( - this.node, - this.address, - this.serviceName, - this.serviceId, - this.serviceAddress, - this.servicePort, - newValue); - } - - /** - * This instance is equal to all instances of {@code ImmutableCatalogService} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableCatalogService - && equalTo((ImmutableCatalogService) another); - } - - private boolean equalTo(ImmutableCatalogService another) { - return node.equals(another.node) - && address.equals(another.address) - && serviceName.equals(another.serviceName) - && serviceId.equals(another.serviceId) - && serviceAddress.equals(another.serviceAddress) - && servicePort == another.servicePort - && serviceTags.equals(another.serviceTags); - } - - /** - * Computes a hash code from attributes: {@code node}, {@code address}, {@code serviceName}, {@code serviceId}, {@code serviceAddress}, {@code servicePort}, {@code serviceTags}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + node.hashCode(); - h = h * 17 + address.hashCode(); - h = h * 17 + serviceName.hashCode(); - h = h * 17 + serviceId.hashCode(); - h = h * 17 + serviceAddress.hashCode(); - h = h * 17 + servicePort; - h = h * 17 + serviceTags.hashCode(); - return h; - } - - /** - * Prints the immutable value {@code CatalogService...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("CatalogService") - .add("node", node) - .add("address", address) - .add("serviceName", serviceName) - .add("serviceId", serviceId) - .add("serviceAddress", serviceAddress) - .add("servicePort", servicePort) - .add("serviceTags", serviceTags) - .toString(); - } - - /** - * Utility type used to correctly read immutable object from JSON representation. - * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonDeserialize - static final class Json extends CatalogService { - String node; - String address; - String serviceName; - String serviceId; - String serviceAddress; - Integer servicePort; - List serviceTags = ImmutableList.of(); - @JsonProperty(value = "Node") - public void setNode(String node) { - this.node = node; - } - @JsonProperty(value = "Address") - public void setAddress(String address) { - this.address = address; - } - @JsonProperty(value = "ServiceName") - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - @JsonProperty(value = "ServiceID") - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - @JsonProperty(value = "ServiceAddress") - public void setServiceAddress(String serviceAddress) { - this.serviceAddress = serviceAddress; - } - @JsonProperty(value = "ServicePort") - public void setServicePort(int servicePort) { - this.servicePort = servicePort; - } - @JsonProperty(value = "ServiceTags") - public void setServiceTags(List serviceTags) { - this.serviceTags = serviceTags; - } - @Override - public String getNode() { throw new UnsupportedOperationException(); } - @Override - public String getAddress() { throw new UnsupportedOperationException(); } - @Override - public String getServiceName() { throw new UnsupportedOperationException(); } - @Override - public String getServiceId() { throw new UnsupportedOperationException(); } - @Override - public String getServiceAddress() { throw new UnsupportedOperationException(); } - @Override - public int getServicePort() { throw new UnsupportedOperationException(); } - @Override - public List getServiceTags() { throw new UnsupportedOperationException(); } - } - - /** - * @param json A JSON-bindable data structure - * @return An immutable value type - * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonCreator - static ImmutableCatalogService fromJson(Json json) { - ImmutableCatalogService.Builder builder = ImmutableCatalogService.builder(); - if (json.node != null) { - builder.node(json.node); - } - if (json.address != null) { - builder.address(json.address); - } - if (json.serviceName != null) { - builder.serviceName(json.serviceName); - } - if (json.serviceId != null) { - builder.serviceId(json.serviceId); - } - if (json.serviceAddress != null) { - builder.serviceAddress(json.serviceAddress); - } - if (json.servicePort != null) { - builder.servicePort(json.servicePort); - } - if (json.serviceTags != null) { - builder.addAllServiceTags(json.serviceTags); - } - return builder.build(); - } - - /** - * Creates an immutable copy of a {@link CatalogService} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable CatalogService instance - */ - public static ImmutableCatalogService copyOf(CatalogService instance) { - if (instance instanceof ImmutableCatalogService) { - return (ImmutableCatalogService) instance; - } - return ImmutableCatalogService.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableCatalogService ImmutableCatalogService}. - * @return A new ImmutableCatalogService builder - */ - public static ImmutableCatalogService.Builder builder() { - return new ImmutableCatalogService.Builder(); - } - - /** - * Builds instances of type {@link ImmutableCatalogService ImmutableCatalogService}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private static final long INIT_BIT_NODE = 0x1L; - private static final long INIT_BIT_ADDRESS = 0x2L; - private static final long INIT_BIT_SERVICE_NAME = 0x4L; - private static final long INIT_BIT_SERVICE_ID = 0x8L; - private static final long INIT_BIT_SERVICE_ADDRESS = 0x10L; - private static final long INIT_BIT_SERVICE_PORT = 0x20L; - private long initBits = 0x3f; - - private String node; - private String address; - private String serviceName; - private String serviceId; - private String serviceAddress; - private int servicePort; - private ImmutableList.Builder serviceTagsBuilder = ImmutableList.builder(); - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code CatalogService} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * Collection elements and entries will be added, not replaced. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(CatalogService instance) { - Preconditions.checkNotNull(instance, "instance"); - node(instance.getNode()); - address(instance.getAddress()); - serviceName(instance.getServiceName()); - serviceId(instance.getServiceId()); - serviceAddress(instance.getServiceAddress()); - servicePort(instance.getServicePort()); - addAllServiceTags(instance.getServiceTags()); - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getNode() node} attribute. - * @param node The value for node - * @return {@code this} builder for use in a chained invocation - */ - public final Builder node(String node) { - this.node = Preconditions.checkNotNull(node, "node"); - initBits &= ~INIT_BIT_NODE; - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getAddress() address} attribute. - * @param address The value for address - * @return {@code this} builder for use in a chained invocation - */ - public final Builder address(String address) { - this.address = Preconditions.checkNotNull(address, "address"); - initBits &= ~INIT_BIT_ADDRESS; - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getServiceName() serviceName} attribute. - * @param serviceName The value for serviceName - * @return {@code this} builder for use in a chained invocation - */ - public final Builder serviceName(String serviceName) { - this.serviceName = Preconditions.checkNotNull(serviceName, "serviceName"); - initBits &= ~INIT_BIT_SERVICE_NAME; - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getServiceId() serviceId} attribute. - * @param serviceId The value for serviceId - * @return {@code this} builder for use in a chained invocation - */ - public final Builder serviceId(String serviceId) { - this.serviceId = Preconditions.checkNotNull(serviceId, "serviceId"); - initBits &= ~INIT_BIT_SERVICE_ID; - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute. - * @param serviceAddress The value for serviceAddress - * @return {@code this} builder for use in a chained invocation - */ - public final Builder serviceAddress(String serviceAddress) { - this.serviceAddress = Preconditions.checkNotNull(serviceAddress, "serviceAddress"); - initBits &= ~INIT_BIT_SERVICE_ADDRESS; - return this; - } - - /** - * Initializes the value for the {@link CatalogService#getServicePort() servicePort} attribute. - * @param servicePort The value for servicePort - * @return {@code this} builder for use in a chained invocation - */ - public final Builder servicePort(int servicePort) { - this.servicePort = servicePort; - initBits &= ~INIT_BIT_SERVICE_PORT; - return this; - } - - /** - * Adds one element to {@link CatalogService#getServiceTags() serviceTags} list. - * @param element A serviceTags element - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addServiceTags(String element) { - serviceTagsBuilder.add(element); - return this; - } - - /** - * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list. - * @param elements An array of serviceTags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addServiceTags(String... elements) { - serviceTagsBuilder.add(elements); - return this; - } - - /** - * Sets or replaces all elements for {@link CatalogService#getServiceTags() serviceTags} list. - * @param elements An iterable of serviceTags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder serviceTags(Iterable elements) { - serviceTagsBuilder = ImmutableList.builder(); - return addAllServiceTags(elements); - } - - /** - * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list. - * @param elements An iterable of serviceTags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addAllServiceTags(Iterable elements) { - serviceTagsBuilder.addAll(elements); - return this; - } - - /** - * Builds a new {@link ImmutableCatalogService ImmutableCatalogService}. - * @return An immutable instance of CatalogService - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableCatalogService build() throws IllegalStateException { - if (initBits != 0) { - throw new IllegalStateException(formatRequiredAttributesMessage()); - } - return new ImmutableCatalogService( - node, - address, - serviceName, - serviceId, - serviceAddress, - servicePort, - serviceTagsBuilder.build()); - } - - private String formatRequiredAttributesMessage() { - List attributes = Lists.newArrayList(); - if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); - if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); - if ((initBits & INIT_BIT_SERVICE_NAME) != 0) attributes.add("serviceName"); - if ((initBits & INIT_BIT_SERVICE_ID) != 0) attributes.add("serviceId"); - if ((initBits & INIT_BIT_SERVICE_ADDRESS) != 0) attributes.add("serviceAddress"); - if ((initBits & INIT_BIT_SERVICE_PORT) != 0) attributes.add("servicePort"); - return "Cannot build CatalogService, some of required attributes are not set " + attributes; - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java deleted file mode 100644 index dcf67a2..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.catalog; - -import com.google.common.base.Objects; - -public class ServiceInfo { - - private String serviceName; - - private String version=""; - - 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; - } - - @Override - public boolean equals(Object other) - { - if(this == other) - return true; - if(other instanceof ServiceInfo) - { - ServiceInfo that = (ServiceInfo)other; - return Objects.equal(serviceName, that.serviceName) && Objects.equal(version, that.version); - } else - { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hashCode(serviceName, version); - } - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java deleted file mode 100644 index ed0340e..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.health; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import java.util.List; -import javax.annotation.Generated; - -/** - * Immutable implementation of {@link Node}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableNode.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "Node"}) -@JsonIgnoreProperties(ignoreUnknown = true) -public final class ImmutableNode extends Node { - private final String node; - private final String address; - - private ImmutableNode(String node, String address) { - this.node = node; - this.address = address; - } - - /** - * @return The value of the {@code node} attribute - */ - @JsonProperty(value = "Node") - @Override - public String getNode() { - return node; - } - - /** - * @return The value of the {@code address} attribute - */ - @JsonProperty(value = "Address") - @Override - public String getAddress() { - return address; - } - - /** - * Copy the current immutable object by setting a value for the {@link Node#getNode() node} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for node - * @return A modified copy of the {@code this} object - */ - public final ImmutableNode withNode(String value) { - if (this.node.equals(value)) return this; - return new ImmutableNode(Preconditions.checkNotNull(value, "node"), this.address); - } - - /** - * Copy the current immutable object by setting a value for the {@link Node#getAddress() address} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for address - * @return A modified copy of the {@code this} object - */ - public final ImmutableNode withAddress(String value) { - if (this.address.equals(value)) return this; - return new ImmutableNode(this.node, Preconditions.checkNotNull(value, "address")); - } - - /** - * This instance is equal to all instances of {@code ImmutableNode} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableNode - && equalTo((ImmutableNode) another); - } - - private boolean equalTo(ImmutableNode another) { - return node.equals(another.node) - && address.equals(another.address); - } - - /** - * Computes a hash code from attributes: {@code node}, {@code address}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + node.hashCode(); - h = h * 17 + address.hashCode(); - return h; - } - - /** - * Prints the immutable value {@code Node...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("Node") - .add("node", node) - .add("address", address) - .toString(); - } - - /** - * Utility type used to correctly read immutable object from JSON representation. - * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonDeserialize - static final class Json extends Node { - String node; - String address; - @JsonProperty(value = "Node") - public void setNode(String node) { - this.node = node; - } - @JsonProperty(value = "Address") - public void setAddress(String address) { - this.address = address; - } - @Override - public String getNode() { throw new UnsupportedOperationException(); } - @Override - public String getAddress() { throw new UnsupportedOperationException(); } - } - - /** - * @param json A JSON-bindable data structure - * @return An immutable value type - * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonCreator - static ImmutableNode fromJson(Json json) { - ImmutableNode.Builder builder = ImmutableNode.builder(); - if (json.node != null) { - builder.node(json.node); - } - if (json.address != null) { - builder.address(json.address); - } - return builder.build(); - } - - /** - * Creates an immutable copy of a {@link Node} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable Node instance - */ - public static ImmutableNode copyOf(Node instance) { - if (instance instanceof ImmutableNode) { - return (ImmutableNode) instance; - } - return ImmutableNode.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableNode ImmutableNode}. - * @return A new ImmutableNode builder - */ - public static ImmutableNode.Builder builder() { - return new ImmutableNode.Builder(); - } - - /** - * Builds instances of type {@link ImmutableNode ImmutableNode}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private static final long INIT_BIT_NODE = 0x1L; - private static final long INIT_BIT_ADDRESS = 0x2L; - private long initBits = 0x3; - - private String node; - private String address; - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code Node} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(Node instance) { - Preconditions.checkNotNull(instance, "instance"); - node(instance.getNode()); - address(instance.getAddress()); - return this; - } - - /** - * Initializes the value for the {@link Node#getNode() node} attribute. - * @param node The value for node - * @return {@code this} builder for use in a chained invocation - */ - public final Builder node(String node) { - this.node = Preconditions.checkNotNull(node, "node"); - initBits &= ~INIT_BIT_NODE; - return this; - } - - /** - * Initializes the value for the {@link Node#getAddress() address} attribute. - * @param address The value for address - * @return {@code this} builder for use in a chained invocation - */ - public final Builder address(String address) { - this.address = Preconditions.checkNotNull(address, "address"); - initBits &= ~INIT_BIT_ADDRESS; - return this; - } - - /** - * Builds a new {@link ImmutableNode ImmutableNode}. - * @return An immutable instance of Node - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableNode build() throws IllegalStateException { - if (initBits != 0) { - throw new IllegalStateException(formatRequiredAttributesMessage()); - } - return new ImmutableNode(node, address); - } - - private String formatRequiredAttributesMessage() { - List attributes = Lists.newArrayList(); - if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node"); - if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); - return "Cannot build Node, some of required attributes are not set " + attributes; - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java deleted file mode 100644 index ec8f2d3..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java +++ /dev/null @@ -1,477 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.health; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import java.util.List; -import javax.annotation.Generated; - -/** - * Immutable implementation of {@link Service}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableService.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "Service"}) -@JsonIgnoreProperties(ignoreUnknown = true) -public final class ImmutableService extends Service { - private final String id; - private final String service; - private final ImmutableList tags; - private final String address; - private final int port; - - private ImmutableService( - String id, - String service, - ImmutableList tags, - String address, - int port) { - this.id = id; - this.service = service; - this.tags = tags; - this.address = address; - this.port = port; - } - - /** - * @return The value of the {@code id} attribute - */ - @JsonProperty(value = "ID") - @Override - public String getId() { - return id; - } - - /** - * @return The value of the {@code service} attribute - */ - @JsonProperty(value = "Service") - @Override - public String getService() { - return service; - } - - /** - * @return The value of the {@code tags} attribute - */ - @JsonProperty(value = "Tags") - @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) - @Override - public ImmutableList getTags() { - return tags; - } - - /** - * @return The value of the {@code address} attribute - */ - @JsonProperty(value = "Address") - @Override - public String getAddress() { - return address; - } - - /** - * @return The value of the {@code port} attribute - */ - @JsonProperty(value = "Port") - @Override - public int getPort() { - return port; - } - - /** - * Copy the current immutable object by setting a value for the {@link Service#getId() id} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for id - * @return A modified copy of the {@code this} object - */ - public final ImmutableService withId(String value) { - if (this.id.equals(value)) return this; - return new ImmutableService( - Preconditions.checkNotNull(value, "id"), - this.service, - this.tags, - this.address, - this.port); - } - - /** - * Copy the current immutable object by setting a value for the {@link Service#getService() service} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for service - * @return A modified copy of the {@code this} object - */ - public final ImmutableService withService(String value) { - if (this.service.equals(value)) return this; - return new ImmutableService( - this.id, - Preconditions.checkNotNull(value, "service"), - this.tags, - this.address, - this.port); - } - - /** - * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}. - * @param elements The elements to set - * @return A modified copy of {@code this} object - */ - public final ImmutableService withTags(String... elements) { - ImmutableList newValue = ImmutableList.copyOf(elements); - return new ImmutableService(this.id, this.service, newValue, this.address, this.port); - } - - /** - * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}. - * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. - * @param elements An iterable of tags elements to set - * @return A modified copy of {@code this} object - */ - public final ImmutableService withTags(Iterable elements) { - if (this.tags == elements) return this; - ImmutableList newValue = ImmutableList.copyOf(elements); - return new ImmutableService(this.id, this.service, newValue, this.address, this.port); - } - - /** - * Copy the current immutable object by setting a value for the {@link Service#getAddress() address} attribute. - * An equals check used to prevent copying of the same value by returning {@code this}. - * @param value A new value for address - * @return A modified copy of the {@code this} object - */ - public final ImmutableService withAddress(String value) { - if (this.address.equals(value)) return this; - return new ImmutableService( - this.id, - this.service, - this.tags, - Preconditions.checkNotNull(value, "address"), - this.port); - } - - /** - * Copy the current immutable object by setting a value for the {@link Service#getPort() port} attribute. - * A value equality check is used to prevent copying of the same value by returning {@code this}. - * @param value A new value for port - * @return A modified copy of the {@code this} object - */ - public final ImmutableService withPort(int value) { - if (this.port == value) return this; - return new ImmutableService(this.id, this.service, this.tags, this.address, value); - } - - /** - * This instance is equal to all instances of {@code ImmutableService} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableService - && equalTo((ImmutableService) another); - } - - private boolean equalTo(ImmutableService another) { - return id.equals(another.id) - && service.equals(another.service) - && tags.equals(another.tags) - && address.equals(another.address) - && port == another.port; - } - - /** - * Computes a hash code from attributes: {@code id}, {@code service}, {@code tags}, {@code address}, {@code port}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + id.hashCode(); - h = h * 17 + service.hashCode(); - h = h * 17 + tags.hashCode(); - h = h * 17 + address.hashCode(); - h = h * 17 + port; - return h; - } - - /** - * Prints the immutable value {@code Service...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("Service") - .add("id", id) - .add("service", service) - .add("tags", tags) - .add("address", address) - .add("port", port) - .toString(); - } - - /** - * Utility type used to correctly read immutable object from JSON representation. - * @deprecated Do not use this type directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonDeserialize - static final class Json extends Service { - String id; - String service; - List tags = ImmutableList.of(); - String address; - Integer port; - @JsonProperty(value = "ID") - public void setId(String id) { - this.id = id; - } - @JsonProperty(value = "Service") - public void setService(String service) { - this.service = service; - } - @JsonProperty(value = "Tags") - @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) - public void setTags(List tags) { - this.tags = tags; - } - @JsonProperty(value = "Address") - public void setAddress(String address) { - this.address = address; - } - @JsonProperty(value = "Port") - public void setPort(int port) { - this.port = port; - } - @Override - public String getId() { throw new UnsupportedOperationException(); } - @Override - public String getService() { throw new UnsupportedOperationException(); } - @Override - public List getTags() { throw new UnsupportedOperationException(); } - @Override - public String getAddress() { throw new UnsupportedOperationException(); } - @Override - public int getPort() { throw new UnsupportedOperationException(); } - } - - /** - * @param json A JSON-bindable data structure - * @return An immutable value type - * @deprecated Do not use this method directly, it exists only for the Jackson-binding infrastructure - */ - @Deprecated - @JsonCreator - static ImmutableService fromJson(Json json) { - ImmutableService.Builder builder = ImmutableService.builder(); - if (json.id != null) { - builder.id(json.id); - } - if (json.service != null) { - builder.service(json.service); - } - if (json.tags != null) { - builder.addAllTags(json.tags); - } - if (json.address != null) { - builder.address(json.address); - } - if (json.port != null) { - builder.port(json.port); - } - return builder.build(); - } - - /** - * Creates an immutable copy of a {@link Service} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable Service instance - */ - public static ImmutableService copyOf(Service instance) { - if (instance instanceof ImmutableService) { - return (ImmutableService) instance; - } - return ImmutableService.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableService ImmutableService}. - * @return A new ImmutableService builder - */ - public static ImmutableService.Builder builder() { - return new ImmutableService.Builder(); - } - - /** - * Builds instances of type {@link ImmutableService ImmutableService}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private static final long INIT_BIT_ID = 0x1L; - private static final long INIT_BIT_SERVICE = 0x2L; - private static final long INIT_BIT_ADDRESS = 0x4L; - private static final long INIT_BIT_PORT = 0x8L; - private long initBits = 0xf; - - private String id; - private String service; - private ImmutableList.Builder tagsBuilder = ImmutableList.builder(); - private String address; - private int port; - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code Service} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * Collection elements and entries will be added, not replaced. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(Service instance) { - Preconditions.checkNotNull(instance, "instance"); - id(instance.getId()); - service(instance.getService()); - addAllTags(instance.getTags()); - address(instance.getAddress()); - port(instance.getPort()); - return this; - } - - /** - * Initializes the value for the {@link Service#getId() id} attribute. - * @param id The value for id - * @return {@code this} builder for use in a chained invocation - */ - public final Builder id(String id) { - this.id = Preconditions.checkNotNull(id, "id"); - initBits &= ~INIT_BIT_ID; - return this; - } - - /** - * Initializes the value for the {@link Service#getService() service} attribute. - * @param service The value for service - * @return {@code this} builder for use in a chained invocation - */ - public final Builder service(String service) { - this.service = Preconditions.checkNotNull(service, "service"); - initBits &= ~INIT_BIT_SERVICE; - return this; - } - - /** - * Adds one element to {@link Service#getTags() tags} list. - * @param element A tags element - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addTags(String element) { - tagsBuilder.add(element); - return this; - } - - /** - * Adds elements to {@link Service#getTags() tags} list. - * @param elements An array of tags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addTags(String... elements) { - tagsBuilder.add(elements); - return this; - } - - /** - * Sets or replaces all elements for {@link Service#getTags() tags} list. - * @param elements An iterable of tags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder tags(Iterable elements) { - tagsBuilder = ImmutableList.builder(); - return addAllTags(elements); - } - - /** - * Adds elements to {@link Service#getTags() tags} list. - * @param elements An iterable of tags elements - * @return {@code this} builder for use in a chained invocation - */ - public final Builder addAllTags(Iterable elements) { - tagsBuilder.addAll(elements); - return this; - } - - /** - * Initializes the value for the {@link Service#getAddress() address} attribute. - * @param address The value for address - * @return {@code this} builder for use in a chained invocation - */ - public final Builder address(String address) { - this.address = Preconditions.checkNotNull(address, "address"); - initBits &= ~INIT_BIT_ADDRESS; - return this; - } - - /** - * Initializes the value for the {@link Service#getPort() port} attribute. - * @param port The value for port - * @return {@code this} builder for use in a chained invocation - */ - public final Builder port(int port) { - this.port = port; - initBits &= ~INIT_BIT_PORT; - return this; - } - - /** - * Builds a new {@link ImmutableService ImmutableService}. - * @return An immutable instance of Service - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableService build() throws IllegalStateException { - if (initBits != 0) { - throw new IllegalStateException(formatRequiredAttributesMessage()); - } - return new ImmutableService(id, service, tagsBuilder.build(), address, port); - } - - private String formatRequiredAttributesMessage() { - List attributes = Lists.newArrayList(); - if ((initBits & INIT_BIT_ID) != 0) attributes.add("id"); - if ((initBits & INIT_BIT_SERVICE) != 0) attributes.add("service"); - if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address"); - if ((initBits & INIT_BIT_PORT) != 0) attributes.add("port"); - return "Cannot build Service, some of required attributes are not set " + attributes; - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java deleted file mode 100644 index 9f603c5..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.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; - - -@JsonSerialize(as = ImmutableNode.class) -@JsonDeserialize(as = ImmutableNode.class) -@JsonIgnoreProperties(ignoreUnknown = true) -public abstract class Node { - - @JsonProperty("Node") - public abstract String getNode(); - - @JsonProperty("Address") - public abstract String getAddress(); -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java deleted file mode 100644 index 6ac3d4b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.health; - -import java.util.List; - -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; - - -@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 getTags(); - - @JsonProperty("Address") - public abstract String getAddress(); - - @JsonProperty("Port") - public abstract int getPort(); -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java deleted file mode 100644 index 4693256..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.model.health; - -import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.Objects; - - -@JsonIgnoreProperties(ignoreUnknown = true) -public class ServiceHealth { - - @JsonProperty("Node") - public Node node; - - @JsonProperty("Service") - public Service service; - - public Node getNode() { - return node; - } - - public void setNode(Node node) { - this.node = node; - } - - public Service getService() { - return service; - } - - public void setService(Service service) { - this.service = service; - } - - @Override - public boolean equals(Object other) - { - if(this == other) - return true; - if(other instanceof ServiceHealth) - { - ServiceHealth that = (ServiceHealth)other; - return Objects.equal(node, that.node) && Objects.equal(service, that.service); - } else - { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hashCode(node, service); - } - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java deleted file mode 100644 index daba73c..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; - -import javax.ws.rs.client.WebTarget; - -import com.google.common.base.Optional; - - -public abstract class CatalogOptions implements ParamAdder { - - public abstract Optional getDatacenter(); - public abstract Optional getTag(); - - public static final CatalogOptions BLANK = ImmutableCatalogOptions.builder().build(); - - @Override - public final WebTarget apply(final WebTarget input) { - WebTarget added = optionallyAdd(input, "dc", getDatacenter()); - added = optionallyAdd(added, "tag", getTag()); - return added; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java deleted file mode 100644 index ea47c65..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -public enum ConsistencyMode { - DEFAULT, STALE, CONSISTENT -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java deleted file mode 100644 index 89048d5..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java +++ /dev/null @@ -1,250 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import javax.annotation.Generated; - -/** - * Immutable implementation of {@link CatalogOptions}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableCatalogOptions.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "CatalogOptions"}) -public final class ImmutableCatalogOptions extends CatalogOptions { - private final Optional datacenter; - private final Optional tag; - - private ImmutableCatalogOptions( - Optional datacenter, - Optional tag) { - this.datacenter = datacenter; - this.tag = tag; - } - - /** - * @return The value of the {@code datacenter} attribute - */ - @Override - public Optional getDatacenter() { - return datacenter; - } - - /** - * @return The value of the {@code tag} attribute - */ - @Override - public Optional getTag() { - return tag; - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link CatalogOptions#getDatacenter() datacenter} attribute. - * @param value The value for datacenter - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogOptions withDatacenter(String value) { - Optional newValue = Optional.of(value); - return new ImmutableCatalogOptions(newValue, this.tag); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getDatacenter() datacenter} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for datacenter - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogOptions withDatacenter(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "datacenter"); - if (this.datacenter == value) return this; - return new ImmutableCatalogOptions(value, this.tag); - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link CatalogOptions#getTag() tag} attribute. - * @param value The value for tag - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogOptions withTag(String value) { - Optional newValue = Optional.of(value); - return new ImmutableCatalogOptions(this.datacenter, newValue); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getTag() tag} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for tag - * @return A modified copy of {@code this} object - */ - public final ImmutableCatalogOptions withTag(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "tag"); - if (this.tag == value) return this; - return new ImmutableCatalogOptions(this.datacenter, value); - } - - /** - * This instance is equal to all instances of {@code ImmutableCatalogOptions} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableCatalogOptions - && equalTo((ImmutableCatalogOptions) another); - } - - private boolean equalTo(ImmutableCatalogOptions another) { - return datacenter.equals(another.datacenter) - && tag.equals(another.tag); - } - - /** - * Computes a hash code from attributes: {@code datacenter}, {@code tag}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + datacenter.hashCode(); - h = h * 17 + tag.hashCode(); - return h; - } - - /** - * Prints the immutable value {@code CatalogOptions...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("CatalogOptions") - .add("datacenter", datacenter) - .add("tag", tag) - .toString(); - } - - /** - * Creates an immutable copy of a {@link CatalogOptions} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable CatalogOptions instance - */ - public static ImmutableCatalogOptions copyOf(CatalogOptions instance) { - if (instance instanceof ImmutableCatalogOptions) { - return (ImmutableCatalogOptions) instance; - } - return ImmutableCatalogOptions.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableCatalogOptions ImmutableCatalogOptions}. - * @return A new ImmutableCatalogOptions builder - */ - public static ImmutableCatalogOptions.Builder builder() { - return new ImmutableCatalogOptions.Builder(); - } - - /** - * Builds instances of type {@link ImmutableCatalogOptions ImmutableCatalogOptions}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private Optional datacenter = Optional.absent(); - private Optional tag = Optional.absent(); - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code CatalogOptions} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(CatalogOptions instance) { - Preconditions.checkNotNull(instance, "instance"); - Optional datacenterOptional = instance.getDatacenter(); - if (datacenterOptional.isPresent()) { - datacenter(datacenterOptional); - } - Optional tagOptional = instance.getTag(); - if (tagOptional.isPresent()) { - tag(tagOptional); - } - return this; - } - - /** - * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter. - * @param datacenter The value for datacenter - * @return {@code this} builder for chained invocation - */ - public final Builder datacenter(String datacenter) { - this.datacenter = Optional.of(datacenter); - return this; - } - - /** - * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter. - * @param datacenter The value for datacenter - * @return {@code this} builder for use in a chained invocation - */ - public final Builder datacenter(Optional datacenter) { - this.datacenter = Preconditions.checkNotNull(datacenter, "datacenter"); - return this; - } - - /** - * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag. - * @param tag The value for tag - * @return {@code this} builder for chained invocation - */ - public final Builder tag(String tag) { - this.tag = Optional.of(tag); - return this; - } - - /** - * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag. - * @param tag The value for tag - * @return {@code this} builder for use in a chained invocation - */ - public final Builder tag(Optional tag) { - this.tag = Preconditions.checkNotNull(tag, "tag"); - return this; - } - - /** - * Builds a new {@link ImmutableCatalogOptions ImmutableCatalogOptions}. - * @return An immutable instance of CatalogOptions - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableCatalogOptions build() throws IllegalStateException { - return new ImmutableCatalogOptions(datacenter, tag); - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java deleted file mode 100644 index c39b578..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java +++ /dev/null @@ -1,530 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.primitives.Booleans; -import java.math.BigInteger; -import java.util.ArrayList; -import javax.annotation.Generated; - -/** - * Immutable implementation of {@link QueryOptions}. - *

    - * Use the builder to create immutable instances: - * {@code ImmutableQueryOptions.builder()}. - */ -@SuppressWarnings("all") -@Generated({"Immutables.generator", "QueryOptions"}) -public final class ImmutableQueryOptions extends QueryOptions { - private final Optional wait; - private final Optional token; - private final Optional index; - private final Optional near; - private final ConsistencyMode consistencyMode; - private final boolean isBlocking; - private final boolean hasToken; - - private ImmutableQueryOptions(ImmutableQueryOptions.Builder builder) { - this.wait = builder.wait; - this.token = builder.token; - this.index = builder.index; - this.near = builder.near; - if (builder.consistencyMode != null) { - initShim.consistencyMode(builder.consistencyMode); - } - this.consistencyMode = initShim.getConsistencyMode(); - this.isBlocking = initShim.isBlocking(); - this.hasToken = initShim.hasToken(); - this.initShim = null; - } - - private ImmutableQueryOptions( - Optional wait, - Optional token, - Optional index, - Optional near, - ConsistencyMode consistencyMode) { - this.wait = wait; - this.token = token; - this.index = index; - this.near = near; - this.consistencyMode = consistencyMode; - initShim.consistencyMode(consistencyMode); - this.isBlocking = initShim.isBlocking(); - this.hasToken = initShim.hasToken(); - this.initShim = null; - } - - private static final int STAGE_INITIALIZING = -1; - private static final int STAGE_UNINITIALIZED = 0; - private static final int STAGE_INITIALIZED = 1; - private volatile InitShim initShim = new InitShim(); - - private final class InitShim { - private ConsistencyMode consistencyMode; - private byte consistencyModeStage; - - ConsistencyMode getConsistencyMode() { - if (consistencyModeStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); - if (consistencyModeStage == STAGE_UNINITIALIZED) { - consistencyModeStage = STAGE_INITIALIZING; - this.consistencyMode = Preconditions.checkNotNull(ImmutableQueryOptions.super.getConsistencyMode(), "consistencyMode"); - consistencyModeStage = STAGE_INITIALIZED; - } - return consistencyMode; - } - - ConsistencyMode consistencyMode(ConsistencyMode value) { - this.consistencyMode = value; - consistencyModeStage = STAGE_INITIALIZED; - return value; - } - private boolean isBlocking; - private byte isBlockingStage; - - boolean isBlocking() { - if (isBlockingStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); - if (isBlockingStage == STAGE_UNINITIALIZED) { - isBlockingStage = STAGE_INITIALIZING; - this.isBlocking = ImmutableQueryOptions.super.isBlocking(); - isBlockingStage = STAGE_INITIALIZED; - } - return isBlocking; - } - private boolean hasToken; - private byte hasTokenStage; - - boolean hasToken() { - if (hasTokenStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); - if (hasTokenStage == STAGE_UNINITIALIZED) { - hasTokenStage = STAGE_INITIALIZING; - this.hasToken = ImmutableQueryOptions.super.hasToken(); - hasTokenStage = STAGE_INITIALIZED; - } - return hasToken; - } - - private String formatInitCycleMessage() { - ArrayList attributes = Lists.newArrayList(); - if (consistencyModeStage == STAGE_INITIALIZING) attributes.add("consistencyMode"); - if (isBlockingStage == STAGE_INITIALIZING) attributes.add("isBlocking"); - if (hasTokenStage == STAGE_INITIALIZING) attributes.add("hasToken"); - return "Cannot build QueryOptions, attribute initializers form cycle" + attributes; - } - } - - /** - * @return The value of the {@code wait} attribute - */ - @Override - public Optional getWait() { - return wait; - } - - /** - * @return The value of the {@code token} attribute - */ - @Override - public Optional getToken() { - return token; - } - - /** - * @return The value of the {@code index} attribute - */ - @Override - public Optional getIndex() { - return index; - } - - /** - * @return The value of the {@code near} attribute - */ - @Override - public Optional getNear() { - return near; - } - - /** - * @return The value of the {@code consistencyMode} attribute - */ - @Override - public ConsistencyMode getConsistencyMode() { - return initShim != null - ? initShim.getConsistencyMode() - : consistencyMode; - } - - /** - * @return The computed-at-construction value of the {@code isBlocking} attribute - */ - @Override - public boolean isBlocking() { - return initShim != null - ? initShim.isBlocking() - : isBlocking; - } - - /** - * @return The computed-at-construction value of the {@code hasToken} attribute - */ - @Override - public boolean hasToken() { - return initShim != null - ? initShim.hasToken() - : hasToken; - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getWait() wait} attribute. - * @param value The value for wait - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withWait(String value) { - Optional newValue = Optional.of(value); - return validate(new ImmutableQueryOptions(newValue, this.token, this.index, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getWait() wait} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for wait - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withWait(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "wait"); - if (this.wait == value) return this; - return validate(new ImmutableQueryOptions(value, this.token, this.index, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getToken() token} attribute. - * @param value The value for token - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withToken(String value) { - Optional newValue = Optional.of(value); - return validate(new ImmutableQueryOptions(this.wait, newValue, this.index, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getToken() token} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for token - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withToken(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "token"); - if (this.token == value) return this; - return validate(new ImmutableQueryOptions(this.wait, value, this.index, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getIndex() index} attribute. - * @param value The value for index - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withIndex(BigInteger value) { - Optional newValue = Optional.of(value); - return validate(new ImmutableQueryOptions(this.wait, this.token, newValue, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getIndex() index} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for index - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withIndex(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "index"); - if (this.index == value) return this; - return validate(new ImmutableQueryOptions(this.wait, this.token, value, this.near, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting a present value for the optional {@link QueryOptions#getNear() near} attribute. - * @param value The value for near - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withNear(String value) { - Optional newValue = Optional.of(value); - return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, newValue, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getNear() near} attribute. - * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}. - * @param optional A value for near - * @return A modified copy of {@code this} object - */ - public final ImmutableQueryOptions withNear(Optional optional) { - Optional value = Preconditions.checkNotNull(optional, "near"); - if (this.near == value) return this; - return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, value, this.consistencyMode)); - } - - /** - * Copy the current immutable object by setting a value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute. - * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. - * @param value A new value for consistencyMode - * @return A modified copy of the {@code this} object - */ - public final ImmutableQueryOptions withConsistencyMode(ConsistencyMode value) { - if (this.consistencyMode == value) return this; - return validate(new ImmutableQueryOptions( - this.wait, - this.token, - this.index, - this.near, - Preconditions.checkNotNull(value, "consistencyMode"))); - } - - /** - * This instance is equal to all instances of {@code ImmutableQueryOptions} that have equal attribute values. - * @return {@code true} if {@code this} is equal to {@code another} instance - */ - @Override - public boolean equals(Object another) { - if (this == another) return true; - return another instanceof ImmutableQueryOptions - && equalTo((ImmutableQueryOptions) another); - } - - private boolean equalTo(ImmutableQueryOptions another) { - return wait.equals(another.wait) - && token.equals(another.token) - && index.equals(another.index) - && near.equals(another.near) - && consistencyMode.equals(another.consistencyMode) - && isBlocking == another.isBlocking - && hasToken == another.hasToken; - } - - /** - * Computes a hash code from attributes: {@code wait}, {@code token}, {@code index}, {@code near}, {@code consistencyMode}, {@code isBlocking}, {@code hasToken}. - * @return hashCode value - */ - @Override - public int hashCode() { - int h = 31; - h = h * 17 + wait.hashCode(); - h = h * 17 + token.hashCode(); - h = h * 17 + index.hashCode(); - h = h * 17 + near.hashCode(); - h = h * 17 + consistencyMode.hashCode(); - h = h * 17 + Booleans.hashCode(isBlocking); - h = h * 17 + Booleans.hashCode(hasToken); - return h; - } - - /** - * Prints the immutable value {@code QueryOptions...} with all non-generated - * and non-auxiliary attribute values. - * @return A string representation of the value - */ - @Override - public String toString() { - return MoreObjects.toStringHelper("QueryOptions") - .add("wait", wait) - .add("token", token) - .add("index", index) - .add("near", near) - .add("consistencyMode", consistencyMode) - .add("isBlocking", isBlocking) - .add("hasToken", hasToken) - .toString(); - } - - private static ImmutableQueryOptions validate(ImmutableQueryOptions instance) { - instance.validate(); - return instance; - } - - /** - * Creates an immutable copy of a {@link QueryOptions} value. - * Uses accessors to get values to initialize the new immutable instance. - * If an instance is already immutable, it is returned as is. - * @param instance The instance to copy - * @return A copied immutable QueryOptions instance - */ - public static ImmutableQueryOptions copyOf(QueryOptions instance) { - if (instance instanceof ImmutableQueryOptions) { - return (ImmutableQueryOptions) instance; - } - return ImmutableQueryOptions.builder() - .from(instance) - .build(); - } - - /** - * Creates a builder for {@link ImmutableQueryOptions ImmutableQueryOptions}. - * @return A new ImmutableQueryOptions builder - */ - public static ImmutableQueryOptions.Builder builder() { - return new ImmutableQueryOptions.Builder(); - } - - /** - * Builds instances of type {@link ImmutableQueryOptions ImmutableQueryOptions}. - * Initialize attributes and then invoke the {@link #build()} method to create an - * immutable instance. - *

    {@code Builder} is not thread-safe and generally should not be stored in a field or collection, - * but instead used immediately to create instances. - */ - public static final class Builder { - private Optional wait = Optional.absent(); - private Optional token = Optional.absent(); - private Optional index = Optional.absent(); - private Optional near = Optional.absent(); - private ConsistencyMode consistencyMode; - - private Builder() { - } - - /** - * Fill a builder with attribute values from the provided {@code QueryOptions} instance. - * Regular attribute values will be replaced with those from the given instance. - * Absent optional values will not replace present values. - * @param instance The instance from which to copy values - * @return {@code this} builder for use in a chained invocation - */ - public final Builder from(QueryOptions instance) { - Preconditions.checkNotNull(instance, "instance"); - Optional waitOptional = instance.getWait(); - if (waitOptional.isPresent()) { - wait(waitOptional); - } - Optional tokenOptional = instance.getToken(); - if (tokenOptional.isPresent()) { - token(tokenOptional); - } - Optional indexOptional = instance.getIndex(); - if (indexOptional.isPresent()) { - index(indexOptional); - } - Optional nearOptional = instance.getNear(); - if (nearOptional.isPresent()) { - near(nearOptional); - } - consistencyMode(instance.getConsistencyMode()); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getWait() wait} to wait. - * @param wait The value for wait - * @return {@code this} builder for chained invocation - */ - public final Builder wait(String wait) { - this.wait = Optional.of(wait); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getWait() wait} to wait. - * @param wait The value for wait - * @return {@code this} builder for use in a chained invocation - */ - public final Builder wait(Optional wait) { - this.wait = Preconditions.checkNotNull(wait, "wait"); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getToken() token} to token. - * @param token The value for token - * @return {@code this} builder for chained invocation - */ - public final Builder token(String token) { - this.token = Optional.of(token); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getToken() token} to token. - * @param token The value for token - * @return {@code this} builder for use in a chained invocation - */ - public final Builder token(Optional token) { - this.token = Preconditions.checkNotNull(token, "token"); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getIndex() index} to index. - * @param index The value for index - * @return {@code this} builder for chained invocation - */ - public final Builder index(BigInteger index) { - this.index = Optional.of(index); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getIndex() index} to index. - * @param index The value for index - * @return {@code this} builder for use in a chained invocation - */ - public final Builder index(Optional index) { - this.index = Preconditions.checkNotNull(index, "index"); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getNear() near} to near. - * @param near The value for near - * @return {@code this} builder for chained invocation - */ - public final Builder near(String near) { - this.near = Optional.of(near); - return this; - } - - /** - * Initializes the optional value {@link QueryOptions#getNear() near} to near. - * @param near The value for near - * @return {@code this} builder for use in a chained invocation - */ - public final Builder near(Optional near) { - this.near = Preconditions.checkNotNull(near, "near"); - return this; - } - - /** - * Initializes the value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute. - *

    If not set, this attribute will have a default value as returned by the initializer of {@link QueryOptions#getConsistencyMode() consistencyMode}. - * @param consistencyMode The value for consistencyMode - * @return {@code this} builder for use in a chained invocation - */ - public final Builder consistencyMode(ConsistencyMode consistencyMode) { - this.consistencyMode = Preconditions.checkNotNull(consistencyMode, "consistencyMode"); - return this; - } - - /** - * Builds a new {@link ImmutableQueryOptions ImmutableQueryOptions}. - * @return An immutable instance of QueryOptions - * @throws java.lang.IllegalStateException if any required attributes are missing - */ - public ImmutableQueryOptions build() throws IllegalStateException { - return ImmutableQueryOptions.validate(new ImmutableQueryOptions(this)); - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java deleted file mode 100644 index 1f04c09..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import com.google.common.base.Optional; - -import javax.ws.rs.client.WebTarget; - -public class Options { - private Options(){}; - - static WebTarget optionallyAdd(WebTarget input, String key, Optional val) { - return val.isPresent() ? input.queryParam(key, val.get()) : input; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java deleted file mode 100644 index dc9a9fa..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import com.google.common.base.Function; - -import javax.ws.rs.client.WebTarget; - -public interface ParamAdder extends Function {} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java deleted file mode 100644 index 688728e..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.option; - -import static com.google.common.base.Preconditions.checkArgument; -import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; - -import java.math.BigInteger; - -import javax.ws.rs.client.WebTarget; - -import com.google.common.base.Optional; - -/** - * Container for common query options used by the Consul API. - */ - -public abstract class QueryOptions implements ParamAdder { - - public static final QueryOptions BLANK = ImmutableQueryOptions.builder().build(); - - public abstract Optional getWait(); - public abstract Optional getToken(); - public abstract Optional getIndex(); - public abstract Optional getNear(); - - - public ConsistencyMode getConsistencyMode() { - return ConsistencyMode.DEFAULT; - } - - - public boolean isBlocking() { - return getWait().isPresent(); - } - - - public boolean hasToken() { - return getToken().isPresent(); - } - - - void validate() { - if (isBlocking()) { - checkArgument(getIndex().isPresent(), "If wait is specified, index must also be specified"); - } - } - - public static ImmutableQueryOptions.Builder blockSeconds(int seconds, BigInteger index) { - return blockBuilder("s", seconds, index); - } - - public static ImmutableQueryOptions.Builder blockMinutes(int minutes, BigInteger index) { - return blockBuilder("m", minutes, index); - } - - private static ImmutableQueryOptions.Builder blockBuilder(String identifier, int qty, BigInteger index) { - return ImmutableQueryOptions.builder() - .wait(String.format("%s%s", qty, identifier)) - .index(index); - } - - @Override - public WebTarget apply(WebTarget input) { - - WebTarget added = input; - switch (getConsistencyMode()) { - case CONSISTENT: - added = added.queryParam("consistent", ""); - break; - case STALE: - added = added.queryParam("stale", ""); - break; - } - - if (isBlocking()) { - added = added.queryParam("wait", getWait().get()) - .queryParam("index", String.valueOf(getIndex().get())); - } - - added = optionallyAdd(added, "token", getToken()); - added = optionallyAdd(added, "near", getToken()); - - return added; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java deleted file mode 100644 index 4770b6d..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.google.common.base.Optional; -import com.google.common.io.BaseEncoding; -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; - -/** - * For use with JSON fields that Consul Base 64 encodes. - */ -public class Base64EncodingDeserializer extends JsonDeserializer> { - - /** - * {@inheritDoc} - */ - @Override - public Optional deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - String value = p.getValueAsString(); - - if (StringUtils.isNotEmpty(value)) { - return Optional.of(new String(BaseEncoding.base64().decode(value))); - } - return Optional.absent(); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java deleted file mode 100644 index c45f0dd..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java +++ /dev/null @@ -1,261 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import javax.ws.rs.ServerErrorException; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.InvocationCallback; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.openo.msb.wrapper.consul.ConsulException; -import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; -import org.openo.msb.wrapper.consul.model.ConsulResponse; -import org.openo.msb.wrapper.consul.option.CatalogOptions; -import org.openo.msb.wrapper.consul.option.ParamAdder; -import org.openo.msb.wrapper.consul.option.QueryOptions; - -import java.math.BigInteger; -import java.util.List; -import java.util.Map; - -/** - * A collection of stateless utility methods for use in constructing - * requests and responses to the Consul HTTP API. - */ -public class ClientUtil { - - /** - * Applies all key/values from the params map to query string parameters. - * - * @param webTarget The JAX-RS target to apply the query parameters. - * @param params Map of parameters. - * @return The new target with the parameters applied. - */ - public static WebTarget queryParams(WebTarget webTarget, Map params) { - WebTarget target = webTarget; - - if(params != null) { - for(Map.Entry entry : params.entrySet()) { - target = target.queryParam(entry.getKey(), entry.getValue()); - } - } - - return target; - } - - /** - * Given a {@link org.openo.msb.wrapper.consul.option.ParamAdder} object, adds the - * appropriate query string parameters to the request being built. - * - * @param webTarget The base {@link javax.ws.rs.client.WebTarget}. - * @param paramAdder will add specific params to the target. - * @return A {@link javax.ws.rs.client.WebTarget} with all appropriate query - * string parameters. - */ - public static WebTarget addParams(WebTarget webTarget, ParamAdder paramAdder) { - return paramAdder == null ? webTarget : paramAdder.apply(webTarget); - } - - /** - * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, - * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. - * - * @param target The base {@link javax.ws.rs.client.WebTarget}. - * @param catalogOptions Catalog specific options to use. - * @param queryOptions The Query Options to use. - * @param type The generic type to marshall the resulting data to. - * @param The result type. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. - */ - public static ConsulResponse response(WebTarget target, CatalogOptions catalogOptions, - QueryOptions queryOptions, - GenericType type) { - target = addParams(target, catalogOptions); - target = addParams(target, queryOptions); - - return response(target, type); - } - - /** - * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, - * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. - * - * @param target The base {@link javax.ws.rs.client.WebTarget}. - * @param catalogOptions Catalog specific options to use. - * @param queryOptions The Query Options to use. - * @param type The generic type to marshall the resulting data to. - * @param The result type. - */ - public static void response(WebTarget target, CatalogOptions catalogOptions, - QueryOptions queryOptions, - GenericType type, - ConsulResponseCallback callback) { - - target = addParams(target, catalogOptions); - target = addParams(target, queryOptions); - - response(target, type, callback); - } - - /** - * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall - * the result JSON into, complete the HTTP GET request. - * - * @param webTarget The JAX-RS target. - * @param responseType The class to marshall the JSON into. - * @param The class to marshall the JSON into. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing the result. - */ - public static ConsulResponse response(WebTarget webTarget, GenericType responseType) { - Response response = webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).get(); - - return consulResponse(responseType, response); - } - - /** - * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall - * the result JSON into, complete the HTTP GET request. - * - * @param webTarget The JAX-RS target. - * @param responseType The class to marshall the JSON into. - * @param callback The callback object to handle the result on a different thread. - * @param The class to marshall the JSON into. - */ - public static void response(WebTarget webTarget, final GenericType responseType, - final ConsulResponseCallback callback) { - webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).async().get(new InvocationCallback() { - - @Override - public void completed(Response response) { - try { - callback.onComplete(consulResponse(responseType, response)); - } catch (Exception ex) { - callback.onFailure(ex); - } - } - - @Override - public void failed(Throwable throwable) { - callback.onFailure(throwable); - } - }); - } - - /** - * Extracts Consul specific headers and adds them to a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} - * object, which also contains the returned JSON entity. - * - * @param responseType The class to marshall the JSON to. - * @param response The HTTP response. - * @param The class to marshall the JSON to. - * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} object. - */ - private static ConsulResponse consulResponse(GenericType responseType, Response response) { - handleErrors(response); - - String indexHeaderValue = response.getHeaderString("X-Consul-Index"); - String lastContactHeaderValue = response.getHeaderString("X-Consul-Lastcontact"); - String knownLeaderHeaderValue = response.getHeaderString("X-Consul-Knownleader"); - - BigInteger index = new BigInteger(indexHeaderValue); - long lastContact = lastContactHeaderValue == null ? -1 : Long.valueOf(lastContactHeaderValue); - boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean.valueOf(knownLeaderHeaderValue); - - ConsulResponse consulResponse = new ConsulResponse(readResponse(response, responseType), lastContact, knownLeader, index); - - response.close(); - - return consulResponse; - } - - /** - * Converts a {@link Response} object to the generic type provided, or an empty - * representation if appropriate - * - * @param response response - * @param responseType response type - * @param - * @return the re - */ - private static T readResponse(Response response, GenericType responseType) { - if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { - // would be nice I knew a better way to do this - if (responseType.getRawType() == List.class) { - return (T) ImmutableList.of(); - } else if (responseType.getRawType() == Optional.class) { - return (T) Optional.absent(); - } else if(responseType.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 " + responseType.getRawType()); - } - } - return response.readEntity(responseType); - } - - /** - * Since Consul returns plain text when an error occurs, check for - * unsuccessful HTTP status code, and throw an exception with the text - * from Consul as the message. - * - * @param response The HTTP response. - */ - public static void handleErrors(Response response) { - - if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL - || response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { - // not an error - return; - } - - try { - final String message = response.hasEntity() ? response.readEntity(String.class) : null; - if (response.getStatusInfo().getFamily() == Response.Status.Family.SERVER_ERROR) { - throw new ServerErrorException(message, response); - } else { - throw new WebApplicationException(message, response); - } - } catch (Exception e) { - throw new ConsulException(e.getLocalizedMessage(), e); - } finally { - response.close(); - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java deleted file mode 100644 index f49ba12..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.guava.GuavaModule; - -public class Jackson { - - public static final ObjectMapper MAPPER = newObjectMapper(); - - private static ObjectMapper newObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new GuavaModule()); - return mapper; - } - - private Jackson() {} - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java deleted file mode 100644 index 9887bfe..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import javax.ws.rs.ext.ContextResolver; - -import com.fasterxml.jackson.databind.ObjectMapper; - -public class ObjectMapperContextResolver implements ContextResolver { - - private final ObjectMapper objectMapper; - public ObjectMapperContextResolver(final ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - @Override - public ObjectMapper getContext(final Class type) { - return objectMapper; - } - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java deleted file mode 100644 index 8bb04a6..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; - -/** - * Deserializes Consul time values with "s" suffix to {@link Long} objects. - */ -public class SecondsDeserializer extends JsonDeserializer { - - @Override - public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - String value = p.getValueAsString(); - - if (StringUtils.isNotEmpty(value)) { - value = value.replaceAll("[a-zA-Z]", ""); - return Long.valueOf(value); - } else { - return null; - } - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java deleted file mode 100644 index 8c0ba85..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * Serializes a time field (e.g. TTL) as seconds. - */ -public class SecondsSerializer extends JsonSerializer { - - @Override - public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(String.format("%ss", value)); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java deleted file mode 100644 index 7bdee6f..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.consul.util; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.google.common.primitives.UnsignedLongs; - -import java.io.IOException; - -/** - * @author sgardner - * @since 2015.02.28 - */ -public class UnsignedLongDeserializer extends JsonDeserializer { - @Override - public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { - String sValue = jp.getValueAsString(); - return UnsignedLongs.decode(sValue); - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java deleted file mode 100644 index 50960c7..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/serviceListener/MicroServiceChangeListener.java +++ /dev/null @@ -1,291 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.serviceListener; - -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.ApiRouteInfo; -import org.openo.msb.api.CustomRouteInfo; -import org.openo.msb.api.IuiRouteInfo; -import org.openo.msb.api.Node; -import org.openo.msb.api.RouteServer; -import org.openo.msb.api.Service; -import org.openo.msb.wrapper.ApiRouteServiceWrapper; -import org.openo.msb.wrapper.CustomRouteServiceWrapper; -import org.openo.msb.wrapper.IuiRouteServiceWrapper; -import org.openo.msb.wrapper.util.RegExpTestUtil; -import org.openo.msb.wrapper.util.RouteUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class MicroServiceChangeListener implements IMicroServiceChangeListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceChangeListener.class); - - @Override - public void onSave(Service microServiceInfo, String serverPort) { - - if ("UI".equals(microServiceInfo.getProtocol())) { - IuiRouteInfo iuiRouteInfo = this.buildIuiRouteInfo(microServiceInfo); - if (null != iuiRouteInfo) { - IuiRouteServiceWrapper.getInstance().saveIuiRouteInstance(iuiRouteInfo); - } - } else if ("REST".equals(microServiceInfo.getProtocol())) { - ApiRouteInfo apiRouteInfo = this.buildApiRouteInfo(microServiceInfo); - if (null != apiRouteInfo) { - ApiRouteServiceWrapper.getInstance().saveApiRouteInstance(apiRouteInfo, serverPort); - } - } else if ("HTTP".equals(microServiceInfo.getProtocol())) { - CustomRouteInfo customRouteInfo = this.buildCustomRouteInfo(microServiceInfo); - if (null != customRouteInfo) { - CustomRouteServiceWrapper.getInstance() - .saveCustomRouteInstance(customRouteInfo, serverPort); - } - } - - } - - @Override - public void onChange(String serviceName, String version, Service microServiceInfo, - String serverPort) { - - if ("UI".equals(microServiceInfo.getProtocol())) { - if (serviceName.startsWith("iui_") || serviceName.startsWith("IUI_")) { - serviceName = serviceName.substring(4); - } - IuiRouteInfo iuiRouteInfo = this.buildIuiRouteInfo(microServiceInfo); - if (null != iuiRouteInfo) { - IuiRouteServiceWrapper.getInstance().updateIuiRouteInstance(serviceName, iuiRouteInfo); - } - } else if ("REST".equals(microServiceInfo.getProtocol())) { - ApiRouteInfo apiRouteInfo = this.buildApiRouteInfo(microServiceInfo); - if (null != apiRouteInfo) { - ApiRouteServiceWrapper.getInstance().updateApiRouteInstance(serviceName, version, - apiRouteInfo, serverPort); - } - } else if ("HTTP".equals(microServiceInfo.getProtocol())) { - if (!serviceName.startsWith("/")) { - serviceName = "/" + serviceName; - } - CustomRouteInfo customRouteInfo = this.buildCustomRouteInfo(microServiceInfo); - if (null != customRouteInfo) { - CustomRouteServiceWrapper.getInstance().updateCustomRouteInstance(serviceName, - customRouteInfo, serverPort); - } - } - - - - } - - @Override - public void onStatusChange(String serviceName, String url, String version, String protocol, - String status) { - if ("UI".equals(protocol)) { - - if (serviceName.startsWith("iui_") || serviceName.startsWith("IUI_")) { - serviceName = serviceName.substring(4); - } - IuiRouteServiceWrapper.getInstance().updateIuiRouteStatus(serviceName, status); - - } else if ("REST".equals(protocol)) { - ApiRouteServiceWrapper.getInstance().updateApiRouteStatus(serviceName, version, status); - } else if ("HTTP".equals(protocol)) { - if (!serviceName.startsWith("/")) { - serviceName = "/" + serviceName; - } - CustomRouteServiceWrapper.getInstance().updateCustomRouteStatus(serviceName, status); - } - - } - - @Override - public void onDelete(String serviceName, String url, String version, String protocol, - String serverPort) { - - if ("UI".equals(protocol)) { - if (serviceName.startsWith("iui_") || serviceName.startsWith("IUI_")) { - serviceName = serviceName.substring(4); - } - IuiRouteServiceWrapper.getInstance().deleteIuiRoute(serviceName, "*"); - - } else if ("REST".equals(protocol)) { - ApiRouteServiceWrapper.getInstance().deleteApiRoute(serviceName, version, "*", serverPort); - } else if ("HTTP".equals(protocol)) { - if (!serviceName.startsWith("/")) { - serviceName = "/" + serviceName; - } - - CustomRouteServiceWrapper.getInstance().deleteCustomRoute(serviceName, "*", serverPort); - } - - } - - - /** - * @Title ifApiRouteUrl - * @Description TODO(According to judge whether the API registration URL format) - * @param url - * @return - * @return boolean - */ - private boolean ifApiRouteUrl(String url) { - return RegExpTestUtil.apiRouteUrlRegExpTest(url); - } - - - /** - * From MicroServiceInfo to ApiRouteInfo - * - * @param microServiceInfo - * @return - */ - private ApiRouteInfo buildApiRouteInfo(Service microServiceInfo) { - - ApiRouteInfo apiRouteInfo = new ApiRouteInfo(); - apiRouteInfo.setUrl(microServiceInfo.getUrl()); - - Set nodes = microServiceInfo.getNodes(); - RouteServer[] routeServers = new RouteServer[nodes.size()]; - - - int i = 0; - for (Node node : nodes) { - RouteServer routeServer = new RouteServer(node.getIp(), node.getPort()); - routeServers[i] = routeServer; - i++; - } - - - apiRouteInfo.setServers(routeServers); - String[] rangs = StringUtils.split(microServiceInfo.getVisualRange(), "|"); - if (RouteUtil.contain(rangs, "0")) { - apiRouteInfo.setVisualRange("0"); - } else { - apiRouteInfo.setVisualRange("1"); - } - - - if ("ip_hash".equals(microServiceInfo.getLb_policy())) { - apiRouteInfo.setUseOwnUpstream("1"); - } - - - - apiRouteInfo.setServiceName(microServiceInfo.getServiceName()); - apiRouteInfo.setVersion(microServiceInfo.getVersion()); - // TODO:set json and metrics defaultValue - String version = - "".equals(microServiceInfo.getVersion()) ? "" : "/" + microServiceInfo.getVersion(); - apiRouteInfo.setApiJson(microServiceInfo.getUrl() + "/swagger.json"); - apiRouteInfo.setMetricsUrl("/admin/metrics"); - return apiRouteInfo; - } - - - /** - * From MicroServiceInfo to CustomRouteInfo - * - * @param microServiceInfo - * @return - */ - private CustomRouteInfo buildCustomRouteInfo(Service microServiceInfo) { - - CustomRouteInfo customRouteInfo = new CustomRouteInfo(); - customRouteInfo.setUrl(microServiceInfo.getUrl()); - - Set nodes = microServiceInfo.getNodes(); - RouteServer[] routeServers = new RouteServer[nodes.size()]; - - - int i = 0; - for (Node node : nodes) { - RouteServer routeServer = new RouteServer(node.getIp(), node.getPort()); - routeServers[i] = routeServer; - i++; - } - - customRouteInfo.setServers(routeServers); - String[] rangs = StringUtils.split(microServiceInfo.getVisualRange(), "|"); - if (RouteUtil.contain(rangs, "0")) { - customRouteInfo.setVisualRange("0"); - } else { - customRouteInfo.setVisualRange("1"); - } - - if ("ip_hash".equals(microServiceInfo.getLb_policy())) { - customRouteInfo.setUseOwnUpstream("1"); - } - - String serviceName; - if (!microServiceInfo.getServiceName().startsWith("/")) { - serviceName = "/" + microServiceInfo.getServiceName(); - } else { - serviceName = microServiceInfo.getServiceName(); - } - customRouteInfo.setServiceName(serviceName); - - return customRouteInfo; - } - - - /** - * From MicroServiceInfo to IuiRouteInfo - * - * @param microServiceInfo - * @return - */ - private IuiRouteInfo buildIuiRouteInfo(Service microServiceInfo) { - - IuiRouteInfo iuiRouteInfo = new IuiRouteInfo(); - iuiRouteInfo.setUrl(microServiceInfo.getUrl()); - - Set nodes = microServiceInfo.getNodes(); - RouteServer[] routeServers = new RouteServer[nodes.size()]; - - - int i = 0; - for (Node node : nodes) { - RouteServer routeServer = new RouteServer(node.getIp(), node.getPort()); - routeServers[i] = routeServer; - i++; - } - - iuiRouteInfo.setServers(routeServers); - String[] rangs = StringUtils.split(microServiceInfo.getVisualRange(), "|"); - if (RouteUtil.contain(rangs, "0")) { - iuiRouteInfo.setVisualRange("0"); - } else { - iuiRouteInfo.setVisualRange("1"); - } - - if ("ip_hash".equals(microServiceInfo.getLb_policy())) { - iuiRouteInfo.setUseOwnUpstream("1"); - } - - String serviceName = microServiceInfo.getServiceName(); - if (serviceName.startsWith("iui_") || serviceName.startsWith("IUI_")) { - serviceName = serviceName.substring(4); - } - - - iuiRouteInfo.setServiceName(serviceName); - - return iuiRouteInfo; - } -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java deleted file mode 100644 index 5157187..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JacksonJsonUtil.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.util; - -import java.util.List; - -import org.openo.msb.api.ApiRouteInfo; -import org.openo.msb.api.RouteServer; -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 static ObjectMapper mapper; - - - public static synchronized ObjectMapper getMapperInstance() { - 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; - try { - ObjectMapper objectMapper = getMapperInstance(); - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - json =objectMapper.writeValueAsString(obj); - } catch (Exception e) { - logger.error("Class beanToJson faild"); - throw new Exception("Class beanToJson faild"); - } - 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 List jsonToListBean(String json) throws Exception { - List vo =null; - try { - - ObjectMapper objectMapper = getMapperInstance(); - - - vo = objectMapper.readValue(json, new TypeReference>() {}); - - } catch (Exception e) { - throw new Exception( "JSON_TO_BEAN_FAILD"); - } - return vo; - } - - public static void main(String[] args) { - RouteServer server=new RouteServer("127.0.0.1","80"); - try { - String json=beanToJson(server); - System.out.println(json); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java deleted file mode 100644 index 46d071e..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/JedisUtil.java +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.util; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.util.PropertyResourceBundle; -import java.util.ResourceBundle; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; - - - -public final 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 static JedisPool jedisPool = null; - - public static String serverIp="127.0.0.1"; - - public static int serverPort=10080; - - public static String propertiesName="redis.properties"; - - public static String propertiesPath=""; - - - -public static void main(String[] args) { - -} - - private JedisUtil() { - // private constructor - - } - - private static void initialPool() { - try { - JedisPoolConfig config = new JedisPoolConfig(); - -// String pathtest=JedisUtil.class.getResource("").getPath(); -// String path ="/"+ pathtest.substring(0, pathtest.indexOf("assembly")).replace("file:/", "") +"assembly/"+defaultWorkspace; - - 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!"); - } - - - - String strHost = bundle.getString("redis.host"); - if(StringUtils.isNotEmpty(strHost)){ - host = strHost; - } - String strPort = bundle.getString("redis.port"); - if(StringUtils.isNotEmpty(strPort)){ - port = Integer.valueOf(strPort); - } - - - String strTimeout = bundle.getString("redis.connectionTimeout"); - if (StringUtils.isNotEmpty(strTimeout) ){ - connectionTimeout = Integer.valueOf(strTimeout); - } - -// serverIp=bundle.getString("server.ip"); - serverPort=Integer.valueOf(bundle.getString("server.port")); - - String strDbIndex = bundle.getString("redis.db_index"); - if (StringUtils.isNotEmpty(strDbIndex)) { - DEFAULT_DB_INDEX = Integer.valueOf(strDbIndex); - } - - String strMaxTotal = bundle.getString("redis.pool.maxTotal"); - if (StringUtils.isNotEmpty(strMaxTotal)) { - config.setMaxTotal(Integer.valueOf(strMaxTotal)); - } - - String strMaxIdle = bundle.getString("redis.pool.maxIdle"); - if (StringUtils.isNotEmpty(strMaxIdle)) { - config.setMaxIdle(Integer.valueOf(strMaxIdle)); - } - - String strMaxWaitMillis = bundle.getString("redis.pool.maxWaitMillis"); - if (StringUtils.isNotEmpty(strMaxWaitMillis)) { - config.setMaxWaitMillis(Long.valueOf(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)); - } - - } - - LOGGER.info("Redis server info: " + host + ":" + port); - LOGGER.info("nginx server info: " + serverIp + ":" + serverPort); - - -// ResourceBundle bundle = ResourceBundle.getBundle("conf.redis"); - - jedisPool = new JedisPool(config, host, port, connectionTimeout); - } catch (Exception e) { - LOGGER.error("Initiate Jedis pool failed!", e); - } - } - /** - * From the connection pool to obtain jedis instance, use the default database index number 0 - * @return - */ - public synchronized static Jedis borrowJedisInstance() { - if (jedisPool == null) { - initialPool(); - } - try { - if (jedisPool != null) { - Jedis resource = jedisPool.getResource(); - resource.select(DEFAULT_DB_INDEX); - return resource; - } else { - return null; - } - } catch (Exception e) { - LOGGER.error("Get Jedis from pool failed!", e); - return null; - } - } - /** - * From the connection pool to obtain jedis instance, using the specified database index number - * @return - */ - public synchronized static Jedis borrowJedisInstance(final int dbIndex) { - if (jedisPool == null) { - initialPool(); - } - try { - if (jedisPool != null) { - Jedis resource = jedisPool.getResource(); - resource.select(dbIndex); - return resource; - } else { - return null; - } - } catch (Exception e) { - LOGGER.error("Get Jedis from pool failed!", e); - return null; - } - } - - /** - * returned to the pool jedis instance - * @param jedis - */ - public static void returnJedisInstance(final Jedis jedis) { - if (jedis != null) { - jedis.close(); - } - } - - - /** - * @Title getJedis - * @Description TODO(From the connection pool to obtain jedis instance) - * @throws Exception - * @return Jedis - */ - public static Jedis getJedis() throws Exception{ - - - Jedis jedis = borrowJedisInstance(); - if (jedis == null) { - throw new Exception("fetch from jedis pool failed,null object!"); - - } - - return jedis; - - } - -} \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java deleted file mode 100644 index f2e2004..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java +++ /dev/null @@ -1,428 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.util; - -import java.sql.Date; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.MicroServiceFullInfo; -import org.openo.msb.api.MicroServiceInfo; -import org.openo.msb.api.Node; -import org.openo.msb.api.NodeInfo; -import org.openo.msb.api.Service; -import org.openo.msb.wrapper.serviceListener.IMicroServiceChangeListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; - -public class MicroServiceDB { - - private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceDB.class); - - private static MicroServiceDB instance = new MicroServiceDB(); - - private List serviceListenerlist = - new ArrayList(); - - private MicroServiceDB() {} - - public static MicroServiceDB getInstance() { - return instance; - } - - - public void addServiceChangeListener(IMicroServiceChangeListener listener) { - synchronized (serviceListenerlist) { - serviceListenerlist.add(listener); - } - } - - - public void removeServiceChangeListener(IMicroServiceChangeListener listener) { - synchronized (serviceListenerlist) { - serviceListenerlist.remove(listener); - } - } - - - public MicroServiceFullInfo[] getAllMicroServiceInstances() throws Exception { - Jedis jedis = null; - MicroServiceFullInfo[] microServiceList; - try { - jedis = JedisUtil.getJedis(); - - String routekey = - MicroServiceUtil.getPrefixedKey("","*", MicroServiceUtil.SUFFIX_PATH_INFO); - Set serviceSet = jedis.keys(routekey); - microServiceList = new MicroServiceFullInfo[serviceSet.size()]; - - Pattern redisKeyPattern = MicroServiceUtil.getRedisKeyPattern(); - int i = 0; - for (String servicePath : serviceSet) { - Matcher matcher = redisKeyPattern.matcher(servicePath); - if (matcher.matches()) { - microServiceList[i] = getMicroServiceByJedis(jedis, matcher.group("servicename"),matcher.group("version"), ""); - i++; - } - } - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new Exception("call redis throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return microServiceList; - } - - public void saveMicroServiceInfo2Redis(MicroServiceInfo microServiceInfo,String serverPort) throws Exception { - // 1.1 set info - String serviceInfokey = - MicroServiceUtil.getServiceInfoKey(serverPort,microServiceInfo.getServiceName(), - microServiceInfo.getVersion()); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("url", microServiceInfo.getUrl()); - serviceInfoMap.put("protocol", microServiceInfo.getProtocol()); - serviceInfoMap.put("visualRange",microServiceInfo.getVisualRange()); - serviceInfoMap.put("lb_policy",microServiceInfo.getLb_policy()); - serviceInfoMap.put("status", "1"); - - - - // 1.2 set lb info - String serviceLBkey = - MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(), - microServiceInfo.getVersion(), MicroServiceUtil.ROUTE_PATH_LOADBALANCE); - - - Jedis jedis = null; - try { - jedis = JedisUtil.getJedis(); - // 2.1 save info - jedis.hmset(serviceInfokey, serviceInfoMap); - - - for(Node node:microServiceInfo.getNodes()){ - - String key=serviceLBkey+":"+node.getIp()+"-"+node.getPort(); - - Map nodeMap = new HashMap(); - - nodeMap.put("ip", node.getIp()); - nodeMap.put("port", node.getPort()); - nodeMap.put("ttl", Integer.toString(node.getTtl())); - long expiration_time=System.currentTimeMillis()+node.getTtl()*1000; - nodeMap.put("expiration", Long.toString(expiration_time)); - - if(jedis.keys(key).isEmpty()){ - nodeMap.put("created_at", Long.toString(System.currentTimeMillis())); - } -// else{ -// Map nodeLBmap = jedis.hgetAll(key); -// nodeMap.put("created_at", nodeLBmap.get("created_at")); -// } - nodeMap.put("updated_at", Long.toString(System.currentTimeMillis())); - - jedis.hmset(key, nodeMap); - } - -// jedis.sadd(serviceLBkey, nodeArray); - - } catch (Exception e) { - LOGGER.error("save to redis throw exception", e); - throw new Exception("save to redis throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - - - } - - public void updateMicroServiceStatus(String serviceName, String version,String status) throws Exception{ - - - String serviceInfokey = MicroServiceUtil.getServiceInfoKey("",serviceName, version); - Map serviceInfoMap = new HashMap(); - serviceInfoMap.put("status", status); - - - Jedis jedis = null; - try { - jedis = JedisUtil.borrowJedisInstance(); - if (jedis == null) { - throw new Exception("fetch from jedis pool failed,null object!"); - } - jedis.hmset(serviceInfokey, serviceInfoMap); - } - catch (Exception e) { - LOGGER.error("update MicroService status throw exception", e); - throw new Exception("update MicroService status throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - } - - - public void updateMicroServiceNode2Redis(String serviceName, String version,String ip,String port,int ttl) throws Exception { - String serviceLBkey = - MicroServiceUtil.getPrefixedKey("",serviceName,version, MicroServiceUtil.ROUTE_PATH_LOADBALANCE); - - - Jedis jedis = null; - try { - jedis = JedisUtil.getJedis(); - - - String nodeKey=serviceLBkey+":"+ip+"-"+port; - Map nodeLBmap = jedis.hgetAll(nodeKey); - - if(nodeLBmap.isEmpty()){ - throw new NullPointerException(" MicroService Node not fond "); - } - - - nodeLBmap.put("ttl", Integer.toString(ttl)); - long expiration_time=System.currentTimeMillis()+ttl*1000; - nodeLBmap.put("expiration", Long.toString(expiration_time)); - nodeLBmap.put("updated_at", Long.toString(System.currentTimeMillis())); - - jedis.hmset(nodeKey, nodeLBmap); - - - } - catch (NullPointerException e){ - throw e; - } - catch (Exception e) { - LOGGER.error("update MicroService Node throw exception", e); - throw new Exception("update MicroService Node throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - } - - - public void noticeUpdateApiListener(String serviceName,String version,Service microServiceInfo,String serverPort) { - if (isNeedNotify(microServiceInfo)) { - for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { - serviceListener.onChange(serviceName,version, microServiceInfo,serverPort); - } - } - - } - - public void noticeUpdateStatusListener(Service microServiceInfo,String status) { - - for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { - serviceListener.onStatusChange(microServiceInfo.getServiceName(),microServiceInfo.getUrl(), - microServiceInfo.getVersion(),microServiceInfo.getProtocol(),status); - } - } - - - - public void noticeApiListener(Service microServiceInfo, String type,String serverPort) { - if (isNeedNotify(microServiceInfo)) { - - if ("ADD".equals(type)) { - for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { - serviceListener.onSave(microServiceInfo,serverPort); - } - } else if ("DELETE".equals(type)) { - for (IMicroServiceChangeListener serviceListener : serviceListenerlist) { - serviceListener.onDelete(microServiceInfo.getServiceName(),microServiceInfo.getUrl(), - microServiceInfo.getVersion(),microServiceInfo.getProtocol(),serverPort); - } - } - - } - } - - - public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort) - throws Exception { - if (null == version || "null".equals(version)) { - version = ""; - } - - Jedis jedis = null; - MicroServiceFullInfo microServiceInfo = null; - - try { - jedis = JedisUtil.getJedis(); - - microServiceInfo= getMicroServiceByJedis(jedis,serviceName,version, serverPort); - - - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new Exception("call redis throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - return microServiceInfo; - - } - - private MicroServiceFullInfo getMicroServiceByJedis(Jedis jedis,String serviceName, String version,String serverPort){ - MicroServiceFullInfo microServiceInfo = null; - String serviceInfoKey = MicroServiceUtil.getServiceInfoKey(serverPort,serviceName, version); - Map infomap = jedis.hgetAll(serviceInfoKey); - if (!infomap.isEmpty()) { - microServiceInfo = new MicroServiceFullInfo(); - microServiceInfo.setServiceName(serviceName); - microServiceInfo.setVersion(version); - microServiceInfo.setUrl(infomap.get("url")); - microServiceInfo.setProtocol(infomap.get("protocol")); - microServiceInfo.setVisualRange(infomap.get("visualRange")); - microServiceInfo.setStatus(infomap.get("status")); - microServiceInfo.setLb_policy(infomap.get("lb_policy")); - - String nodeLBkey = - MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(), - microServiceInfo.getVersion(), - MicroServiceUtil.ROUTE_PATH_LOADBALANCE); - - Set nodeKeys=jedis.keys(nodeLBkey+":*"); - - Set nodes=new HashSet(); - for(String nodeKey:nodeKeys){ - Map nodeLBmap = jedis.hgetAll(nodeKey); - NodeInfo nodeInfo=new NodeInfo(); - nodeInfo.setNodeId(serviceName+"_"+nodeLBmap.get("ip")+"_"+nodeLBmap.get("port")); - nodeInfo.setIp(nodeLBmap.get("ip")); - nodeInfo.setPort(nodeLBmap.get("port")); - nodeInfo.setTtl(Integer.parseInt(nodeLBmap.get("ttl"))); - nodeInfo.setCreated_at(new Date(Long.parseLong(nodeLBmap.get("created_at")))); - nodeInfo.setUpdated_at(new Date(Long.parseLong(nodeLBmap.get("updated_at")))); - nodeInfo.setExpiration(new Date(Long.parseLong(nodeLBmap.get("expiration")))); - - nodes.add(nodeInfo); - } - - microServiceInfo.setNodes(nodes); - } - - - - - return microServiceInfo; - } - - - public void deleteMicroService(String serviceName, String version,String serverPort) throws Exception { - if (null == version || "null".equals(version)) { - version = ""; - } - - Jedis jedis = null; - try { - jedis = JedisUtil.getJedis(); - String routekey = MicroServiceUtil.getPrefixedKey(serverPort,serviceName, version, "*"); - Set infoSet = jedis.keys(routekey); - - if (infoSet.isEmpty()) { - LOGGER.error("delete MicroService FAIL:serviceName-" - + serviceName + ",version:" + version + " not fond "); - } - else{ - String[] paths = new String[infoSet.size()]; - - infoSet.toArray(paths); - - jedis.del(paths); - } - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new Exception("call redis throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - } - - public void deleteNode(String serviceName, String version, String ip,String port) throws Exception { - if (null == version || "null".equals(version)) { - version = ""; - } - - Jedis jedis = null; - try { - jedis = JedisUtil.getJedis(); - String serviceLBkey = - MicroServiceUtil.getPrefixedKey("",serviceName, version, - MicroServiceUtil.ROUTE_PATH_LOADBALANCE,ip+"-"+port); - jedis.del(serviceLBkey); - } catch (Exception e) { - LOGGER.error("call redis throw exception", e); - throw new Exception("call redis throw exception:"+e.getMessage()); - } finally { - JedisUtil.returnJedisInstance(jedis); - } - - } - - - /** - * Determine whether the service needs to send a notification - * TODO: filter according to the agreement, - * the only notice of agreement for REST \ UI interface MSB - REST - * @param protocol - * @return - */ - private boolean isNeedNotifyByProtocol(String protocol) { - return "UI".equalsIgnoreCase(protocol) || "REST".equalsIgnoreCase(protocol) || "HTTP".equalsIgnoreCase(protocol); - } - - /** - * Determine whether the service needs to send a notification - * TODO: according to the visual range filter conditions - * @param visualRange - * @return - */ - private boolean isNeedNotifyByVisualRange(String visualRange) { - String[] rangeArray=StringUtils.split(visualRange, "|"); - return RouteUtil.contain(RouteUtil.visualRangeMatches, rangeArray); - } - - /** - * According to the MicroServiceInfo entity information to judge whether need to send a notification - * @param microServiceInfo - * @return - */ - private boolean isNeedNotify(Service microServiceInfo) { - if (null != microServiceInfo) { - return isNeedNotifyByProtocol(microServiceInfo.getProtocol()) && - isNeedNotifyByVisualRange(microServiceInfo.getVisualRange()); - } else { - return false; - } - } - - - -} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java deleted file mode 100644 index c987142..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/RouteUtil.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright 2016 ZTE Corporation. - * - * 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.openo.msb.wrapper.util; - -import org.apache.commons.lang3.StringUtils; -import org.openo.msb.api.DiscoverInfo; - - -public class RouteUtil { - - public static String IUI_ROOT_PATH="iui"; - - public static String API_ROOT_PATH="api"; - - public static final String ROUTE_PATH="msb:routing"; - - public static final String APIROUTE="api"; - - public static final String IUIROUTE="iui"; - - public static final String CUSTOMROUTE="custom"; - - public static final String P2PROUTE="p2p"; - - - public static final String ROUTE_PATH_INFO="info"; - - public static final String ROUTE_PATH_LOADBALANCE="lb"; - - public static final String APIROUTE_PATH_LIFE="life"; - - - public static final String REQUEST_SUCCESS = "SUCCESS"; - - public static final String REQUEST_FAIL = "FAIL"; - - public static String PROTOCOL_LIST="REST,UI,HTTP,MQ,FTP,SNMP,TCP,UDP"; - - public static DiscoverInfo discoverInfo=new DiscoverInfo(); - - - public static String[] visualRangeRange={"0","1"}; - - public static String[] controlRangeMatches={"0","1","2"}; - - public static String[] statusRangeMatches={"0","1"}; - - public static String[] useOwnUpstreamRangeMatches={"0","1"}; - - public static String[] visualRangeMatches={"1"}; - - /** - * @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(String.valueOf(JedisUtil.serverPort))){ - sb.append(ROUTE_PATH); - } - else{ - sb.append(paths[0]); - } - - for (int i = 1; i < paths.length; i++) { - sb.append(":"); - sb.append(paths[i]); - } - return sb.toString(); - } - - - 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[] array,String str){ - for(int i=0;i - - - - - ZENAP API-DOC. - - ZENAP API-DOC - - - - - index.html - index.xhtml - index.htm - index.jsp - - - - diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js b/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js deleted file mode 100644 index 9971682..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.contentWindow.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! iFrame Resizer (iframeSizer.contentWindow.min.js) - v3.5.3 - 2016-02-23 - * Desc: Include this file in any page being loaded into an iframe - * to force the iframe to resize to the content size. - * Requires: iframeResizer.min.js on host page. - * Copyright: (c) 2016 David J. Bradshaw - dave@bradshaw.net - * License: MIT - */ -!function(a){"use strict";function b(b,c,d){"addEventListener"in a?b.addEventListener(c,d,!1):"attachEvent"in a&&b.attachEvent("on"+c,d)}function c(b,c,d){"removeEventListener"in a?b.removeEventListener(c,d,!1):"detachEvent"in a&&b.detachEvent("on"+c,d)}function d(a){return a.charAt(0).toUpperCase()+a.slice(1)}function e(a){var b,c,d,e=null,f=0,g=function(){f=Fa(),e=null,d=a.apply(b,c),e||(b=c=null)};return function(){var h=Fa();f||(f=h);var i=xa-(h-f);return b=this,c=arguments,0>=i||i>xa?(e&&(clearTimeout(e),e=null),f=h,d=a.apply(b,c),e||(b=c=null)):e||(e=setTimeout(g,i)),d}}function f(a){return ma+"["+oa+"] "+a}function g(b){la&&"object"==typeof a.console&&console.log(f(b))}function h(b){"object"==typeof a.console&&console.warn(f(b))}function i(){j(),g("Initialising iFrame ("+location.href+")"),k(),n(),m("background",W),m("padding",$),A(),s(),t(),o(),C(),u(),ia=B(),N("init","Init message from host page"),Da()}function j(){function a(a){return"true"===a?!0:!1}var b=ha.substr(na).split(":");oa=b[0],X=void 0!==b[1]?Number(b[1]):X,_=void 0!==b[2]?a(b[2]):_,la=void 0!==b[3]?a(b[3]):la,ja=void 0!==b[4]?Number(b[4]):ja,U=void 0!==b[6]?a(b[6]):U,Y=b[7],fa=void 0!==b[8]?b[8]:fa,W=b[9],$=b[10],ua=void 0!==b[11]?Number(b[11]):ua,ia.enable=void 0!==b[12]?a(b[12]):!1,qa=void 0!==b[13]?b[13]:qa,Aa=void 0!==b[14]?b[14]:Aa}function k(){function b(){var b=a.iFrameResizer;g("Reading data from page: "+JSON.stringify(b)),Ca="messageCallback"in b?b.messageCallback:Ca,Da="readyCallback"in b?b.readyCallback:Da,ta="targetOrigin"in b?b.targetOrigin:ta,fa="heightCalculationMethod"in b?b.heightCalculationMethod:fa,Aa="widthCalculationMethod"in b?b.widthCalculationMethod:Aa}"iFrameResizer"in a&&Object===a.iFrameResizer.constructor&&b(),g("TargetOrigin for parent set to: "+ta)}function l(a,b){return-1!==b.indexOf("-")&&(h("Negative CSS value ignored for "+a),b=""),b}function m(a,b){void 0!==b&&""!==b&&"null"!==b&&(document.body.style[a]=b,g("Body "+a+' set to "'+b+'"'))}function n(){void 0===Y&&(Y=X+"px"),m("margin",l("margin",Y))}function o(){document.documentElement.style.height="",document.body.style.height="",g('HTML & body height set to "auto"')}function p(e){function f(){N(e.eventName,e.eventType)}var h={add:function(c){b(a,c,f)},remove:function(b){c(a,b,f)}};e.eventNames&&Array.prototype.map?(e.eventName=e.eventNames[0],e.eventNames.map(h[e.method])):h[e.method](e.eventName),g(d(e.method)+" event listener: "+e.eventType)}function q(a){p({method:a,eventType:"Animation Start",eventNames:["animationstart","webkitAnimationStart"]}),p({method:a,eventType:"Animation Iteration",eventNames:["animationiteration","webkitAnimationIteration"]}),p({method:a,eventType:"Animation End",eventNames:["animationend","webkitAnimationEnd"]}),p({method:a,eventType:"Input",eventName:"input"}),p({method:a,eventType:"Mouse Up",eventName:"mouseup"}),p({method:a,eventType:"Mouse Down",eventName:"mousedown"}),p({method:a,eventType:"Orientation Change",eventName:"orientationchange"}),p({method:a,eventType:"Print",eventName:["afterprint","beforeprint"]}),p({method:a,eventType:"Ready State Change",eventName:"readystatechange"}),p({method:a,eventType:"Touch Start",eventName:"touchstart"}),p({method:a,eventType:"Touch End",eventName:"touchend"}),p({method:a,eventType:"Touch Cancel",eventName:"touchcancel"}),p({method:a,eventType:"Transition Start",eventNames:["transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart"]}),p({method:a,eventType:"Transition Iteration",eventNames:["transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration"]}),p({method:a,eventType:"Transition End",eventNames:["transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend"]}),"child"===qa&&p({method:a,eventType:"IFrame Resized",eventName:"resize"})}function r(a,b,c,d){return b!==a&&(a in c||(h(a+" is not a valid option for "+d+"CalculationMethod."),a=b),g(d+' calculation method set to "'+a+'"')),a}function s(){fa=r(fa,ea,Ga,"height")}function t(){Aa=r(Aa,za,Ha,"width")}function u(){!0===U?(q("add"),F()):g("Auto Resize disabled")}function v(){g("Disable outgoing messages"),ra=!1}function w(){g("Remove event listener: Message"),c(a,"message",S)}function x(){null!==Z&&Z.disconnect()}function y(){q("remove"),x(),clearInterval(ka)}function z(){v(),w(),!0===U&&y()}function A(){var a=document.createElement("div");a.style.clear="both",a.style.display="block",document.body.appendChild(a)}function B(){function c(){return{x:void 0!==a.pageXOffset?a.pageXOffset:document.documentElement.scrollLeft,y:void 0!==a.pageYOffset?a.pageYOffset:document.documentElement.scrollTop}}function d(a){var b=a.getBoundingClientRect(),d=c();return{x:parseInt(b.left,10)+parseInt(d.x,10),y:parseInt(b.top,10)+parseInt(d.y,10)}}function e(a){function b(a){var b=d(a);g("Moving to in page link (#"+c+") at x: "+b.x+" y: "+b.y),R(b.y,b.x,"scrollToOffset")}var c=a.split("#")[1]||a,e=decodeURIComponent(c),f=document.getElementById(e)||document.getElementsByName(e)[0];void 0!==f?b(f):(g("In page link (#"+c+") not found in iFrame, so sending to parent"),R(0,0,"inPageLink","#"+c))}function f(){""!==location.hash&&"#"!==location.hash&&e(location.href)}function i(){function a(a){function c(a){a.preventDefault(),e(this.getAttribute("href"))}"#"!==a.getAttribute("href")&&b(a,"click",c)}Array.prototype.forEach.call(document.querySelectorAll('a[href^="#"]'),a)}function j(){b(a,"hashchange",f)}function k(){setTimeout(f,ba)}function l(){Array.prototype.forEach&&document.querySelectorAll?(g("Setting up location.hash handlers"),i(),j(),k()):h("In page linking not fully supported in this browser! (See README.md for IE8 workaround)")}return ia.enable?l():g("In page linking not enabled"),{findTarget:e}}function C(){g("Enable public methods"),Ba.parentIFrame={autoResize:function(a){return!0===a&&!1===U?(U=!0,u()):!1===a&&!0===U&&(U=!1,y()),U},close:function(){R(0,0,"close"),z()},getId:function(){return oa},getPageInfo:function(a){"function"==typeof a?(Ea=a,R(0,0,"pageInfo")):(Ea=function(){},R(0,0,"pageInfoStop"))},moveToAnchor:function(a){ia.findTarget(a)},reset:function(){Q("parentIFrame.reset")},scrollTo:function(a,b){R(b,a,"scrollTo")},scrollToOffset:function(a,b){R(b,a,"scrollToOffset")},sendMessage:function(a,b){R(0,0,"message",JSON.stringify(a),b)},setHeightCalculationMethod:function(a){fa=a,s()},setWidthCalculationMethod:function(a){Aa=a,t()},setTargetOrigin:function(a){g("Set targetOrigin: "+a),ta=a},size:function(a,b){var c=""+(a?a:"")+(b?","+b:"");N("size","parentIFrame.size("+c+")",a,b)}}}function D(){0!==ja&&(g("setInterval: "+ja+"ms"),ka=setInterval(function(){N("interval","setInterval: "+ja)},Math.abs(ja)))}function E(){function b(a){function b(a){!1===a.complete&&(g("Attach listeners to "+a.src),a.addEventListener("load",f,!1),a.addEventListener("error",h,!1),k.push(a))}"attributes"===a.type&&"src"===a.attributeName?b(a.target):"childList"===a.type&&Array.prototype.forEach.call(a.target.querySelectorAll("img"),b)}function c(a){k.splice(k.indexOf(a),1)}function d(a){g("Remove listeners from "+a.src),a.removeEventListener("load",f,!1),a.removeEventListener("error",h,!1),c(a)}function e(a,b,c){d(a.target),N(b,c+": "+a.target.src,void 0,void 0)}function f(a){e(a,"imageLoad","Image loaded")}function h(a){e(a,"imageLoadFailed","Image load failed")}function i(a){N("mutationObserver","mutationObserver: "+a[0].target+" "+a[0].type),a.forEach(b)}function j(){var a=document.querySelector("body"),b={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0};return m=new l(i),g("Create body MutationObserver"),m.observe(a,b),m}var k=[],l=a.MutationObserver||a.WebKitMutationObserver,m=j();return{disconnect:function(){"disconnect"in m&&(g("Disconnect body MutationObserver"),m.disconnect(),k.forEach(d))}}}function F(){var b=0>ja;a.MutationObserver||a.WebKitMutationObserver?b?D():Z=E():(g("MutationObserver not supported in this browser!"),D())}function G(a,b){function c(a){var c=/^\d+(px)?$/i;if(c.test(a))return parseInt(a,V);var d=b.style.left,e=b.runtimeStyle.left;return b.runtimeStyle.left=b.currentStyle.left,b.style.left=a||0,a=b.style.pixelLeft,b.style.left=d,b.runtimeStyle.left=e,a}var d=0;return b=b||document.body,"defaultView"in document&&"getComputedStyle"in document.defaultView?(d=document.defaultView.getComputedStyle(b,null),d=null!==d?d[a]:0):d=c(b.currentStyle[a]),parseInt(d,V)}function H(a){a>xa/2&&(xa=2*a,g("Event throttle increased to "+xa+"ms"))}function I(a,b){for(var c=b.length,e=0,f=0,h=d(a),i=Fa(),j=0;c>j;j++)e=b[j].getBoundingClientRect()[a]+G("margin"+h,b[j]),e>f&&(f=e);return i=Fa()-i,g("Parsed "+c+" HTML elements"),g("Element position calculated in "+i+"ms"),H(i),f}function J(a){return[a.bodyOffset(),a.bodyScroll(),a.documentElementOffset(),a.documentElementScroll()]}function K(a,b){function c(){return h("No tagged elements ("+b+") found on page"),da}var d=document.querySelectorAll("["+b+"]");return 0===d.length?c():I(a,d)}function L(){return document.querySelectorAll("body *")}function M(a,b,c,d){function e(){da=l,ya=m,R(da,ya,a)}function f(){function a(a,b){var c=Math.abs(a-b)<=ua;return!c}return l=void 0!==c?c:Ga[fa](),m=void 0!==d?d:Ha[Aa](),a(da,l)||_&&a(ya,m)}function h(){return!(a in{init:1,interval:1,size:1})}function i(){return fa in pa||_&&Aa in pa}function j(){g("No change in size detected")}function k(){h()&&i()?Q(b):a in{interval:1}||j()}var l,m;f()||"init"===a?(O(),e()):k()}function N(a,b,c,d){function e(){a in{reset:1,resetPage:1,init:1}||g("Trigger event: "+b)}function f(){return va&&a in aa}f()?g("Trigger event cancelled: "+a):(e(),Ia(a,b,c,d))}function O(){va||(va=!0,g("Trigger event lock on")),clearTimeout(wa),wa=setTimeout(function(){va=!1,g("Trigger event lock off"),g("--")},ba)}function P(a){da=Ga[fa](),ya=Ha[Aa](),R(da,ya,a)}function Q(a){var b=fa;fa=ea,g("Reset trigger event: "+a),O(),P("reset"),fa=b}function R(a,b,c,d,e){function f(){void 0===e?e=ta:g("Message targetOrigin: "+e)}function h(){var f=a+":"+b,h=oa+":"+f+":"+c+(void 0!==d?":"+d:"");g("Sending message to host page ("+h+")"),sa.postMessage(ma+h,e)}!0===ra&&(f(),h())}function S(b){function c(){return ma===(""+b.data).substr(0,na)}function d(){ha=b.data,sa=b.source,i(),ca=!1,setTimeout(function(){ga=!1},ba)}function e(){ga?g("Page reset ignored by init"):(g("Page size reset by host page"),P("resetPage"))}function f(){N("resizeParent","Parent window requested size check")}function j(){var a=l();ia.findTarget(a)}function k(){return b.data.split("]")[1].split(":")[0]}function l(){return b.data.substr(b.data.indexOf(":")+1)}function m(){return"iFrameResize"in a}function n(){var a=l();g("MessageCallback called from parent: "+a),Ca(JSON.parse(a)),g(" --")}function o(){var a=l();g("PageInfoFromParent called from parent: "+a),Ea(JSON.parse(a)),g(" --")}function p(){return b.data.split(":")[2]in{"true":1,"false":1}}function q(){switch(k()){case"reset":e();break;case"resize":f();break;case"moveToAnchor":j();break;case"message":n();break;case"pageInfo":o();break;default:m()||p()||h("Unexpected message ("+b.data+")")}}function r(){!1===ca?q():p()?d():g('Ignored message of type "'+k()+'". Received before initialization.')}c()&&r()}function T(){"loading"!==document.readyState&&a.parent.postMessage("[iFrameResizerChild]Ready","*")}var U=!0,V=10,W="",X=0,Y="",Z=null,$="",_=!1,aa={resize:1,click:1},ba=128,ca=!0,da=1,ea="bodyOffset",fa=ea,ga=!0,ha="",ia={},ja=32,ka=null,la=!1,ma="[iFrameSizer]",na=ma.length,oa="",pa={max:1,min:1,bodyScroll:1,documentElementScroll:1},qa="child",ra=!0,sa=a.parent,ta="*",ua=0,va=!1,wa=null,xa=16,ya=1,za="scroll",Aa=za,Ba=a,Ca=function(){h("MessageCallback function not defined")},Da=function(){},Ea=function(){},Fa=Date.now||function(){return(new Date).getTime()},Ga={bodyOffset:function(){return document.body.offsetHeight+G("marginTop")+G("marginBottom")},offset:function(){return Ga.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,J(Ga))},min:function(){return Math.min.apply(null,J(Ga))},grow:function(){return Ga.max()},lowestElement:function(){return Math.max(Ga.bodyOffset(),I("bottom",L()))},taggedElement:function(){return K("bottom","data-iframe-height")}},Ha={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max(Ha.bodyScroll(),Ha.documentElementScroll())},max:function(){return Math.max.apply(null,J(Ha))},min:function(){return Math.min.apply(null,J(Ha))},rightMostElement:function(){return I("right",L())},taggedElement:function(){return K("right","data-iframe-width")}},Ia=e(M);b(a,"message",S),T()}(window||{}); -//# sourceMappingURL=iframeResizer.contentWindow.map \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js b/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js deleted file mode 100644 index 853bbdd..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/api-doc/js/iframeResizer/iframeResizer.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! iFrame Resizer (iframeSizer.min.js ) - v3.5.3 - 2016-02-23 - * Desc: Force cross domain iframes to size to content. - * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame. - * Copyright: (c) 2016 David J. Bradshaw - dave@bradshaw.net - * License: MIT - */ -!function(a){"use strict";function b(b,c,d){"addEventListener"in a?b.addEventListener(c,d,!1):"attachEvent"in a&&b.attachEvent("on"+c,d)}function c(b,c,d){"removeEventListener"in a?b.removeEventListener(c,d,!1):"detachEvent"in a&&b.detachEvent("on"+c,d)}function d(){var b,c=["moz","webkit","o","ms"];for(b=0;be&&(e=c,h(W,"Set "+d+" to min value")),e>b&&(e=b,h(W,"Set "+d+" to max value")),V[d]=""+e}function k(){function a(){function a(){var a=0,d=!1;for(h(W,"Checking connection is from allowed list of origins: "+c);aP[w]["max"+a])throw new Error("Value for min"+a+" can not be greater than max"+a)}c("Height"),c("Width"),b("maxHeight"),b("minHeight"),b("maxWidth"),b("minWidth")}function e(){var a=c&&c.id||S.id+F++;return null!==document.getElementById(a)&&(a+=F++),a}function f(b){return R=b,""===b&&(a.id=b=e(),G=(c||{}).log,R=b,h(b,"Added missing iframe ID: "+b+" ("+a.src+")")),b}function g(){h(w,"IFrame scrolling "+(P[w].scrolling?"enabled":"disabled")+" for "+w),a.style.overflow=!1===P[w].scrolling?"hidden":"auto",a.scrolling=!1===P[w].scrolling?"no":"yes"}function i(){("number"==typeof P[w].bodyMargin||"0"===P[w].bodyMargin)&&(P[w].bodyMarginV1=P[w].bodyMargin,P[w].bodyMargin=""+P[w].bodyMargin+"px")}function k(){var b=P[w].firstRun,c=P[w].heightCalculationMethod in O;!b&&c&&r({iframe:a,height:0,width:0,type:"init"})}function l(){Function.prototype.bind&&(P[w].iframe.iFrameResizer={close:n.bind(null,P[w].iframe),resize:u.bind(null,"Window resize","resize",P[w].iframe),moveToAnchor:function(a){u("Move to anchor","inPageLink:"+a,P[w].iframe,w)},sendMessage:function(a){a=JSON.stringify(a),u("Send Message","message:"+a,P[w].iframe,w)}})}function m(c){function d(){u("iFrame.onload",c,a),k()}b(a,"load",d),u("init",c,a)}function o(a){if("object"!=typeof a)throw new TypeError("Options is not an object")}function p(a){for(var b in S)S.hasOwnProperty(b)&&(P[w][b]=a.hasOwnProperty(b)?a[b]:S[b])}function q(a){return""===a||"file://"===a?"*":a}function s(b){b=b||{},P[w]={firstRun:!0,iframe:a,remoteHost:a.src.split("/").slice(0,3).join("/")},o(b),p(b),P[w].targetOrigin=!0===P[w].checkOrigin?q(P[w].remoteHost):"*"}function t(){return w in P&&"iFrameResizer"in a}var w=f(a.id);t()?j(w,"Ignored iFrame, already setup."):(s(c),g(),d(),i(),m(v(w)),l())}function x(a,b){null===Q&&(Q=setTimeout(function(){Q=null,a()},b))}function y(){function b(){function a(a){function b(b){return"0px"===P[a].iframe.style[b]}function c(a){return null!==a.offsetParent}c(P[a].iframe)&&(b("height")||b("width"))&&u("Visibility change","resize",P[a].iframe,a)}for(var b in P)a(b)}function c(a){h("window","Mutation observed: "+a[0].target+" "+a[0].type),x(b,16)}function d(){var a=document.querySelector("body"),b={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0},d=new e(c);d.observe(a,b)}var e=a.MutationObserver||a.WebKitMutationObserver;e&&d()}function z(a){function b(){B("Window "+a,"resize")}h("window","Trigger event: "+a),x(b,16)}function A(){function a(){B("Tab Visable","resize")}"hidden"!==document.visibilityState&&(h("document","Trigger event: Visiblity change"),x(a,16))}function B(a,b){function c(a){return"parent"===P[a].resizeFrom&&P[a].autoResize&&!P[a].firstRun}for(var d in P)c(d)&&u(a,b,document.getElementById(d),d)}function C(){b(a,"message",l),b(a,"resize",function(){z("resize")}),b(document,"visibilitychange",A),b(document,"-webkit-visibilitychange",A),b(a,"focusin",function(){z("focus")}),b(a,"focus",function(){z("focus")})}function D(){function a(a,c){function d(){if(!c.tagName)throw new TypeError("Object is not a valid DOM element");if("IFRAME"!==c.tagName.toUpperCase())throw new TypeError("Expected - - - - - - - - - - - - - \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-en-US.properties b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-en-US.properties deleted file mode 100644 index 89acc60..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-en-US.properties +++ /dev/null @@ -1,168 +0,0 @@ -# -# Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. -# -# 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. -# -# Author: Zhaoxing Meng -# email: meng.zhaoxing1@zte.com.cn -# - -org_openo_msb_route_title=Open-O micro-services - -org_openo_msb_route_sideBar_serviceroute=Service Route -org_openo_msb_route_sideBar_servicediscover=Service Discover -org_openo_msb_route_sideBar_servicemng=Service Manage - -org_openo_msb_route_chinese_name= -org_openo_msb_route_english_name=MicroService Bus - -org_openo_msb_route_banner_title=MicroService Bus -org_openo_msb_route_btn_export=Service Export -org_openo_msb_route_tab_api=API Service -org_openo_msb_route_tab_iui=IUI Service -org_openo_msb_route_tab_custom=Custom Service -org_openo_msb_route_tab_msb=MSB Service -org_openo_msb_route_btn_add_api=Add API Service -org_openo_msb_route_form_sourceservice=Source Service -org_openo_msb_route_form_address=Host -org_openo_msb_route_form_host_tip=Add Host(format--IP:Port) -org_openo_msb_route_form_node_no=No -org_openo_msb_route_form_node_control=operate -org_openo_msb_route_form_url=URL -org_openo_msb_route_form_target_tip=Published as -org_openo_msb_route_form_target_service=Published URL -org_openo_msb_route_form_servicename=Name -org_openo_msb_route_form_version=Version -org_openo_msb_route_form_version_tip=format:v(lowercase) + digital -org_openo_msb_route_form_swagger=API Define -org_openo_msb_route_form_swagger_address=API Address -org_openo_msb_route_form_target_address= Target Address: -org_openo_msb_route_form_publish_address=Published Address: -org_openo_msb_route_form_metrics=Metrics Define -org_openo_msb_route_form_metrics_address=Metrics Address -org_openo_msb_route_form_btn_cancel=Cancel -org_openo_msb_route_form_btn_save=Save -org_openo_msb_route_form_btn_close=Close - -org_openo_msb_route_box_version=version: -org_openo_msb_route_box_btn_disable=Disable -org_openo_msb_route_box_btn_able=Enable -org_openo_msb_route_box_btn_delete=Delete -org_openo_msb_route_box_btn_update=Edit -org_openo_msb_route_form_btn_addhost=Add Host -org_openo_msb_route_form_btn_delhost=Delete Host -org_openo_msb_route_box_btn_view=View - -org_openo_msb_route_btn_add_iui=Add IUI Service -org_openo_msb_route_form_iui_tip=Target service registration at the same time corresponding Api service can be accessed through this address -org_openo_msb_route_btn_add_custom=Add Custom Service -org_openo_msb_route_btn_add_msb=Add MSB Service -org_openo_msb_route_form_protocol=Protocol -org_openo_msb_route_form_visualrange=VisualRange -org_openo_msb_route_form_intersystem=OutSystem -org_openo_msb_route_form_insystem=InSystem -org_openo_msb_route_form_msb_host=Host -org_openo_msb_route_form_ttl_tip=Add TTL - -org_openo_msb_route_servicecontent_swagger=Rest Interface -org_openo_msb_route_servicecontent_metrics=Metrics - -org_openo_msb_route_msb_info=Basic Information -org_openo_msb_route_msb_hostlist=Host List - -org_openo_msb_route_content_title=Service Detail -org_openo_msb_route_swagger_type_predefined=predeFined -org_openo_msb_route_swagger_type_custominput=customInput - - -//table -org_openo_msb_route-table-sLengthMenu=View _MENU_ records -org_openo_msb_route-table-sZeroRecords=No matching records found -org_openo_msb_route-table-sInfo=Found total _TOTAL_ records -org_openo_msb_route-table-sInfoEmpty=No records found to show -org_openo_msb_route-table-sGroupActions=_TOTAL_ records selected: -org_openo_msb_route-table-sAjaxRequestGeneralError=Could not complete request. Please check your internet connection. -org_openo_msb_route-table-sEmptyTable=No data available in table -org_openo_msb_route-table-sPrevious=Prev -org_openo_msb_route-table-sNext=Next -org_openo_msb_route-table-sPage=Page -org_openo_msb_route-table-sPageOf=of -org_openo_msb_route-table-search=Search: -org_openo_msb_route-table-infofilter=(Filter from _MAX_ Records) - -org_openo_msb_route_err_host_empty=The new Host cannot be empty -org_openo_msb_route_err_ttl_empty=The new TTL cannot be empty -org_openo_msb_route_err_host_format=Wrong Host format (format IP: port) -org_openo_msb_route_err_ttl_format=TTL can only for Numbers -org_openo_msb_route_err_host_repeat=The services (Host: {0}) has been in existence -org_openo_msb_route_err_host_del=Are you sure to delete [Host: {0}:{1}]? - -org_openo_msb_route_title_add_msb=Add MSB Service -org_openo_msb_route_title_edit_msb=Edit MSB Service -org_openo_msb_route_title_view_msb=View MSB Service -org_openo_msb_route_title_add_iui=Add IUI Service -org_openo_msb_route_title_edit_iui=Edit IUI Service -org_openo_msb_route_title_view_iui=View IUI Service -org_openo_msb_route_title_add_api=Add API Service -org_openo_msb_route_title_edit_api=Edit API Service -org_openo_msb_route_title_view_api=View API Service -org_openo_msb_route_title_add_custom=Add Custom Service -org_openo_msb_route_title_edit_custom=Edit Custom Service -org_openo_msb_route_title_view_custom=View Custom Service -org_openo_msb_route_err_service_repeat=Service(Name:{0}) has been published -org_openo_msb_route_err_api_repeat=Service(Name:{0}-Version:{1}) has been published -org_openo_msb_route_err_service_del_ask=Sure to delete[Name:{0} - Version:{1}]Service? -org_openo_msb_route_err_service2_del_ask=Sure to delete[Name:{0}]Service? -org_openo_msb_route_err_service_save=Service save failed: -org_openo_msb_route_service_save= - Save success -org_openo_msb_route_service_update= - Edit success -org_openo_msb_route_err_host_leastone=Please enter at least one HOST address -org_openo_msb_route_err_visualrange_empty= Please select the service visibleRange -org_openo_msb_route_status_enable=Enable service success -org_openo_msb_route_status_disable=Disable service success -org_openo_msb_route_err_status=Service status update failed: - -org_openo_msb_route_service_del_success= - Delete success -org_openo_msb_route_service_del_fail=Service delete failed: - -org_openo_msb_route_metric_content_title=Metrics Detail -org_openo_msb_route_iui_content_title=IUI Service Detail - -//Input efficacy suggested -org_openo_msb_route_validator_ip_format=Please fill in the correct IP -org_openo_msb_route_validator_url_head_format=url address Begin with /, cannot end with / -org_openo_msb_route_validator_url_head_only_format=url address Begin with/ -org_openo_msb_route_validator_url_format=The service URL format:ip:port/url -org_openo_msb_route_validator_url_line_format=Name cannot contain / -org_openo_msb_route_validator_content_format=Special symbols and Chinese name can not be filled in -org_openo_msb_route_validator_name_empty=Please enter the service name -org_openo_msb_route_validator_url_empty=Please enter the URL address -org_openo_msb_route_validator_server_empty=Please enter the Host address -org_openo_msb_route_validator_protocol_empty=Please select a service protocol -org_openo_msb_route_validator_type_empty=Please select a service type -org_openo_msb_route_validator_digits=Please enter an integer -org_openo_msb_route_validator_min=Not a negative - - -org_openo_msb_route_property_ttl=Tip: -org_openo_msb_route_property_root=Root Service -org_openo_msb_route_property_other_group=other -org_openo_msb_route_property_normal=normal -org_openo_msb_route_property_disable=disable -org_openo_msb_route_property_unknown=unknown - - - - - - diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-zh-CN.properties b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-zh-CN.properties deleted file mode 100644 index 391ac12..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/i18n/msb-iui-route-i18n-zh-CN.properties +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved. -# -# 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. -# -# Author: Zhaoxing Meng -# email: meng.zhaoxing1@zte.com.cn -# - -org_openo_msb_route_title=微服务 - -org_openo_msb_route_sideBar_serviceroute=服务路由 -org_openo_msb_route_sideBar_servicediscover=服务发现 -org_openo_msb_route_sideBar_servicemng=服务管理 - - -org_openo_msb_route_chinese_name=微服务 -org_openo_msb_route_english_name=MicroService Bus - -org_openo_msb_route_banner_title= —— 微服务 -org_openo_msb_route_btn_export=服务导出 -org_openo_msb_route_tab_api=API服务 -org_openo_msb_route_tab_iui=IUI服务 -org_openo_msb_route_tab_custom=自定义服务 -org_openo_msb_route_tab_msb=MSB服务 -org_openo_msb_route_btn_add_api=添加API服务 -org_openo_msb_route_form_sourceservice=源服务 -org_openo_msb_route_form_address=服务器地址 -org_openo_msb_route_form_host_tip=添加host地址(格式 IP:Port) -org_openo_msb_route_form_node_no=序号 -org_openo_msb_route_form_node_control=操作 -org_openo_msb_route_form_url=URL地址 -org_openo_msb_route_form_target_tip=发布为 -org_openo_msb_route_form_target_service=发布服务 -org_openo_msb_route_form_servicename=服务名 -org_openo_msb_route_form_version=版本号 -org_openo_msb_route_form_version_tip=格式:v(小写)+数字 -org_openo_msb_route_form_swagger=API定义 -org_openo_msb_route_form_swagger_address=API地址 -org_openo_msb_route_form_target_address=目标地址: -org_openo_msb_route_form_publish_address=发布地址: -org_openo_msb_route_form_metrics=性能指标定义 -org_openo_msb_route_form_metrics_address=性能指标地址 -org_openo_msb_route_form_btn_cancel=取消 -org_openo_msb_route_form_btn_save=保存 -org_openo_msb_route_form_btn_close=关闭 - -org_openo_msb_route_box_version=版本: -org_openo_msb_route_box_btn_disable=禁用 -org_openo_msb_route_box_btn_able=启用 -org_openo_msb_route_box_btn_delete=删除 -org_openo_msb_route_box_btn_update=修改 -org_openo_msb_route_form_btn_addhost=添加Host -org_openo_msb_route_form_btn_delhost=删除Host -org_openo_msb_route_box_btn_view=查看 - -org_openo_msb_route_btn_add_iui=添加IUI服务 -org_openo_msb_route_form_iui_tip=目标服务同时注册对应Api服务才能通过此地址访问 -org_openo_msb_route_btn_add_custom=添加自定义服务 -org_openo_msb_route_btn_add_msb=添加MSB服务 -org_openo_msb_route_form_protocol=服务协议 -org_openo_msb_route_form_visualrange=服务可见范围 -org_openo_msb_route_form_intersystem=系统间 -org_openo_msb_route_form_insystem=系统内 -org_openo_msb_route_form_msb_host=服务HOST -org_openo_msb_route_form_ttl_tip=添加TTL数字 - -org_openo_msb_route_servicecontent_swagger=接口 -org_openo_msb_route_servicecontent_metrics=性能 - -org_openo_msb_route_msb_info=基本信息 -org_openo_msb_route_msb_hostlist=服务实例列表 - -org_openo_msb_route_content_title=微服务详情 -org_openo_msb_route_swagger_type_predefined=预定义选择 -org_openo_msb_route_swagger_type_custominput=自定义输入 - - -//表格相关 -org_openo_msb_route-table-sLengthMenu=每页 _MENU_ 条结果 -org_openo_msb_route-table-sZeroRecords=没有匹配结果 -org_openo_msb_route-table-sInfo=总共找到 _TOTAL_ 条结果 -org_openo_msb_route-table-sInfoEmpty=共 0 项 -org_openo_msb_route-table-sGroupActions=_TOTAL_ 条结果被选择: -org_openo_msb_route-table-sAjaxRequestGeneralError=不能完成请求,请检查您的网络连接情况。 -org_openo_msb_route-table-sEmptyTable=表中数据为空 -org_openo_msb_route-table-sPrevious=前页 -org_openo_msb_route-table-sNext=下页 -org_openo_msb_route-table-sPage=第 -org_openo_msb_route-table-sPageOf=页,总页数: -org_openo_msb_route-table-search=搜索: -org_openo_msb_route-table-infofilter=(从 _MAX_ 条记录过滤) - -org_openo_msb_route_err_host_empty=新增HOST不能为空 -org_openo_msb_route_err_ttl_empty=新增HOST的TTL不能为空 -org_openo_msb_route_err_host_format=HOST格式有误(格式 ip:port) -org_openo_msb_route_err_ttl_format=TTL只能为数字 -org_openo_msb_route_err_host_repeat=服务(HOST:{0})已存在 -org_openo_msb_route_err_host_del=确定删除[HOST:{0}:{1}]? - -org_openo_msb_route_title_add_msb=添加MSB服务实例 -org_openo_msb_route_title_edit_msb=修改MSB服务实例 -org_openo_msb_route_title_view_msb=查看MSB服务实例 -org_openo_msb_route_title_add_iui=添加IUI服务实例 -org_openo_msb_route_title_edit_iui=修改IUI服务实例 -org_openo_msb_route_title_view_iui=查看IUI服务实例 -org_openo_msb_route_title_add_api=添加API服务实例 -org_openo_msb_route_title_edit_api=修改API服务实例 -org_openo_msb_route_title_view_api=查看API服务实例 -org_openo_msb_route_title_add_custom=添加自定义服务实例 -org_openo_msb_route_title_edit_custom=修改自定义服务实例 -org_openo_msb_route_title_view_custom=查看自定义服务实例 -org_openo_msb_route_err_service_repeat=服务(服务名:{0})已发布 -org_openo_msb_route_err_api_repeat=服务(服务名:{0}-版本号:{1})已发布 -org_openo_msb_route_err_service_del_ask=确定删除[服务名:{0} - 版本号:{1}]服务? -org_openo_msb_route_err_service2_del_ask=确定删除[服务名:{0}]服务? -org_openo_msb_route_err_service_save=服务保存失败: -org_openo_msb_route_service_save=保存成功 -org_openo_msb_route_service_update=修改成功 -org_openo_msb_route_err_host_leastone=请至少输入一个HOST地址 -org_openo_msb_route_err_visualrange_empty=请选择服务可见范围 -org_openo_msb_route_status_enable=激活成功 -org_openo_msb_route_status_disable=禁用成功 -org_openo_msb_route_err_status=服务状态操作失败: - -org_openo_msb_route_service_del_success=删除成功 -org_openo_msb_route_service_del_fail=服务删除失败: - -org_openo_msb_route_metric_content_title=性能详情 -org_openo_msb_route_iui_content_title=IUI服务详情 - -//输入效验提示 -org_openo_msb_route_validator_ip_format=请填写正确的IP地址 -org_openo_msb_route_validator_url_head_format=url地址以/开头,不能以/结尾 -org_openo_msb_route_validator_url_head_only_format=url地址以/开头 -org_openo_msb_route_validator_url_format=服务地址格式:ip:port/url -org_openo_msb_route_validator_url_line_format=名称不能包含/ -org_openo_msb_route_validator_content_format=名称不能输入特殊符号和中文 -org_openo_msb_route_validator_name_empty=请输入服务名 -org_openo_msb_route_validator_url_empty=请输入URL地址 -org_openo_msb_route_validator_server_empty=请输入服务器地址 -org_openo_msb_route_validator_protocol_empty=请选择服务协议 -org_openo_msb_route_validator_type_empty=请选择服务类型 -org_openo_msb_route_validator_digits=请输入整数 -org_openo_msb_route_validator_min=不能为负数 - - -org_openo_msb_route_property_ttl=提示: -org_openo_msb_route_property_root=根服务 -org_openo_msb_route_property_other_group=其他 -org_openo_msb_route_property_normal=正常 -org_openo_msb_route_property_disable=停用 -org_openo_msb_route_property_unknown=未知 \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/conductor-logo.png b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/conductor-logo.png deleted file mode 100644 index d4476b2b9ad1bfff83792d82adf98d2a75c02a1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4907 zcmV+`6V&X9P)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z2v|u(K~#9!?3;VAS5+0qKlgHZ1qkw<6jGi-DHj65QA(3g8q20krfhJuU}{9b5+}7X z#A?#9ND+-BjL}Ie0Y?}yEkTfUP(qZTC>jJ(Fdy-Lc=`6n@B5qCoH^(G&hK}Bm$}0E z&g?no?7i3C=j^@q+H0-7PK_jT;_r^-GP3Tz&_{ocHIF$N8m896?g?$Z~X`0 zJYXhpVWgi$X0RjqR5epbDmR@bX{(OKvy%D-b;e0rDrv8h@r0zYl3JLig``_!>dmg; z9rJXYQn>^*lAerA@Ipy#UEWvHq7rm5HALvH$S3Q>V4!Ov z6T4he8<&lcv@L~s-mqlK($C}w?RH6B@(KH3GteoLUJoX9r=(sk8(;=W!dsGtmiclE zB5mB3PgwIytRK^yPw~(gYun>^dA961NA^# z;0<7C^qGM6 z%g*~!3T+3g0<8kN>rHpRuaDYTNn)U_lAf=Cc_#R~-#4S2?Q!Ym@m?J0wVkTXKvRNA zJRqr$^GB7CK6@nn&Z{npHzobt%6Fa9cu9vP-5K=#L_l*e;x34$q6K(eN}WEEUh|3@ z8pA-l0tuLu&ap-LPz(c&EpuXv3^Y*EZz2n{S`0MO%=0fv!!peCqt#}h`4K5lG`**) z@i^)UeKp8i5%hgSr2eG|?|8Axf0p5U`kASpNnoJ1CFtv1@5LAf8do6$4f4w0=B;H& zl^Cc-(sSNE`)8;>%kOhxmiB8is!IKX`%Qro+OHbkaNwiB$AY}xR(y#G^*A%3ok{k9 z|0qMB{{-#@E&>Kt@Xnp>S>IVjpKe>=JuBihzg3Nvje zOv=(}Rt7pJxPK=ykWGPh6yl1CMmB8B>`&jI2eHn~i1Dp!nW9##w67_2X zx|$#_$vOl0iz6F``an4gTKHUYCWRQR-a*;0;8-XN-nNA}Dr+c47To34P-7D|Ts2LB z!#hANZYylkbq?TIITO8LE$3R(pS(6;iFwasX?LF(gh(2pcyg4FK0J>(}!tglm zsU`y@A#13`N}tmI4d?(|<^gJ%P=8&ZXLV1I93hTa^j~bo$TC4+@O5p5y8i*LDRXQd zajFzMJVpzFS-@2(@liE)My>}oMxqy9_VqH4QI>^uzMYy?(}9xEGDDp^feV0N11|ti z1Cy;R9!j7IU;gY!*}oHL=9)Qg$?#77fb0A&n`ypS1l$iyus6RULF%uxCz+VgmyN&* ze{cT`eSY6M=-lJMKEASVCsz#oI>3xfLtmSS;u+Q%i|_F$zk&tgm8 z=}j={4OMRM23x+rv;}&g+`|UoJKo}!SvgO_RA3tLTQgmgGEfbLsKPWw_~sIAER4y! zH5jDgc@}|5|9VP$6TKSm29{WCf7mAOU@Nw3?Kb!tg}}C^uprY?`;3x1)W5E>vOm|f z<^Fi^vfJnbtg)+Oh{vTTaEZrj7Vs?a&87?}3j@pcq&NtdWoYBP2+hNh@@RnBv#1=LuLmR__`=!7)g6Ceql;C+g@Ib~DdoA!23Zb&~UisT8{D-zW zMH!vz_oyURuvvY*mRvPaKH0#r5wC0@I4=u?kM&^K_h3B|1=h3V&TB`CQ)h9-5|1cD01s0el|# zR>UQ66Y$00`5(Z2+Duu(QqWO~8x5n~mV(u@wGB9TCZY zz@~YQ6JQIgHqHRXQ223hOicM~Z)f@M&CM8f$FZ*g_7HcoH+W!z8(^=M=-K)7&b3PDY~DTIP^+M&7MmKHR_?6a|J{9q(J=h#u&vc*C^KAq z=i=vIeBNYgTDiM&|H1teub+7E-~oE>AD{nbrpE2g+#Zu27ak@f5#Sen9%6JV;vk9h zk2wDgM4r+3_Wh!D^O#j~@18xrB2eukKo!`vkZ?K*{iMpb)Q)|b<-LMgzj$AUuh5cm zalGz3jb&6Zz--#9HC~nT>ORW+W?}k$_VSeFV=Q60IhB@*w@7h>Z7OLKYpK+-9+8$| z9TMS3Xbg5nn|n-1%}@i9lpn04RBb65tSe%4Q+DRRA(iXItW=c#_U`N>FTb020w)k~ zwxaoJn0z4i(K8};|}(*J_vcbByJ z^@LCEe9Kz&`en{l;q;Eu*8REFI12vpZOxxIEOHsh`j;0IPyk{#N!ch6728B^2Wi>e zqC#4db+A38VNkG@L9gnrL7|HLCcd#kP&iP1)=tgJd70nakn6;wA{jd{88fSaP1xR| zWG$$|6_F7hgxmx_2H9hnM_*hOkZ=tnFe2Cy)N^s}BG?g#JdFt$UA=Y{7_FLeVr;?% z2-J4{XV=%kL_WRj*Eg8KNsQh7l44HGO$SE1&GUDzEcIBgRC*(}%*v7B_v3jBj(D{l z-)8>ugX5dIzuM)vyZmjw?`@6F*v(g3er4D%L97S))kxAqZIp3=5TRA758BhELws|e z$QFX|!!+DffvUQQ%Fr@HBQ293rtfV$(<#g?YLN2I)QewIrbK7#&K7S~Qwap>aV6`L z)Jcf1HTt#igC#!^K9P{e8a%G30xFL!Hst(hfH85>iNWPEP}I{#12AV#pIrxxE6vC! zHGX|G=x4lY%ekE-$f&e(LXTdeU<*r>j^sGZsflf?agUYdAm^OL`0S zQz@NH#e$BNm%Ncfb;vb;q72`{G}Hh2L(Ej8(6#Dq?NS<%Ywi+bO^vL6k6c8pLa%g@ zl%Wduyc**nRdJhXGAEvJKp(DP<&l#S@r0D*?xYjJ#RxmN>N)95WaJ)GB{eWuGQO%D z{`a8)F7V~+qj?@KK!-fx4QQ;MDSGd}MYBwa)x?H0>+(tS2`6L8Ko^b6c7~R_Tg&m{O>IF zsOMHK1+sBf-Kwj;$5Lm&QW-ONR;k#h^>g^vu z!H733qS{TIW5O;;twSI%Bp-AL^?mhWmD_srq6V;NS$twjiAS29CBL2j=f z&g5xt|GpbBp7wA~hhk38%?Ca?1M_!oEcJF?;XJ&Fk#iT)8(EsJh4GTyt37=$xF4=q z+;Cg{^O?3TLJ|G<+Mr9^Pm_L|-uTX5>+Mlu>F1+72xeA`jD-SA+od`oqq|3>VU$`J5$2YSG1lBgr z={#rf2=Vic6ru2VX!Mid;jMw>%4JvTK&!i~wHi5q2iSmoT-^=`0o(UR&g0;jT!vz= z=6{&s#gWf_$&&yi=AY(8W6NZ^)#u?&KFxD1eIrfdzTn7Cu>Vv13u(g|uiC@v-kG*~ zf`x90NEqJR|MeZt8(V%Ojrlp2ZvHlBTL9vkA7yhd%e3wMxQc?lTvDB<5@4oH**Puuo-fKlMY8roQ!s9Tp7Wd=47OAi zo?9AomyDYgnJZIAFx|t-6C;u|;pdoS5jjFNf7A3aS@OlI+5VwAI`s@4EiwM8qeHYB z=@T9O;b)s;Ny=-2TV%{1yX`GEZ8_P!bHcy$3Z~?#wO{=?6>*y%iAZM^Yl1rM-6+`7 zFKP>E90m$yYPV zKfcQ@qms?LzVh)!jAV9mv~wWtYm*iW=-M7>K`;W7b%ZpI2x;3G)I%e+K*)X1D;^cu z1+3HMnr<2+u{pd@F2{|4Cy$4?YyyF8-nkHs4@5>p%^3a30s(pS(zHQDz0N~n1Ek0;(g$oEzZB^bp8t z6C(t{yNM3L5=@|Q%U#;>3mKG&#}nwAximgxG{q#NATrsF+9uVrdZYUX+dGHFW<>Mj zx(`B!8JbJ*N>ypG>5c5%JrKnj$Y;`2_O8sV*$gF+;ixYt{_v zS9!U(0Eo2}_Vj9gPBi3GFb%OGeoCe0qU*a9?|go}a7BlQBzJc}Ys*Ycf)W&3RK$T%)-FG{bhA&i9A)^AZ0En}4XM zPC@86J@vQia127nDwg@cI(&3+6*||UFPYmH(9fNe&x&MeE0g4F_eN$#`*UyTq0vX? zwVkx(-IuPoft%b+(t;pso4CLuo@y8IEKI~15H?7ZM0*va4X)Gk4^V^!UA1r6AcU;r zqWr==aBex5;VG&6G>U7f>592OY$sHwWG)ac9mZrsYRAH)oHqTzJ(*cfp1rL5dgMVJVZ-))AB5+B zmLtHY)g{E@I{J^*+}XSTp>+81FFky7G7xQOkUOt#wRebK=9|pD0&7V9;U>65 zEw7-^(y~L;@&tWx!zmFpu4pV(pC`slh)9|ekkV}lQs%jB>{vEONz9(!6rtRlucg+K z`2!64N2`a$v*O12ZgzJC+yoCiuJ;~jDo7j`7`P{(#K3g$h5@EqpNeY`I{WH0#Lal6 zm(9ncNVVlkCsMpX?pOISW;)x{Xlycwdk(YQs#w4j#EgFnBoep%TCC1o@&EkHn;ve- z4361bB?xs4cGv_54pS6egypy1wo{UDQz*QMQFS(PKBudsTa+J&tb@Gvpr)f)D7bpC z4u$MLU~{jK6x%l0U&}Fs<`wK!C6$q8c%<|WcKLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z2v|u(K~#9!?3;VAS5+0qKlgHZ1qkw<6jGi-DHj65QA(3g8q20krfhJuU}{9b5+}7X z#A?#9ND+-BjL}Ie0Y?}yEkTfUP(qZTC>jJ(Fdy-Lc=`6n@B5qCoH^(G&hK}Bm$}0E z&g?no?7i3C=j^@q+H0-7PK_jT;_r^-GP3Tz&_{ocHIF$N8m896?g?$Z~X`0 zJYXhpVWgi$X0RjqR5epbDmR@bX{(OKvy%D-b;e0rDrv8h@r0zYl3JLig``_!>dmg; z9rJXYQn>^*lAerA@Ipy#UEWvHq7rm5HALvH$S3Q>V4!Ov z6T4he8<&lcv@L~s-mqlK($C}w?RH6B@(KH3GteoLUJoX9r=(sk8(;=W!dsGtmiclE zB5mB3PgwIytRK^yPw~(gYun>^dA961NA^# z;0<7C^qGM6 z%g*~!3T+3g0<8kN>rHpRuaDYTNn)U_lAf=Cc_#R~-#4S2?Q!Ym@m?J0wVkTXKvRNA zJRqr$^GB7CK6@nn&Z{npHzobt%6Fa9cu9vP-5K=#L_l*e;x34$q6K(eN}WEEUh|3@ z8pA-l0tuLu&ap-LPz(c&EpuXv3^Y*EZz2n{S`0MO%=0fv!!peCqt#}h`4K5lG`**) z@i^)UeKp8i5%hgSr2eG|?|8Axf0p5U`kASpNnoJ1CFtv1@5LAf8do6$4f4w0=B;H& zl^Cc-(sSNE`)8;>%kOhxmiB8is!IKX`%Qro+OHbkaNwiB$AY}xR(y#G^*A%3ok{k9 z|0qMB{{-#@E&>Kt@Xnp>S>IVjpKe>=JuBihzg3Nvje zOv=(}Rt7pJxPK=ykWGPh6yl1CMmB8B>`&jI2eHn~i1Dp!nW9##w67_2X zx|$#_$vOl0iz6F``an4gTKHUYCWRQR-a*;0;8-XN-nNA}Dr+c47To34P-7D|Ts2LB z!#hANZYylkbq?TIITO8LE$3R(pS(6;iFwasX?LF(gh(2pcyg4FK0J>(}!tglm zsU`y@A#13`N}tmI4d?(|<^gJ%P=8&ZXLV1I93hTa^j~bo$TC4+@O5p5y8i*LDRXQd zajFzMJVpzFS-@2(@liE)My>}oMxqy9_VqH4QI>^uzMYy?(}9xEGDDp^feV0N11|ti z1Cy;R9!j7IU;gY!*}oHL=9)Qg$?#77fb0A&n`ypS1l$iyus6RULF%uxCz+VgmyN&* ze{cT`eSY6M=-lJMKEASVCsz#oI>3xfLtmSS;u+Q%i|_F$zk&tgm8 z=}j={4OMRM23x+rv;}&g+`|UoJKo}!SvgO_RA3tLTQgmgGEfbLsKPWw_~sIAER4y! zH5jDgc@}|5|9VP$6TKSm29{WCf7mAOU@Nw3?Kb!tg}}C^uprY?`;3x1)W5E>vOm|f z<^Fi^vfJnbtg)+Oh{vTTaEZrj7Vs?a&87?}3j@pcq&NtdWoYBP2+hNh@@RnBv#1=LuLmR__`=!7)g6Ceql;C+g@Ib~DdoA!23Zb&~UisT8{D-zW zMH!vz_oyURuvvY*mRvPaKH0#r5wC0@I4=u?kM&^K_h3B|1=h3V&TB`CQ)h9-5|1cD01s0el|# zR>UQ66Y$00`5(Z2+Duu(QqWO~8x5n~mV(u@wGB9TCZY zz@~YQ6JQIgHqHRXQ223hOicM~Z)f@M&CM8f$FZ*g_7HcoH+W!z8(^=M=-K)7&b3PDY~DTIPKLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z3p7bYK~#9!?3{U!71bHVe{aBH5g0&_RU?QSZj~4njcYV2iBTa&jj>A2qNTyOluIS1 zOxzP!5|fIgj9PBdiZPlPNfa%uD8z`-xF9N`0s;fb4C^q!%*h|`bj`Kxe%rj6kxZYe zu6gtN?)}~Go_oIAFDHo%8M+f{vLVQj8GVKfnbBv+kQx1!imw5$00(7{Ju~|5g1*2I zpe}pt-5Wi-QD0kt4M1}Tl-&au59|)i1zvZ38MZ*9-x?@K(_9}byH^?cTVe*;2gnu4 zlLIyan@X%BS3;TPVia%(aHRX(0?Y!w2`tS_Y|AnF!N66(VWvPT(V#v6&H)Aiw*Vtc z^msX-6?hD|9QXn7J)pP0FO+XHFcrA73&yWE@DT8&nAblD_y=$`&;&dStn0$(+{-Ib zE$|M|(5huTuL|m|)-^%WYDt?Uo!^D+_)J`B8`&l8Sep9*|EZAE=79dD zHszqUf;^>q$nOIG@^u?b+c0W@>81j4-u;2oC2b&EfO}K!w+F+4yMd#F z?;3z>fcxCfGs>9EM+5hF(R1DyP}JrwYQqrVY&(GObm@Ml9m_-#1-e~QE+zeLrY{ke zO4=hK-8e~WgLEq;?OugttsHtYSkj9@8=55jEokq=3aQ(KE?Ux$k+j+ExU!4daINca zku>_VNN-A+wHGCLkWT5rb4Q8 zNEi9G&q6$AM8F1CZ;3knMW!nu-MI)@Tx8(G!QaZ1rj#~r)rn)WA8?vKuLHggyc|pO z81R!a`SEJtsUrQ{2^av(0oDLxfr+Mt^MNOdjBzcnuhpYE;5Fdyb{t9QW13py_(GDx zG}aV%L4mr50S5wm`B}{aW?Cs42#ofgBBFYGn<~~g&4yTcqwOGe_5X8$f4kfy>Npk{ z>M>g8b{yzB9;ybtIWR^)BmH(dUMrYBRX+hmL6i7E- z(le44Ncu3iK5#wr-1dc%UXt`xNqr<;C+Us^HD`NCOI+_Ik}kB`5~4xUDJkt4BWacu zqYxijvDuhFZ%&ZZ?0P1rs8(+|-+c-9dr7)E_FN;ZcAxGkqHY}$l-JMc*CwQ0Z~8nq zVcZru&9#z#9Q0L5V^yxF?+^SUn6-HJU+v9mM_}tBT79+En#26L3An33+Bv2?gJP7d z#a_0jH;_#Z+BE_f13z-Qp}?e|Z@um10nYbE8sH<3`v7~*JAwZKZv}PkV9z={2og3p z{r0A7JyKMiXtk|NSqX**l$O{^{kVg2(Q3cke@8g)_>@&z_Rt^G7SQYuybv&mjlc@G zZ-~n~8yE*1AFN6P1A*ilUM*_^O5JX*cNU*KuqEJH@&~y(3d6`pI3F>sh^{Aq-}`}A z3xjNo01It!h0x?lza)@(Z#J!X9yr+d8=d|+FTq$H`+kffMl$ax;C)~p@<$uSS`mv3 z@$%U6es^G;_W(NsdwB10hYda{61~~aP$`b3HE?Eer*>Ol@Gk=g0K3`H53pS<2F`Oo z9u3Ml0+;|C3cMQhAu{;C+IV*dcJWv(^t~g1DX~68#=VOt(y^vTC$(3-+1o*&5Yr`X zU1I)9=}j@bDXFeX^k%%IH7<9Sq`qZRs4oOd>mo@bi>Ooc0<~+LDS_OE5wU#3B&`bi z9DRSNDT)dN!5$07E2KAPnqss{Iz1uZP)W<3@A23;MSXbNG$?62LM884PQOvoz*xGy zf^nOjq5$q6sDJY%)dp>ezHgRvShdufTF>0Nn5uGR7l+pYwga~5C`Gr-^pk?+{AVc} zzj?q*{yfrG=(TYmY)LF%eX#O`^m1ZAQLazX;qR$3MVuJ4;g$kwjAB$Nw5JfKdE5m2 zCS}~;1ZD?H&~6Eg2bYW^Bxsvk~gV6{2y+urTJW8--ZxG-4y+KW{I#TZEW zhttLeT=LZd>0S$X@y-eN7ZezWxau~}e>a%xCt+a~jXoF1xlO=}RVZ_(fU2bRVQnyO zwK3T^vg7xwC0XtOTo?Q96?3}Iz#4B*UW^%GO@j8{UM%wlu+AI6Aq5ODZ6izx?OGQY zQ13FHi&9qMsLoC8aBeE`yB^;AM0KvI!noH4BEZH1>DC70Rufwtqe)nmpv5&YJ-W%7 zd}AjW{c>*#*VxlVS7QfIt4&rxApg?IS!L#L42*wpfpnvSjp9cYwlx=1C~8wCP^7#h zJ?oYdY$2Dhxm^_~PQ$7|8`lSY7*wDgLxUAzc?oT;$ml1T+QfJ5&(e9QiE-GD#;*fI zx`0mx;fi5y;0=#1@bD%CbY)&U+dDrnm_t+29GCK}SK5ek0W}LT#!_P3=w}CY9#i3D z4e>_stWQYE*ALj=pBsWURAf+T7!KSJYvk+Jd^;PR`QtpZfIkHr#-}~`lhD@&wXgrb zm$tL&=UGCF@k{Qp#8qOz`9Rw5EOq$x-ts1FCVZ z>qwG+>k^(}jj3aZ2ZM1qD;UoZC({<8eWX+>Q!b~!GzO|FxRh=56Uj%v;ssCk#eA7yp-Ng{;*lC4I_!_Y>w4^y*cz0d%8;!@_b1C zEdKJ?_-z&25XaFw;eLxJ>C-m)ai(Yynt=!G?Q3FrH`uv7L_XqsBy9mFJXv?~1n!gI z6o&w(IPVXAh3yKx@gF@2MtWsy20vd7ZisYns< z7ghM?Q?t)M)FhO-YY=>if*QjU((UAP7D?wc(#~(pP6&8Z>&>adCH+CtyOKV3fNq7P z_a!~$piWYN?kGt!BrSGOsljF3DrrbU`fYsfWOhoR2uYVonknhFgfSi@=`NqOX>?m( zcCe<_0jim9SG?SV9oVXOTNg^2>U+O*IcKM|>DvzEEp^@%4xU{a1dzf2(<}$PK9=;H zq*1XnCrWxg7`K%^|8u?1F2(B~>0{qdOFF5PXPQg-Ez4Fae}Vd4@}cN>*m|V3>u3i) zhx|#nRSC+*9NNyIl#0Cr9XAP+y+=8R!lxb6(8GP`V-LBaL_S_;3e;?+W)mHYes1Tw z3Y4MY9`{8R>@|jYMQAk5D}?PzP_DN1zF-|yK3bkeZ|?Il*S`!to%6DDE6J}4E+!wP zyu$S7#sq`M196i#f_*9c+F|rU`Sd`=D6}_d&#xi0P+1UcRZ2fQ3Tw@gE5TAKf1|0s z1Y?g-$~Z2oGG%QungYLC9L=JVS1DgS{daE8QZ8RIlgZ5YedjypWC)`i z5&s%=Htz+c6fk%k1g`;jhG^3WLWluw7=lwq>+ggr4lQ{Z3{M<|J%bvfQC&6|KtHwl zBfO&Cp+a)y@RN$O6HIE#g?fupKIpLEAq(QyMpkRU?FAejWQ3BV%#fG0s{DNGvDCq- zwsmf4bxn)y9th1W98L|6Rq7_@-sjBsb~sSq686{cuE?b_>wLHi$(r_$eKhojkj3r` z+c)%#KihGjR2%CN0ry4WVpTC28^|}rey_W9^?O!a3kP6^)uBQN9{ zlX>`pFWo7w1|cB?qrLVNK_KKo$zHN^-=tCE>DQToKJ;JE3j#Fix^g{k(Ar?&9v2i~Lsn*`M z+kc>}&C&_qxi@-A7w0{#6|H7aB1L9=L#p6eCyCPJezEW_V!5ypj=LG716xoo87Rk8_4;1F!L!~l~fBu5$KXwlDxe>#dz)1f` ztFz_SU?|mA@@7u($t{~eZjJ%bMArlK<+E0_lejtzbNUyMO)so9wG9zEo7vrXX7th; zcYPl$0Z$gb;sh*=b?F1p`jxv5{AbrN3sjgxBM}fX%OkpFY?h?bGD9%je_QXWE^zcf@nqHYL4Z zr{~Y_7qSG~042MASmACh^96u`KHyBRl{gTL>-g8c%hR2bnMZ^}?U3H*_78j@RH-8L zN`nVM?T4Jt!JPW>o|TS*+9)_t#+WaqEFMwX8(MjyR%(j>1sDKNshL-%cY81Z0000< KMNUMnLSTXg*wqC9 diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/throbber.gif b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/img/throbber.gif deleted file mode 100644 index 06393889242fb3ea9e0205fa84369ec7bb66d15a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9257 zcmd^^X;@R|x`tQg5wbE8AV3mAn1TjmQ&en2CK8~ENEH<+P_)pZ24y2E+7O0>K^a6u zQ3;5MiU^7p6*M3qDk!2=YEcHMQ>nzEYP;R`e2C@r+U+?#XaC*&gKPcB#k$`o&;7mu zYNhYYXe|Uo84#4ZIko#rcU5K8*yFL{qT47O&^5fZH$ zVZ@%(l~vVHjnm;H@KL8@r%yUHoo;rbHI_4lIH(_nsTT>S2`DFOD~uCb9_dF4`#QgI zy7ldMcLs+A_s%|e1pRPrbX-tpeNP!9(IpMFTce`t_5U%lP99z%&i6`1d~ zWeM!Rxc50<+d$e^9LT`?B+aMK~apR zHm?q;p<7{wN2g|I^aGlSws;VP84j(z%aQwvAWv83Z$}p(% zZ^?2;gxg(ey_`V5J7{;!o;o;KslW@z5EP~JGs|U)J7dF&(ff#A=6vU?cGQ$-4+;Jf z-ggJEa!yStn`_EWvl)#yhm6XVs}UUbsi;+agri;mCfjH^Uy;lH+Zw^h)4N?oZgZz4 zJk(fTZ|Bi^;+s_M=~+d#vyoxEPzTlOS=mX@sbl*uRj>=MaMr}cFIY8i?UM61>86uB zV$DlOUCiUJwbzJMP@D$urzK|lL2-PC!p1l47V-ZG<5Ev0Z5h~Kx?`KOp7gkAjV93A z-Gc7MrlxTf?wF;CbNc@tCHJH{TB3c;#{SVu%97}tyAM2n&|9W_?qv}$*Jt*%7Yxb# zV0;d;7|lDEltJYS+U)#aiJO};?_Jyy_4%syQ(uy?-J-Yx-9O5nKRk@@XSS~X<(2u~ zV-LamWm~!iqtH9wkpf8mAXZhOD&L#aA_%)4h2M;1M5jt zIR>Us+%W-GXa_f^opKg=DSrAs)AXeRa;Hp0aC1OgbxQ%Qr_QvTleM1jkR!2mkcX$3 ztsR8~G9iqh(-FJ@F_rQBIYDXV_6s7G9SxaVF^laZqcx$!D97m|7t16j6@Jt6UdDRy49Qyvs|c>RuA|@b%}`*wU}2^7q;&Vtc6@lb zcXl)T!6nYDzmMJ~%n$KNXyNlCG)GkJ4!82;v6@d3>s5r~E+3!O?049JDr14Y^PeMI02R`0lJ^=oJ zYd|*u9|SU(j7hY?+<=(?fP*mtV*zFhOrz6%{VA?ozdm&(Jf^V zMfPZ?>l`mS3{Uq8IM;e!+1YjJy2!mzK$O|wPeU{*QSbs9m+@`f5KxO3PBnQ=%RsZg%go*fJ`*w9TL{-WgZVIA$!YV}3BRcfeXaR$x#b zW)Tpd#8E4)^MyYdkH;4_;ChJuw%n+Be7Ko4;w-nHvyo$d_0e-YiF78Df&)_)(}fcr_r0mPH(4RRYWIu+d@t0&Ss@O^s! zOKyX&13)%N@83r^;QsgN{rl(!0|RF1FA)b1{CRXAy&1ySz@>olPiR4r$aMdq&_=nK zq|cFs8phWJ1@%dZ-gXd{zDbTILD>)qEvH-NU*Rf1b2J1Ri79`rBFl@ z8E^0I)OqEi{pH(a24b9YPG;Kz@t-qZW;3Mpe`MRlmYx{7bH-XZ&`RQ7Rb^%}gc&X| zd}Q-FZf|RWxHU?PR!(C?80zu(^l>*h{#ulSiid(O!J(8P-41bNM3tnX@U6NS5yo0? zdcF)~xFE&+&|gZ$23dV5t~?$$&ymZ;F8j7GGMncGSsDo%>J`26=&l=X#rSKv_64;0 zr;k6no@=gV`P)K!=kaHl>q?!`X>(A;84tg^Md<`zA%qbRLby1Z=fn*ZRdNqs%Tq|3 zOt}lZu0q9oKJhgz&+^7PCt$=UFW=R*w?a1)ePoL*`R$Gxj?TU@12tTHsT$giHQU+sqf;fS0FpT!< z z#UR4L_rT;lfRLVo8|3$7cmuxwjY5rmYs&kR6z_LRhf9-=4QalKQYEWw^4-EBI3j$& zA>$Im_{ZA>0`)E_&m%x6a)BThkx=e|aMkOrK9zb1YzqpQ&WZ^$)2T>CwTCuYRn5y) z3fVXg-@R5&Bf4?WUTyD|hBDe2>xEh|o-y}o5Se~+Ob!5xN>CaAN!<4)F zwNh!Y7B?@AigokFYNJL`0Vz&-ekrY95-n3M<%GR<;SzXRmO7(zd+gf|$Thb%;pby2 zyd{5TJ?|JYUgpSlJ0=LB@k6#d&opuPGq^qJAIumfhigC2qAX0OEnYnT@O;bA?X1O5 zpLe9|%_H+Yki!Rv$7Kvjv8r7Z?$<>G)g*%D*V#s&kz>Z3V1 z3!ZKh9H8Nl9IdhEW_rY#oYdDCLTe+nQ{(d2pBX8%CmxL+1`|b#Vb!?IY!kT7$PDWAP9$FY=e9KSK{DEH|408! zl-$lv)U8$EB{~es&j>rYg%{{JRvIl8@NK}L=xDAEVv(o#W@3LUDc*m?yKSPR0O|nY zAh;*QuBdpja8HzP8Uw`ce-r*LrUA47ZvZ)ff3k4^>;dFcof}9eXeeM<0OVj&CKDVK zpUKKIF%hSmry!pwK68UX>zOF@dv}B4Gg)^2GQmN7@A?zG!xO6dT*Cq0+r{eY6}AfU zf`|~y!?^R*nB0!iTcg|CgM}ou^H*s~5)%h;Xh;PYOM!|Yhfk$w;@`1Dx1y!EZrM&^zMat!^Wz# z=Z{;Pa0w21oA1X3*9=`*c7o3ePa^k%Vzu>2C_7DaZJ8FW5GJv|t>`Ym;_S>7g_3XI zdRb!Ppd`ErK`pUDHRsJd9@)bu>}s1)nKsyAR7h21<1u{DX1gd_Vf;^zdUpFPeSHHR z7AMgw^{FlFlK91CGMafKt`$FLhq#^=->@Uok7pqW6&#Zs4*E(i5-jog43A*qC@!(8 z8&F}pofRcMVmcJd=f;fvlfAR!ZqeaTE?#TQ^jQM0ioaJf8m^!Kdv^`f5kEsD0=gX#4={QE1$3A4K~V$ITKEd){XVLx?i6K*D>JF6E=i znqF^X#&UX}rfB|#A9%y|sR5i6B5gyk>8@Q+xHg|^5iz7C2}YkGF)nuP4LX#k2tRBP z=!VnWnXea(K#Wvg2&0f{!mXuuWaPpsoZ)3TSaEp;i|_)CvP=4wjI; zH%7tcLM8dQXsHW*#|}%TG9yiGpyjBltpcpXkpl8zg~x zD{QG)2Z8x$vfjgDc(J6i|OHoLX&!<+m^<$S3DtA8Mf!{ z7;g1}0uqJ0Mxuy%=#BFX5;Xh9JkrA$d}neS9T;$F$kXn}ss zF{Jn}9EDk=>h)sMy$YXfhKIDxr7U@3xl+uI|N5y!>?{aVn703L1Qgb$ql%JT^lsGD%)~)(H?Spj$zNt)h)Raob z@KyVB@&ngE0rtMW4!UTqGX>{&KHJAWqb)oYq9O)e)nmN0jVa;LNbKXx04a+8&O;q) zHBzGejrqt7Dk$Z2VR%%K#`!((pXE*MR{jGtv|q$p5#v9N0f^6B9IB!Q6(y$TmHRLM zsYXm2jn3f{9T)KVVzotDx=Ng8q0Z*VDZOkd5C!p0PRoFt>NyVEc9*%YR&2>Nq~$AI zXOQfjJ&wpGMe~I8y=cC(QR4=W2GWccFK(3`d&gN+)qWtW-`*}mZI%KDRl4@rUv1%d zxFO82lhW$xQyYxJg8tOZyXm1As%kEFNn)eW{R61M>af@wr(YW{R@+eL2 zx?SovK+867$F%T;Dfeajw|kiQ81GcOnS$Y4+hp8g_w1P8_~79d9p$*M1_Ei81$H$Ti6oi?ZW)&tmsJa7RV1LKddm7R*qL54L7j zvCr1Mrb;l!=m^TbJun-C_6$7w81E1eAQC^6s4>rZ4&I5+yyu$kha%Z&d+|S7Ki#{2 zy}%Giz|eR|G?ychX%%=eL`W(aLarb(L4jd>J+wlX;xMV9H8J!l&i?~Mw7)jlIuLD% zyq+AK92j#kC`ycv$SJ|E7!FBParx#v<3_rZ-DLQ@>`#sdl5}immok8&`{YgF|+< z`tB>e%6G{=B4?V-be>`&*}0d*f?$yBX@w+rJht@O+=^zttqB2p=IiA17#YD$4-fih z@$gJ95mGmFhN!d;3Ag4#>3o`>%L{G=9<}qOJ$wDN)%)MN6bVsAPG4oKB3+8r6!Qf9 z3m8?jIpWcEJbt6|f?Y4nMXK(--YZ|GA2_aRS!do%J9S7?Q&4FYL@sPilq}e4tlYa& z?f+we^=FH^Z9|dnXZghblW!IYGIAT{``58&7vZBybh+GuIPP{h*J?&vf7i8rv6qgx zab9~l+K`tvC7pWtlS!5lt(n#Yl}PAR(v01oXjc0F?T0w>+*p#PtE?Tf_hMrEaZ!^V zbv_>=4xibc0TUxg^I>TS?HR4fdiWl`@6{7|WU9G68l7tOz2p>oIe~NNr!>Q&PHm`4 z98R?g(IT*nl#{_|*WO_h0X78;WwMp?A^Zi)W@BX5q==TdOl?~J6HK(0b(xD6?m3e3 z#+zMaSJb(W$h5+d+6vujSjyi_R80c9>7h;0YlUFDvN`iNGu&5HQ5^e>6x?&JSc4V$6_I1jJ4vnCVbkU`Gz=Uy#~OI( zlL-$UAE$pVCsD_rICM#Q!ltzcqDphp5L|ZrqUm>=H%x!RjMrF#*?BN2shvUg=H;)& zy~_xWl*k$~9Hl6PIq({dELPE-r4*YNs7?5{>dlC`EcK~lPKB_8V)G@H)UZFF8$tXT z@^raW#Hq4OJGFL2Aye|HU&_NL%dYans6?ltqEBz`Q|m=@Zh4=-p2r;}q(Nbsk$fUI zP|(Ns2>MDvZi1H7<55frlQn#%?`WY3g`+fRuC#UJx%#d!zxEu3=}zF514S=6f@?~$ zeuSB=6E7r3ya|; z@K7M3VBrls6c{M*M_{AB_fVjgQ|F(FuK(@=1eWeVMSpLglllqV6Rg-L_46;?^IskS z)x6|SR1^gGl6amWjkb1dX}^8DumNXNmhsfxKA#;bBBIZE@0gma5yQY(FX>|N~Y^mgq`xc zdxOf6r{9u#_e0gV3(fdBTdV2Sc4SN5ZmP?cB4?KR [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - avalon.range(1, 11) - => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - avalon.range(0, 30, 5) - => [0, 5, 10, 15, 20, 25] - avalon.range(0, -10, -1) - => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] - avalon.range(0) - => []*/ - range: function (start, end, step) { // 用于生成整数数组 - step || (step = 1) - if (end == null) { - end = start || 0 - start = 0 - } - var index = -1, - length = Math.max(0, Math.ceil((end - start) / step)), - result = new Array(length) - while (++index < length) { - result[index] = start - start += step - } - return result - }, - eventHooks: [], - /*绑定事件*/ - bind: function(el, type, fn, phase) { - var hooks = avalon.eventHooks - var hook = hooks[type] - if (typeof hook === "object") { - type = hook.type - if (hook.deel) { - fn = hook.deel(el, type, fn, phase) - } - } - var callback = W3C ? fn : function(e) { - fn.call(el, fixEvent(e)); - } - if (W3C) { - el.addEventListener(type, callback, !!phase) - } else { - el.attachEvent("on" + type, callback) - } - return callback - }, - /*卸载事件*/ - unbind: function(el, type, fn, phase) { - var hooks = avalon.eventHooks - var hook = hooks[type] - var callback = fn || noop - if (typeof hook === "object") { - type = hook.type - if (hook.deel) { - fn = hook.deel(el, type, fn, false) - } - } - if (W3C) { - el.removeEventListener(type, callback, !!phase) - } else { - el.detachEvent("on" + type, callback) - } - }, - /*读写删除元素节点的样式*/ - css: function (node, name, value) { - if (node instanceof avalon) { - node = node[0] - } - var prop = /[_-]/.test(name) ? camelize(name) : name, fn - name = avalon.cssName(prop) || prop - if (value === void 0 || typeof value === "boolean") { //获取样式 - fn = cssHooks[prop + ":get"] || cssHooks["@:get"] - if (name === "background") { - name = "backgroundColor" - } - var val = fn(node, name) - return value === true ? parseFloat(val) || 0 : val - } else if (value === "") { //请除样式 - node.style[name] = "" - } else { //设置样式 - if (value == null || value !== value) { - return - } - if (isFinite(value) && !avalon.cssNumber[prop]) { - value += "px" - } - fn = cssHooks[prop + ":set"] || cssHooks["@:set"] - fn(node, name, value) - } - }, - /*遍历数组与对象,回调的第一个参数为索引或键名,第二个或元素或键值*/ - each: function (obj, fn) { - if (obj) { //排除null, undefined - var i = 0 - if (isArrayLike(obj)) { - for (var n = obj.length; i < n; i++) { - if (fn(i, obj[i]) === false) - break - } - } else { - for (i in obj) { - if (obj.hasOwnProperty(i) && fn(i, obj[i]) === false) { - break - } - } - } - } - }, - //收集元素的data-{{prefix}}-*属性,并转换为对象 - getWidgetData: function (elem, prefix) { - var raw = avalon(elem).data() - var result = {} - for (var i in raw) { - if (i.indexOf(prefix) === 0) { - result[i.replace(prefix, "").replace(/\w/, function (a) { - return a.toLowerCase() - })] = raw[i] - } - } - return result - }, - Array: { - /*只有当前数组不存在此元素时只添加它*/ - ensure: function (target, item) { - if (target.indexOf(item) === -1) { - return target.push(item) - } - }, - /*移除数组中指定位置的元素,返回布尔表示成功与否*/ - removeAt: function (target, index) { - return !!target.splice(index, 1).length - }, - /*移除数组中第一个匹配传参的那个元素,返回布尔表示成功与否*/ - remove: function (target, item) { - var index = target.indexOf(item) - if (~index) - return avalon.Array.removeAt(target, index) - return false - } - } -}) - -var bindingHandlers = avalon.bindingHandlers = {} -var bindingExecutors = avalon.bindingExecutors = {} - -/*判定是否类数组,如节点集合,纯数组,arguments与拥有非负整数的length属性的纯JS对象*/ -function isArrayLike(obj) { - if (!obj) - return false - var n = obj.length - if (n === (n >>> 0)) { //检测length属性是否为非负整数 - var type = serialize.call(obj).slice(8, -1) - if (/(?:regexp|string|function|window|global)$/i.test(type)) - return false - if (type === "Array") - return true - try { - if ({}.propertyIsEnumerable.call(obj, "length") === false) { //如果是原生对象 - return /^\s?function/.test(obj.item || obj.callee) - } - return true - } catch (e) { //IE的NodeList直接抛错 - return !obj.window //IE6-8 window - } - } - return false -} - - -// https://github.com/rsms/js-lru -var Cache = new function() {// jshint ignore:line - function LRU(maxLength) { - this.size = 0 - this.limit = maxLength - this.head = this.tail = void 0 - this._keymap = {} - } - - var p = LRU.prototype - - p.put = function(key, value) { - var entry = { - key: key, - value: value - } - this._keymap[key] = entry - if (this.tail) { - this.tail.newer = entry - entry.older = this.tail - } else { - this.head = entry - } - this.tail = entry - if (this.size === this.limit) { - this.shift() - } else { - this.size++ - } - return value - } - - p.shift = function() { - var entry = this.head - if (entry) { - this.head = this.head.newer - this.head.older = - entry.newer = - entry.older = - this._keymap[entry.key] = void 0 - } - } - p.get = function(key) { - var entry = this._keymap[key] - if (entry === void 0) - return - if (entry === this.tail) { - return entry.value - } - // HEAD--------------TAIL - // <.older .newer> - // <--- add direction -- - // A B C E - if (entry.newer) { - if (entry === this.head) { - this.head = entry.newer - } - entry.newer.older = entry.older // C <-- E. - } - if (entry.older) { - entry.older.newer = entry.newer // C. --> E - } - entry.newer = void 0 // D --x - entry.older = this.tail // D. --> E - if (this.tail) { - this.tail.newer = entry // E. <-- D - } - this.tail = entry - return entry.value - } - return LRU -}// jshint ignore:line - -/********************************************************************* - * javascript 底层补丁 * - **********************************************************************/ -if (!"司徒正美".trim) { - var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g - String.prototype.trim = function () { - return this.replace(rtrim, "") - } -} -var hasDontEnumBug = !({ - 'toString': null -}).propertyIsEnumerable('toString'), - hasProtoEnumBug = (function () { - }).propertyIsEnumerable('prototype'), - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ], - dontEnumsLength = dontEnums.length; -if (!Object.keys) { - Object.keys = function (object) { //ecma262v5 15.2.3.14 - var theKeys = [] - var skipProto = hasProtoEnumBug && typeof object === "function" - if (typeof object === "string" || (object && object.callee)) { - for (var i = 0; i < object.length; ++i) { - theKeys.push(String(i)) - } - } else { - for (var name in object) { - if (!(skipProto && name === "prototype") && ohasOwn.call(object, name)) { - theKeys.push(String(name)) - } - } - } - - if (hasDontEnumBug) { - var ctor = object.constructor, - skipConstructor = ctor && ctor.prototype === object - for (var j = 0; j < dontEnumsLength; j++) { - var dontEnum = dontEnums[j] - if (!(skipConstructor && dontEnum === "constructor") && ohasOwn.call(object, dontEnum)) { - theKeys.push(dontEnum) - } - } - } - return theKeys - } -} -if (!Array.isArray) { - Array.isArray = function (a) { - return serialize.call(a) === "[object Array]" - } -} - -if (!noop.bind) { - Function.prototype.bind = function (scope) { - if (arguments.length < 2 && scope === void 0) - return this - var fn = this, - argv = arguments - return function () { - var args = [], - i - for (i = 1; i < argv.length; i++) - args.push(argv[i]) - for (i = 0; i < arguments.length; i++) - args.push(arguments[i]) - return fn.apply(scope, args) - } - } -} - -function iterator(vars, body, ret) { - var fun = 'for(var ' + vars + 'i=0,n = this.length; i < n; i++){' + body.replace('_', '((i in this) && fn.call(scope,this[i],i,this))') + '}' + ret - /* jshint ignore:start */ - return Function("fn,scope", fun) - /* jshint ignore:end */ -} -if (!rnative.test([].map)) { - avalon.mix(ap, { - //定位操作,返回数组中第一个等于给定参数的元素的索引值。 - indexOf: function (item, index) { - var n = this.length, - i = ~~index - if (i < 0) - i += n - for (; i < n; i++) - if (this[i] === item) - return i - return -1 - }, - //定位操作,同上,不过是从后遍历。 - lastIndexOf: function (item, index) { - var n = this.length, - i = index == null ? n - 1 : index - if (i < 0) - i = Math.max(0, n + i) - for (; i >= 0; i--) - if (this[i] === item) - return i - return -1 - }, - //迭代操作,将数组的元素挨个儿传入一个函数中执行。Prototype.js的对应名字为each。 - forEach: iterator("", '_', ""), - //迭代类 在数组中的每个项上运行一个函数,如果此函数的值为真,则此元素作为新数组的元素收集起来,并返回新数组 - filter: iterator('r=[],j=0,', 'if(_)r[j++]=this[i]', 'return r'), - //收集操作,将数组的元素挨个儿传入一个函数中执行,然后把它们的返回值组成一个新数组返回。Prototype.js的对应名字为collect。 - map: iterator('r=[],', 'r[i]=_', 'return r'), - //只要数组中有一个元素满足条件(放进给定函数返回true),那么它就返回true。Prototype.js的对应名字为any。 - some: iterator("", 'if(_)return true', 'return false'), - //只有数组中的元素都满足条件(放进给定函数返回true),它才返回true。Prototype.js的对应名字为all。 - every: iterator("", 'if(!_)return false', 'return true') - }) -} -/********************************************************************* - * DOM 底层补丁 * - **********************************************************************/ - -function fixContains(root, el) { - try { //IE6-8,游离于DOM树外的文本节点,访问parentNode有时会抛错 - while ((el = el.parentNode)) - if (el === root) - return true - return false - } catch (e) { - return false - } -} -avalon.contains = fixContains -//IE6-11的文档对象没有contains -if (!DOC.contains) { - DOC.contains = function (b) { - return fixContains(DOC, b) - } -} - -function outerHTML() { - return new XMLSerializer().serializeToString(this) -} - -if (window.SVGElement) { - //safari5+是把contains方法放在Element.prototype上而不是Node.prototype - if (!DOC.createTextNode("x").contains) { - Node.prototype.contains = function (arg) {//IE6-8没有Node对象 - return !!(this.compareDocumentPosition(arg) & 16) - } - } - var svgns = "http://www.w3.org/2000/svg" - var svg = DOC.createElementNS(svgns, "svg") - svg.innerHTML = '' - if (!rsvg.test(svg.firstChild)) { // #409 - function enumerateNode(node, targetNode) {// jshint ignore:line - if (node && node.childNodes) { - var nodes = node.childNodes - for (var i = 0, el; el = nodes[i++]; ) { - if (el.tagName) { - var svg = DOC.createElementNS(svgns, - el.tagName.toLowerCase()) - ap.forEach.call(el.attributes, function (attr) { - svg.setAttribute(attr.name, attr.value) //复制属性 - })// jshint ignore:line - // 递归处理子节点 - enumerateNode(el, svg) - targetNode.appendChild(svg) - } - } - } - } - Object.defineProperties(SVGElement.prototype, { - "outerHTML": {//IE9-11,firefox不支持SVG元素的innerHTML,outerHTML属性 - enumerable: true, - configurable: true, - get: outerHTML, - set: function (html) { - var tagName = this.tagName.toLowerCase(), - par = this.parentNode, - frag = avalon.parseHTML(html) - // 操作的svg,直接插入 - if (tagName === "svg") { - par.insertBefore(frag, this) - // svg节点的子节点类似 - } else { - var newFrag = DOC.createDocumentFragment() - enumerateNode(frag, newFrag) - par.insertBefore(newFrag, this) - } - par.removeChild(this) - } - }, - "innerHTML": { - enumerable: true, - configurable: true, - get: function () { - var s = this.outerHTML - var ropen = new RegExp("<" + this.nodeName + '\\b(?:(["\'])[^"]*?(\\1)|[^>])*>', "i") - var rclose = new RegExp("<\/" + this.nodeName + ">$", "i") - return s.replace(ropen, "").replace(rclose, "") - }, - set: function (html) { - if (avalon.clearHTML) { - avalon.clearHTML(this) - var frag = avalon.parseHTML(html) - enumerateNode(frag, this) - } - } - } - }) - } -} -if (!root.outerHTML && window.HTMLElement) { //firefox 到11时才有outerHTML - HTMLElement.prototype.__defineGetter__("outerHTML", outerHTML); -} - - -//============================= event binding ======================= -var rmouseEvent = /^(?:mouse|contextmenu|drag)|click/ -function fixEvent(event) { - var ret = {} - for (var i in event) { - ret[i] = event[i] - } - var target = ret.target = event.srcElement - if (event.type.indexOf("key") === 0) { - ret.which = event.charCode != null ? event.charCode : event.keyCode - } else if (rmouseEvent.test(event.type)) { - var doc = target.ownerDocument || DOC - var box = doc.compatMode === "BackCompat" ? doc.body : doc.documentElement - ret.pageX = event.clientX + (box.scrollLeft >> 0) - (box.clientLeft >> 0) - ret.pageY = event.clientY + (box.scrollTop >> 0) - (box.clientTop >> 0) - ret.wheelDeltaY = ret.wheelDelta - ret.wheelDeltaX = 0 - } - ret.timeStamp = new Date() - 0 - ret.originalEvent = event - ret.preventDefault = function () { //阻止默认行为 - event.returnValue = false - } - ret.stopPropagation = function () { //阻止事件在DOM树中的传播 - event.cancelBubble = true - } - return ret -} - -var eventHooks = avalon.eventHooks -//针对firefox, chrome修正mouseenter, mouseleave -if (!("onmouseenter" in root)) { - avalon.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }, function (origType, fixType) { - eventHooks[origType] = { - type: fixType, - deel: function (elem, _, fn) { - return function (e) { - var t = e.relatedTarget - if (!t || (t !== elem && !(elem.compareDocumentPosition(t) & 16))) { - delete e.type - e.type = origType - return fn.call(elem, e) - } - } - } - } - }) -} -//针对IE9+, w3c修正animationend -avalon.each({ - AnimationEvent: "animationend", - WebKitAnimationEvent: "webkitAnimationEnd" -}, function (construct, fixType) { - if (window[construct] && !eventHooks.animationend) { - eventHooks.animationend = { - type: fixType - } - } -}) -//针对IE6-8修正input -if (!("oninput" in DOC.createElement("input"))) { - eventHooks.input = { - type: "propertychange", - deel: function (elem, _, fn) { - return function (e) { - if (e.propertyName === "value") { - e.type = "input" - return fn.call(elem, e) - } - } - } - } -} -if (DOC.onmousewheel === void 0) { - /* IE6-11 chrome mousewheel wheelDetla 下 -120 上 120 - firefox DOMMouseScroll detail 下3 上-3 - firefox wheel detlaY 下3 上-3 - IE9-11 wheel deltaY 下40 上-40 - chrome wheel deltaY 下100 上-100 */ - var fixWheelType = DOC.onwheel !== void 0 ? "wheel" : "DOMMouseScroll" - var fixWheelDelta = fixWheelType === "wheel" ? "deltaY" : "detail" - eventHooks.mousewheel = { - type: fixWheelType, - deel: function (elem, _, fn) { - return function (e) { - e.wheelDeltaY = e.wheelDelta = e[fixWheelDelta] > 0 ? -120 : 120 - e.wheelDeltaX = 0 - if (Object.defineProperty) { - Object.defineProperty(e, "type", { - value: "mousewheel" - }) - } - fn.call(elem, e) - } - } - } -} - - - -/********************************************************************* - * 配置系统 * - **********************************************************************/ - -function kernel(settings) { - for (var p in settings) { - if (!ohasOwn.call(settings, p)) - continue - var val = settings[p] - if (typeof kernel.plugins[p] === "function") { - kernel.plugins[p](val) - } else if (typeof kernel[p] === "object") { - avalon.mix(kernel[p], val) - } else { - kernel[p] = val - } - } - return this -} -var openTag, closeTag, rexpr, rexprg, rbind, rregexp = /[-.*+?^${}()|[\]\/\\]/g - -function escapeRegExp(target) { - //http://stevenlevithan.com/regex/xregexp/ - //将字符串安全格式化为正则表达式的源码 - return (target + "").replace(rregexp, "\\$&") -} - -var plugins = { - loader: function (builtin) { - var flag = innerRequire && builtin - window.require = flag ? innerRequire : otherRequire - window.define = flag ? innerRequire.define : otherDefine - }, - interpolate: function (array) { - openTag = array[0] - closeTag = array[1] - if (openTag === closeTag) { - throw new SyntaxError("openTag!==closeTag") - var test = openTag + "test" + closeTag - cinerator.innerHTML = test - if (cinerator.innerHTML !== test && cinerator.innerHTML.indexOf("<") > -1) { - throw new SyntaxError("此定界符不合法") - } - cinerator.innerHTML = "" - } - var o = escapeRegExp(openTag), - c = escapeRegExp(closeTag) - rexpr = new RegExp(o + "(.*?)" + c) - rexprg = new RegExp(o + "(.*?)" + c, "g") - rbind = new RegExp(o + ".*?" + c + "|\\sms-") - } -} - -kernel.debug = true -kernel.plugins = plugins -kernel.plugins['interpolate'](["{{", "}}"]) -kernel.paths = {} -kernel.shim = {} -kernel.maxRepeatSize = 100 -avalon.config = kernel -var ravalon = /(\w+)\[(avalonctrl)="(\S+)"\]/ -var findNodes = DOC.querySelectorAll ? function(str) { - return DOC.querySelectorAll(str) -} : function(str) { - var match = str.match(ravalon) - var all = DOC.getElementsByTagName(match[1]) - var nodes = [] - for (var i = 0, el; el = all[i++]; ) { - if (el.getAttribute(match[2]) === match[3]) { - nodes.push(el) - } - } - return nodes -} -/********************************************************************* - * 事件总线 * - **********************************************************************/ -var EventBus = { - $watch: function (type, callback) { - if (typeof callback === "function") { - var callbacks = this.$events[type] - if (callbacks) { - callbacks.push(callback) - } else { - this.$events[type] = [callback] - } - } else { //重新开始监听此VM的第一重简单属性的变动 - this.$events = this.$watch.backup - } - return this - }, - $unwatch: function (type, callback) { - var n = arguments.length - if (n === 0) { //让此VM的所有$watch回调无效化 - this.$watch.backup = this.$events - this.$events = {} - } else if (n === 1) { - this.$events[type] = [] - } else { - var callbacks = this.$events[type] || [] - var i = callbacks.length - while (~--i < 0) { - if (callbacks[i] === callback) { - return callbacks.splice(i, 1) - } - } - } - return this - }, - $fire: function (type) { - var special, i, v, callback - if (/^(\w+)!(\S+)$/.test(type)) { - special = RegExp.$1 - type = RegExp.$2 - } - var events = this.$events - if (!events) - return - var args = aslice.call(arguments, 1) - var detail = [type].concat(args) - if (special === "all") { - for (i in avalon.vmodels) { - v = avalon.vmodels[i] - if (v !== this) { - v.$fire.apply(v, detail) - } - } - } else if (special === "up" || special === "down") { - var elements = events.expr ? findNodes(events.expr) : [] - if (elements.length === 0) - return - for (i in avalon.vmodels) { - v = avalon.vmodels[i] - if (v !== this) { - if (v.$events.expr) { - var eventNodes = findNodes(v.$events.expr) - if (eventNodes.length === 0) { - continue - } - //循环两个vmodel中的节点,查找匹配(向上匹配或者向下匹配)的节点并设置标识 - /* jshint ignore:start */ - ap.forEach.call(eventNodes, function (node) { - ap.forEach.call(elements, function (element) { - var ok = special === "down" ? element.contains(node) : //向下捕获 - node.contains(element) //向上冒泡 - if (ok) { - node._avalon = v //符合条件的加一个标识 - } - }); - }) - /* jshint ignore:end */ - } - } - } - var nodes = DOC.getElementsByTagName("*") //实现节点排序 - var alls = [] - ap.forEach.call(nodes, function (el) { - if (el._avalon) { - alls.push(el._avalon) - el._avalon = "" - el.removeAttribute("_avalon") - } - }) - if (special === "up") { - alls.reverse() - } - for (i = 0; callback = alls[i++]; ) { - if (callback.$fire.apply(callback, detail) === false) { - break - } - } - } else { - var callbacks = events[type] || [] - var all = events.$all || [] - for (i = 0; callback = callbacks[i++]; ) { - if (isFunction(callback)) - callback.apply(this, args) - } - for (i = 0; callback = all[i++]; ) { - if (isFunction(callback)) - callback.apply(this, arguments) - } - } - } -} - -/********************************************************************* - * modelFactory * - **********************************************************************/ -//avalon最核心的方法的两个方法之一(另一个是avalon.scan),返回一个ViewModel(VM) -var VMODELS = avalon.vmodels = {} //所有vmodel都储存在这里 -avalon.define = function (id, factory) { - var $id = id.$id || id - if (!$id) { - log("warning: vm必须指定$id") - } - if (VMODELS[$id]) { - log("warning: " + $id + " 已经存在于avalon.vmodels中") - } - if (typeof id === "object") { - var model = modelFactory(id) - } else { - var scope = { - $watch: noop - } - factory(scope) //得到所有定义 - - model = modelFactory(scope) //偷天换日,将scope换为model - stopRepeatAssign = true - factory(model) - stopRepeatAssign = false - } - model.$id = $id - return VMODELS[$id] = model -} - -//一些不需要被监听的属性 -var $$skipArray = String("$id,$watch,$unwatch,$fire,$events,$model,$skipArray,$proxy,$reinitialize,$propertyNames").match(rword) -var defineProperty = Object.defineProperty -var canHideOwn = true -//如果浏览器不支持ecma262v5的Object.defineProperties或者存在BUG,比如IE8 -//标准浏览器使用__defineGetter__, __defineSetter__实现 -try { - defineProperty({}, "_", { - value: "x" - }) - var defineProperties = Object.defineProperties -} catch (e) { - canHideOwn = false -} - -function modelFactory(source, $special, $model) { - if (Array.isArray(source)) { - var arr = source.concat() - source.length = 0 - var collection = arrayFactory(source) - collection.pushArray(arr) - return collection - } - //0 null undefined || Node || VModel(fix IE6-8 createWithProxy $val: val引发的BUG) - if (!source || source.nodeType > 0 || (source.$id && source.$events)) { - return source - } - var $skipArray = Array.isArray(source.$skipArray) ? source.$skipArray : [] - $skipArray.$special = $special || {} //强制要监听的属性 - var $vmodel = {} //要返回的对象, 它在IE6-8下可能被偷龙转凤 - $model = $model || {} //vmodels.$model属性 - var $events = {} //vmodel.$events属性 - var accessors = {} //监控属性 - var computed = [] - $$skipArray.forEach(function (name) { - delete source[name] - }) - var names = Object.keys(source) - /* jshint ignore:start */ - names.forEach(function (name, accessor) { - var val = source[name] - $model[name] = val - if (isObservable(name, val, $skipArray)) { - //总共产生三种accessor - $events[name] = [] - var valueType = avalon.type(val) - //总共产生三种accessor - if (valueType === "object" && isFunction(val.get) && Object.keys(val).length <= 2) { - accessor = makeComputedAccessor(name, val) - computed.push(accessor) - } else if (rcomplexType.test(valueType)) { - accessor = makeComplexAccessor(name, val, valueType, $events[name]) - } else { - accessor = makeSimpleAccessor(name, val) - } - accessors[name] = accessor - } - }) - /* jshint ignore:end */ - - $vmodel = defineProperties($vmodel, descriptorFactory(accessors), source) //生成一个空的ViewModel - for (var i = 0; i < names.length; i++) { - var name = names[i] - if (!accessors[name]) { - $vmodel[name] = source[name] - } - } - //添加$id, $model, $events, $watch, $unwatch, $fire - $vmodel.$propertyNames = names.join("­") - $vmodel.$id = generateID() - $vmodel.$model = $model - $vmodel.$events = $events - for (i in EventBus) { - var fn = EventBus[i] - if (!W3C) { //在IE6-8下,VB对象的方法里的this并不指向自身,需要用bind处理一下 - fn = fn.bind($vmodel) - } - $vmodel[i] = fn - } - if (canHideOwn) { - Object.defineProperty($vmodel, "hasOwnProperty", hasOwnDescriptor) - } else { - /* jshint ignore:start */ - $vmodel.hasOwnProperty = function (name) { - return name in $vmodel.$model - } - /* jshint ignore:end */ - } - - $vmodel.$reinitialize = function () { - computed.forEach(function (accessor) { - delete accessor._value - delete accessor.oldArgs - accessor.digest = function () { - accessor.call($vmodel) - } - dependencyDetection.begin({ - callback: function (vm, dependency) {//dependency为一个accessor - var name = dependency._name - if (dependency !== accessor) { - var list = vm.$events[name] - injectDependency(list, accessor.digest) - } - } - }) - try { - accessor.get.call($vmodel) - } finally { - dependencyDetection.end() - } - }) - } - $vmodel.$reinitialize() - return $vmodel -} - -var hasOwnDescriptor = { - value: function (name) { - return name in this.$model - }, - writable: false, - enumerable: false, - configurable: true -} -//创建一个简单访问器 -function makeSimpleAccessor(name, value) { - function accessor(value) { - var oldValue = accessor._value - if (arguments.length > 0) { - if (!stopRepeatAssign && !isEqual(value, oldValue)) { - accessor.updateValue(this, value) - accessor.notify(this, value, oldValue) - } - return this - } else { - dependencyDetection.collectDependency(this, accessor) - return oldValue - } - } - accessorFactory(accessor, name) - accessor._value = value - return accessor; -} - -//创建一个计算访问器 -function makeComputedAccessor(name, options) { - function accessor(value) {//计算属性 - var oldValue = accessor._value - var init = ("_value" in accessor) - if (arguments.length > 0) { - if (stopRepeatAssign) { - return this - } - if (typeof accessor.set === "function") { - if (accessor.oldArgs !== value) { - accessor.oldArgs = value - var $events = this.$events - var lock = $events[name] - $events[name] = [] //清空回调,防止内部冒泡而触发多次$fire - accessor.set.call(this, value) - $events[name] = lock - value = accessor.get.call(this) - if (value !== oldValue) { - accessor.updateValue(this, value) - accessor.notify(this, value, oldValue) //触发$watch回调 - } - } - } - return this - } else { - //将依赖于自己的高层访问器或视图刷新函数(以绑定对象形式)放到自己的订阅数组中 - //将自己注入到低层访问器的订阅数组中 - value = accessor.get.call(this) - accessor.updateValue(this, value) - if (init && oldValue !== value) { - accessor.notify(this, value, oldValue) //触发$watch回调 - } - return value - } - } - accessor.set = options.set - accessor.get = options.get - accessorFactory(accessor, name) - return accessor -} - -//创建一个复杂访问器 -function makeComplexAccessor(name, initValue, valueType, list) { - function accessor(value) { - var oldValue = accessor._value - - var son = accessor._vmodel - if (arguments.length > 0) { - if (stopRepeatAssign) { - return this - } - if (valueType === "array") { - var a = son, b = value, - an = a.length, - bn = b.length - a.$lock = true - if (an > bn) { - a.splice(bn, an - bn) - } else if (bn > an) { - a.push.apply(a, b.slice(an)) - } - var n = Math.min(an, bn) - for (var i = 0; i < n; i++) { - a.set(i, b[i]) - } - delete a.$lock - a._fire("set") - } else if (valueType === "object") { - var newPropertyNames = Object.keys(value).join("­") - if (son.$propertyNames === newPropertyNames) { - for (i in value) { - son[i] = value[i] - } - } else { - var sson = accessor._vmodel = modelFactory(value) - var sevent = sson.$events - var oevent = son.$events - for (var i in sevent) { - var arr = sevent[i] - if (Array.isArray(arr)) { - arr = arr.concat(oevent[i]) - } - } - sevent[subscribers] = oevent[subscribers] - sson.$proxy = son.$proxy - son = sson - } - } - accessor.updateValue(this, son.$model) - accessor.notify(this, this._value, oldValue) - return this - } else { - dependencyDetection.collectDependency(this, accessor) - return son - } - } - accessorFactory(accessor, name) - var son = accessor._vmodel = modelFactory(initValue) - son.$events[subscribers] = list - return accessor -} - -function globalUpdateValue(vmodel, value) { - vmodel.$model[this._name] = this._value = value -} - -function globalNotify(vmodel, value, oldValue) { - var name = this._name - var array = vmodel.$events[name] //刷新值 - if (array) { - fireDependencies(array) //同步视图 - EventBus.$fire.call(vmodel, name, value, oldValue) //触发$watch回调 - } -} - -function accessorFactory(accessor, name) { - accessor._name = name - //同时更新_value与model - accessor.updateValue = globalUpdateValue - accessor.notify = globalNotify -} - -//比较两个值是否相等 -var isEqual = Object.is || function (v1, v2) { - if (v1 === 0 && v2 === 0) { - return 1 / v1 === 1 / v2 - } else if (v1 !== v1) { - return v2 !== v2 - } else { - return v1 === v2 - } -} - -function isObservable(name, value, $skipArray) { - if (isFunction(value) || value && value.nodeType) { - return false - } - if ($skipArray.indexOf(name) !== -1) { - return false - } - var $special = $skipArray.$special - if (name && name.charAt(0) === "$" && !$special[name]) { - return false - } - return true -} - -var descriptorFactory = W3C ? function (obj) { - var descriptors = {} - for (var i in obj) { - descriptors[i] = { - get: obj[i], - set: obj[i], - enumerable: true, - configurable: true - } - } - return descriptors -} : function (a) { - return a -} - -//===================修复浏览器对Object.defineProperties的支持================= -if (!canHideOwn) { - if ("__defineGetter__" in avalon) { - defineProperty = function (obj, prop, desc) { - if ('value' in desc) { - obj[prop] = desc.value - } - if ("get" in desc) { - obj.__defineGetter__(prop, desc.get) - } - if ('set' in desc) { - obj.__defineSetter__(prop, desc.set) - } - return obj - } - defineProperties = function (obj, descs) { - for (var prop in descs) { - if (descs.hasOwnProperty(prop)) { - defineProperty(obj, prop, descs[prop]) - } - } - return obj - } - } - if (IEVersion) { - var VBClassPool = {} - window.execScript([// jshint ignore:line - "Function parseVB(code)", - "\tExecuteGlobal(code)", - "End Function" //转换一段文本为VB代码 - ].join("\n"), "VBScript") - function VBMediator(instance, accessors, name, value) {// jshint ignore:line - var accessor = accessors[name] - if (arguments.length === 4) { - accessor.call(instance, value) - } else { - return accessor.call(instance) - } - } - defineProperties = function (name, accessors, properties) { - // jshint ignore:line - var buffer = [] - buffer.push( - "\r\n\tPrivate [__data__], [__proxy__]", - "\tPublic Default Function [__const__](d, p)", - "\t\tSet [__data__] = d: set [__proxy__] = p", - "\t\tSet [__const__] = Me", //链式调用 - "\tEnd Function") - //添加普通属性,因为VBScript对象不能像JS那样随意增删属性,必须在这里预先定义好 - for (name in properties) { - if (!accessors.hasOwnProperty(name)) { - buffer.push("\tPublic [" + name + "]") - } - } - $$skipArray.forEach(function (name) { - if (!accessors.hasOwnProperty(name)) { - buffer.push("\tPublic [" + name + "]") - } - }) - buffer.push("\tPublic [" + 'hasOwnProperty' + "]") - //添加访问器属性 - for (name in accessors) { - buffer.push( - //由于不知对方会传入什么,因此set, let都用上 - "\tPublic Property Let [" + name + "](val" + expose + ")", //setter - "\t\tCall [__proxy__](Me,[__data__], \"" + name + "\", val" + expose + ")", - "\tEnd Property", - "\tPublic Property Set [" + name + "](val" + expose + ")", //setter - "\t\tCall [__proxy__](Me,[__data__], \"" + name + "\", val" + expose + ")", - "\tEnd Property", - "\tPublic Property Get [" + name + "]", //getter - "\tOn Error Resume Next", //必须优先使用set语句,否则它会误将数组当字符串返回 - "\t\tSet[" + name + "] = [__proxy__](Me,[__data__],\"" + name + "\")", - "\tIf Err.Number <> 0 Then", - "\t\t[" + name + "] = [__proxy__](Me,[__data__],\"" + name + "\")", - "\tEnd If", - "\tOn Error Goto 0", - "\tEnd Property") - - } - - buffer.push("End Class") - var body = buffer.join("\r\n") - var className =VBClassPool[body] - if (!className) { - className = generateID("VBClass") - window.parseVB("Class " + className + body) - window.parseVB([ - "Function " + className + "Factory(a, b)", //创建实例并传入两个关键的参数 - "\tDim o", - "\tSet o = (New " + className + ")(a, b)", - "\tSet " + className + "Factory = o", - "End Function" - ].join("\r\n")) - VBClassPool[body] = className - } - var ret = window[className + "Factory"](accessors, VBMediator) //得到其产品 - return ret //得到其产品 - } - } -} - -/********************************************************************* - * 监控数组(与ms-each, ms-repeat配合使用) * - **********************************************************************/ - -function arrayFactory(model) { - var array = [] - array.$id = generateID() - array.$model = model //数据模型 - array.$events = {} - array.$events[subscribers] = [] - array._ = modelFactory({ - length: model.length - }) - array._.$watch("length", function (a, b) { - array.$fire("length", a, b) - }) - for (var i in EventBus) { - array[i] = EventBus[i] - } - avalon.mix(array, arrayPrototype) - return array -} - -function mutateArray(method, pos, n, index, method2, pos2, n2) { - var oldLen = this.length, loop = 2 - while (--loop) { - switch (method) { - case "add": - /* jshint ignore:start */ - var array = this.$model.slice(pos, pos + n).map(function (el) { - if (rcomplexType.test(avalon.type(el))) { - return el.$id ? el : modelFactory(el, 0, el) - } else { - return el - } - }) - /* jshint ignore:end */ - _splice.apply(this, [pos, 0].concat(array)) - this._fire("add", pos, n) - break - case "del": - var ret = this._splice(pos, n) - this._fire("del", pos, n) - break - } - if (method2) { - method = method2 - pos = pos2 - n = n2 - loop = 2 - method2 = 0 - } - } - this._fire("index", index) - if (this.length !== oldLen) { - this._.length = this.length - } - return ret -} - -var _splice = ap.splice -var arrayPrototype = { - _splice: _splice, - _fire: function (method, a, b) { - fireDependencies(this.$events[subscribers], method, a, b) - }, - size: function () { //取得数组长度,这个函数可以同步视图,length不能 - return this._.length - }, - pushArray: function (array) { - var m = array.length, n = this.length - if (m) { - ap.push.apply(this.$model, array) - mutateArray.call(this, "add", n, m, Math.max(0, n - 1)) - } - return m + n - }, - push: function () { - //http://jsperf.com/closure-with-arguments - var array = [] - var i, n = arguments.length - for (i = 0; i < n; i++) { - array[i] = arguments[i] - } - return this.pushArray(array) - }, - unshift: function () { - var m = arguments.length, n = this.length - if (m) { - ap.unshift.apply(this.$model, arguments) - mutateArray.call(this, "add", 0, m, 0) - } - return m + n //IE67的unshift不会返回长度 - }, - shift: function () { - if (this.length) { - var el = this.$model.shift() - mutateArray.call(this, "del", 0, 1, 0) - return el //返回被移除的元素 - } - }, - pop: function () { - var n = this.length - if (n) { - var el = this.$model.pop() - mutateArray.call(this, "del", n - 1, 1, Math.max(0, n - 2)) - return el //返回被移除的元素 - } - }, - splice: function (start) { - var m = arguments.length, args = [], change - var removed = _splice.apply(this.$model, arguments) - if (removed.length) { //如果用户删掉了元素 - args.push("del", start, removed.length, 0) - change = true - } - if (m > 2) { //如果用户添加了元素 - if (change) { - args.splice(3, 1, 0, "add", start, m - 2) - } else { - args.push("add", start, m - 2, 0) - } - change = true - } - if (change) { //返回被移除的元素 - return mutateArray.apply(this, args) - } else { - return [] - } - }, - contains: function (el) { //判定是否包含 - return this.indexOf(el) !== -1 - }, - remove: function (el) { //移除第一个等于给定值的元素 - return this.removeAt(this.indexOf(el)) - }, - removeAt: function (index) { //移除指定索引上的元素 - if (index >= 0) { - this.$model.splice(index, 1) - return mutateArray.call(this, "del", index, 1, 0) - } - return [] - }, - clear: function () { - this.$model.length = this.length = this._.length = 0 //清空数组 - this._fire("clear", 0) - return this - }, - removeAll: function (all) { //移除N个元素 - if (Array.isArray(all)) { - for (var i = this.length - 1; i >= 0; i--) { - if (all.indexOf(this[i]) !== -1) { - this.removeAt(i) - } - } - } else if (typeof all === "function") { - for ( i = this.length - 1; i >= 0; i--) { - var el = this[i] - if (all(el, i)) { - this.removeAt(i) - } - } - } else { - this.clear() - } - }, - ensure: function (el) { - if (!this.contains(el)) { //只有不存在才push - this.push(el) - } - return this - }, - set: function (index, val) { - if (index >= 0) { - var valueType = avalon.type(val) - if (val && val.$model) { - val = val.$model - } - var target = this[index] - if (valueType === "object") { - for (var i in val) { - if (target.hasOwnProperty(i)) { - target[i] = val[i] - } - } - } else if (valueType === "array") { - target.clear().push.apply(target, val) - } else if (target !== val) { - this[index] = val - this.$model[index] = val - this._fire("set", index, val) - } - } - return this - } -} -//相当于原来bindingExecutors.repeat 的index分支 -function resetIndex(array, pos) { - var last = array.length - 1 - for (var el; el = array[pos]; pos++) { - el.$index = pos - el.$first = pos === 0 - el.$last = pos === last - } -} - -function sortByIndex(array, indexes) { - var map = {}; - for (var i = 0, n = indexes.length; i < n; i++) { - map[i] = array[i] // preserve - var j = indexes[i] - if (j in map) { - array[i] = map[j] - delete map[j] - } else { - array[i] = array[j] - } - } -} - -"sort,reverse".replace(rword, function (method) { - arrayPrototype[method] = function () { - var newArray = this.$model//这是要排序的新数组 - var oldArray = newArray.concat() //保持原来状态的旧数组 - var mask = Math.random() - var indexes = [] - var hasSort - ap[method].apply(newArray, arguments) //排序 - for (var i = 0, n = oldArray.length; i < n; i++) { - var neo = newArray[i] - var old = oldArray[i] - if (isEqual(neo, old)) { - indexes.push(i) - } else { - var index = oldArray.indexOf(neo) - indexes.push(index)//得到新数组的每个元素在旧数组对应的位置 - oldArray[index] = mask //屏蔽已经找过的元素 - hasSort = true - } - } - if (hasSort) { - sortByIndex(this, indexes) - // sortByIndex(this.$proxy, indexes) - this._fire("move", indexes) - this._fire("index", 0) - } - return this - } -}) - - -/********************************************************************* - * 依赖调度系统 * - **********************************************************************/ -//检测两个对象间的依赖关系 -var dependencyDetection = (function () { - var outerFrames = [] - var currentFrame - return { - begin: function (accessorObject) { - //accessorObject为一个拥有callback的对象 - outerFrames.push(currentFrame) - currentFrame = accessorObject - }, - end: function () { - currentFrame = outerFrames.pop() - }, - collectDependency: function (vmodel, accessor) { - if (currentFrame) { - //被dependencyDetection.begin调用 - currentFrame.callback(vmodel, accessor); - } - } - }; -})() -//将绑定对象注入到其依赖项的订阅数组中 -var ronduplex = /^(duplex|on)$/ -avalon.injectBinding = function (data) { - var valueFn = data.evaluator - if (valueFn) { //如果是求值函数 - dependencyDetection.begin({ - callback: function (vmodel, dependency) { - injectDependency(vmodel.$events[dependency._name], data) - } - }) - try { - var value = ronduplex.test(data.type) ? data : valueFn.apply(0, data.args) - if(value === void 0){ - delete data.evaluator - } - data.handler(value, data.element, data) - } catch (e) { - //log("warning:exception throwed in [avalon.injectBinding] " + e) - delete data.evaluator - var node = data.element - if (node.nodeType === 3) { - var parent = node.parentNode - if (kernel.commentInterpolate) { - parent.replaceChild(DOC.createComment(data.value), node) - } else { - node.data = openTag + (data.oneTime ? "::" : "") + data.value + closeTag - } - } - } finally { - dependencyDetection.end() - } - } -} - -//将依赖项(比它高层的访问器或构建视图刷新函数的绑定对象)注入到订阅者数组 -function injectDependency(list, data) { - if (data.oneTime) - return - if (list && avalon.Array.ensure(list, data) && data.element) { - injectDisposeQueue(data, list) - } -} - -//通知依赖于这个访问器的订阅者更新自身 -function fireDependencies(list) { - if (list && list.length) { - if (new Date() - beginTime > 444 && typeof list[0] === "object") { - rejectDisposeQueue() - } - var args = aslice.call(arguments, 1) - for (var i = list.length, fn; fn = list[--i]; ) { - var el = fn.element - if (el && el.parentNode) { - try { - var valueFn = fn.evaluator - if (fn.$repeat) { - fn.handler.apply(fn, args) //处理监控数组的方法 - }else if("$repeat" in fn || !valueFn ){//如果没有eval,先eval - bindingHandlers[fn.type](fn, fn.vmodels) - } else if (fn.type !== "on") { //事件绑定只能由用户触发,不能由程序触发 - var value = valueFn.apply(0, fn.args || []) - fn.handler(value, el, fn) - } - } catch (e) { } - } - } - } -} -/********************************************************************* - * 定时GC回收机制 * - **********************************************************************/ -var disposeCount = 0 -var disposeQueue = avalon.$$subscribers = [] -var beginTime = new Date() -var oldInfo = {} -var uuid2Node = {} -function getUid(obj, makeID) { //IE9+,标准浏览器 - if (!obj.uuid && !makeID) { - obj.uuid = ++disposeCount - uuid2Node[obj.uuid] = obj - } - return obj.uuid -} -function getNode(uuid) { - return uuid2Node[uuid] -} -//添加到回收列队中 -function injectDisposeQueue(data, list) { - var elem = data.element - if (!data.uuid) { - if (elem.nodeType !== 1) { - data.uuid = data.type + (data.pos || 0) + "-" + getUid(elem.parentNode) - } else { - data.uuid = data.name + "-" + getUid(elem) - } - } - var lists = data.lists || (data.lists = []) - avalon.Array.ensure(lists, list) - list.$uuid = list.$uuid || generateID() - if (!disposeQueue[data.uuid]) { - disposeQueue[data.uuid] = 1 - disposeQueue.push(data) - } -} - -function rejectDisposeQueue(data) { - if (avalon.optimize) - return - var i = disposeQueue.length - var n = i - var allTypes = [] - var iffishTypes = {} - var newInfo = {} - //对页面上所有绑定对象进行分门别类, 只检测个数发生变化的类型 - while (data = disposeQueue[--i]) { - var type = data.type - if (newInfo[type]) { - newInfo[type]++ - } else { - newInfo[type] = 1 - allTypes.push(type) - } - } - var diff = false - allTypes.forEach(function (type) { - if (oldInfo[type] !== newInfo[type]) { - iffishTypes[type] = 1 - diff = true - } - }) - i = n - if (diff) { - while (data = disposeQueue[--i]) { - if (!data.element) - continue - if (iffishTypes[data.type] && shouldDispose(data.element)) { //如果它没有在DOM树 - disposeQueue.splice(i, 1) - delete disposeQueue[data.uuid] - delete uuid2Node[data.element.uuid] - var lists = data.lists - for (var k = 0, list; list = lists[k++]; ) { - avalon.Array.remove(lists, list) - avalon.Array.remove(list, data) - } - disposeData(data) - } - } - } - oldInfo = newInfo - beginTime = new Date() -} - -function disposeData(data) { - data.element = null - data.rollback && data.rollback() - for (var key in data) { - data[key] = null - } -} - -function shouldDispose(el) { - try {//IE下,如果文本节点脱离DOM树,访问parentNode会报错 - if (!el.parentNode) { - return true - } - } catch (e) { - return true - } - - return el.msRetain ? 0 : (el.nodeType === 1 ? !root.contains(el) : !avalon.contains(root, el)) -} - -/************************************************************************ - * HTML处理(parseHTML, innerHTML, clearHTML) * - ************************************************************************/ -// We have to close these tags to support XHTML -var tagHooks = { - area: [1, "", ""], - param: [1, "", ""], - col: [2, "", "
    "], - legend: [1, "

    ", "
    "], - option: [1, ""], - thead: [1, "", "
    "], - tr: [2, "", "
    "], - td: [3, "", "
    "], - g: [1, '', ''], - //IE6-8在用innerHTML生成节点时,不能直接创建no-scope元素与HTML5的新标签 - _default: W3C ? [0, "", ""] : [1, "X
    ", "
    "] //div可以不用闭合 -} -tagHooks.th = tagHooks.td -tagHooks.optgroup = tagHooks.option -tagHooks.tbody = tagHooks.tfoot = tagHooks.colgroup = tagHooks.caption = tagHooks.thead -String("circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use").replace(rword, function (tag) { - tagHooks[tag] = tagHooks.g //处理SVG -}) -var rtagName = /<([\w:]+)/ //取得其tagName -var rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig -var rcreate = W3C ? /[^\d\D]/ : /(<(?:script|link|style|meta|noscript))/ig -var scriptTypes = oneObject(["", "text/javascript", "text/ecmascript", "application/ecmascript", "application/javascript"]) -var rnest = /<(?:tb|td|tf|th|tr|col|opt|leg|cap|area)/ //需要处理套嵌关系的标签 -var script = DOC.createElement("script") -var rhtml = /<|&#?\w+;/ -avalon.parseHTML = function (html) { - var fragment = avalonFragment.cloneNode(false) - if (typeof html !== "string") { - return fragment - } - if (!rhtml.test(html)) { - fragment.appendChild(DOC.createTextNode(html)) - return fragment - } - html = html.replace(rxhtml, "<$1>").trim() - var tag = (rtagName.exec(html) || ["", ""])[1].toLowerCase(), - //取得其标签名 - wrap = tagHooks[tag] || tagHooks._default, - wrapper = cinerator, - firstChild, neo - if (!W3C) { //fix IE - html = html.replace(rcreate, "
    $1") //在link style script等标签之前添加一个补丁 - } - wrapper.innerHTML = wrap[1] + html + wrap[2] - var els = wrapper.getElementsByTagName("script") - if (els.length) { //使用innerHTML生成的script节点不会发出请求与执行text属性 - for (var i = 0, el; el = els[i++]; ) { - if (scriptTypes[el.type]) { - //以偷龙转凤方式恢复执行脚本功能 - neo = script.cloneNode(false) //FF不能省略参数 - ap.forEach.call(el.attributes, function (attr) { - if (attr && attr.specified) { - neo[attr.name] = attr.value //复制其属性 - neo.setAttribute(attr.name, attr.value) - } - }) // jshint ignore:line - neo.text = el.text - el.parentNode.replaceChild(neo, el) //替换节点 - } - } - } - if (!W3C) { //fix IE - var target = wrap[1] === "X
    " ? wrapper.lastChild.firstChild : wrapper.lastChild - if (target && target.tagName === "TABLE" && tag !== "tbody") { - //IE6-7处理 --> , - // --> , - // -->
    - for (els = target.childNodes, i = 0; el = els[i++]; ) { - if (el.tagName === "TBODY" && !el.innerHTML) { - target.removeChild(el) - break - } - } - } - els = wrapper.getElementsByTagName("br") - var n = els.length - while (el = els[--n]) { - if (el.className === "msNoScope") { - el.parentNode.removeChild(el) - } - } - for (els = wrapper.all, i = 0; el = els[i++]; ) { //fix VML - if (isVML(el)) { - fixVML(el) - } - } - } - //移除我们为了符合套嵌关系而添加的标签 - for (i = wrap[0]; i--; wrapper = wrapper.lastChild) { - } - while (firstChild = wrapper.firstChild) { // 将wrapper上的节点转移到文档碎片上! - fragment.appendChild(firstChild) - } - return fragment -} - -function isVML(src) { - var nodeName = src.nodeName - return nodeName.toLowerCase() === nodeName && src.scopeName && src.outerText === "" -} - -function fixVML(node) { - if (node.currentStyle.behavior !== "url(#default#VML)") { - node.style.behavior = "url(#default#VML)" - node.style.display = "inline-block" - node.style.zoom = 1 //hasLayout - } -} -avalon.innerHTML = function (node, html) { - if (!W3C && (!rcreate.test(html) && !rnest.test(html))) { - try { - node.innerHTML = html - return - } catch (e) { - } - } - var a = this.parseHTML(html) - this.clearHTML(node).appendChild(a) -} -avalon.clearHTML = function (node) { - node.textContent = "" - while (node.firstChild) { - node.removeChild(node.firstChild) - } - return node -} - -/********************************************************************* - * avalon的原型方法定义区 * - **********************************************************************/ - -function hyphen(target) { - //转换为连字符线风格 - return target.replace(/([a-z\d])([A-Z]+)/g, "$1-$2").toLowerCase() -} - -function camelize(target) { - //提前判断,提高getStyle等的效率 - if (!target || target.indexOf("-") < 0 && target.indexOf("_") < 0) { - return target - } - //转换为驼峰风格 - return target.replace(/[-_][^-_]/g, function(match) { - return match.charAt(1).toUpperCase() - }) -} - -var fakeClassListMethods = { - _toString: function() { - var node = this.node - var cls = node.className - var str = typeof cls === "string" ? cls : cls.baseVal - return str.split(/\s+/).join(" ") - }, - _contains: function(cls) { - return (" " + this + " ").indexOf(" " + cls + " ") > -1 - }, - _add: function(cls) { - if (!this.contains(cls)) { - this._set(this + " " + cls) - } - }, - _remove: function(cls) { - this._set((" " + this + " ").replace(" " + cls + " ", " ")) - }, - __set: function(cls) { - cls = cls.trim() - var node = this.node - if (rsvg.test(node)) { - //SVG元素的className是一个对象 SVGAnimatedString { baseVal="", animVal=""},只能通过set/getAttribute操作 - node.setAttribute("class", cls) - } else { - node.className = cls - } - } //toggle存在版本差异,因此不使用它 -} - - function fakeClassList(node) { - if (!("classList" in node)) { - node.classList = { - node: node - } - for (var k in fakeClassListMethods) { - node.classList[k.slice(1)] = fakeClassListMethods[k] - } - } - return node.classList - } - - - "add,remove".replace(rword, function(method) { - avalon.fn[method + "Class"] = function(cls) { - var el = this[0] - //https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/26 - if (cls && typeof cls === "string" && el && el.nodeType === 1) { - cls.replace(/\S+/g, function(c) { - fakeClassList(el)[method](c) - }) - } - return this - } - }) - avalon.fn.mix({ - hasClass: function(cls) { - var el = this[0] || {} - return el.nodeType === 1 && fakeClassList(el).contains(cls) - }, - toggleClass: function(value, stateVal) { - var className, i = 0 - var classNames = String(value).split(/\s+/) - var isBool = typeof stateVal === "boolean" - while ((className = classNames[i++])) { - var state = isBool ? stateVal : !this.hasClass(className) - this[state ? "addClass" : "removeClass"](className) - } - return this - }, - attr: function(name, value) { - if (arguments.length === 2) { - this[0].setAttribute(name, value) - return this - } else { - return this[0].getAttribute(name) - } - }, - data: function(name, value) { - name = "data-" + hyphen(name || "") - switch (arguments.length) { - case 2: - this.attr(name, value) - return this - case 1: - var val = this.attr(name) - return parseData(val) - case 0: - var ret = {} - ap.forEach.call(this[0].attributes, function(attr) { - if (attr) { - name = attr.name - if (!name.indexOf("data-")) { - name = camelize(name.slice(5)) - ret[name] = parseData(attr.value) - } - } - }) - return ret - } - }, - removeData: function(name) { - name = "data-" + hyphen(name) - this[0].removeAttribute(name) - return this - }, - css: function(name, value) { - if (avalon.isPlainObject(name)) { - for (var i in name) { - avalon.css(this, i, name[i]) - } - } else { - var ret = avalon.css(this, name, value) - } - return ret !== void 0 ? ret : this - }, - position: function() { - var offsetParent, offset, - elem = this[0], - parentOffset = { - top: 0, - left: 0 - } - if (!elem) { - return - } - if (this.css("position") === "fixed") { - offset = elem.getBoundingClientRect() - } else { - offsetParent = this.offsetParent() //得到真正的offsetParent - offset = this.offset() // 得到正确的offsetParent - if (offsetParent[0].tagName !== "HTML") { - parentOffset = offsetParent.offset() - } - parentOffset.top += avalon.css(offsetParent[0], "borderTopWidth", true) - parentOffset.left += avalon.css(offsetParent[0], "borderLeftWidth", true) - - // Subtract offsetParent scroll positions - parentOffset.top -= offsetParent.scrollTop() - parentOffset.left -= offsetParent.scrollLeft() - } - return { - top: offset.top - parentOffset.top - avalon.css(elem, "marginTop", true), - left: offset.left - parentOffset.left - avalon.css(elem, "marginLeft", true) - } - }, - offsetParent: function() { - var offsetParent = this[0].offsetParent - while (offsetParent && avalon.css(offsetParent, "position") === "static") { - offsetParent = offsetParent.offsetParent; - } - return avalon(offsetParent || root) - }, - bind: function(type, fn, phase) { - if (this[0]) { //此方法不会链 - return avalon.bind(this[0], type, fn, phase) - } - }, - unbind: function(type, fn, phase) { - if (this[0]) { - avalon.unbind(this[0], type, fn, phase) - } - return this - }, - val: function(value) { - var node = this[0] - if (node && node.nodeType === 1) { - var get = arguments.length === 0 - var access = get ? ":get" : ":set" - var fn = valHooks[getValType(node) + access] - if (fn) { - var val = fn(node, value) - } else if (get) { - return (node.value || "").replace(/\r/g, "") - } else { - node.value = value - } - } - return get ? val : this - } - }) - - function parseData(data) { - try { - if (typeof data === "object") - return data - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : +data + "" === data ? +data : rbrace.test(data) ? avalon.parseJSON(data) : data - } catch (e) {} - return data - } -var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, - rvalidchars = /^[\],:{}\s]*$/, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, - rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g -avalon.parseJSON = window.JSON ? JSON.parse : function(data) { - if (typeof data === "string") { - data = data.trim(); - if (data) { - if (rvalidchars.test(data.replace(rvalidescape, "@") - .replace(rvalidtokens, "]") - .replace(rvalidbraces, ""))) { - return (new Function("return " + data))() // jshint ignore:line - } - } - avalon.error("Invalid JSON: " + data) - } - return data -} - -//生成avalon.fn.scrollLeft, avalon.fn.scrollTop方法 -avalon.each({ - scrollLeft: "pageXOffset", - scrollTop: "pageYOffset" -}, function(method, prop) { - avalon.fn[method] = function(val) { - var node = this[0] || {}, win = getWindow(node), - top = method === "scrollTop" - if (!arguments.length) { - return win ? (prop in win) ? win[prop] : root[method] : node[method] - } else { - if (win) { - win.scrollTo(!top ? val : avalon(win).scrollLeft(), top ? val : avalon(win).scrollTop()) - } else { - node[method] = val - } - } - } -}) - -function getWindow(node) { - return node.window && node.document ? node : node.nodeType === 9 ? node.defaultView || node.parentWindow : false; -} -//=============================css相关======================= -var cssHooks = avalon.cssHooks = {} -var prefixes = ["", "-webkit-", "-o-", "-moz-", "-ms-"] -var cssMap = { - "float": W3C ? "cssFloat" : "styleFloat" -} -avalon.cssNumber = oneObject("columnCount,order,fillOpacity,fontWeight,lineHeight,opacity,orphans,widows,zIndex,zoom") - -avalon.cssName = function(name, host, camelCase) { - if (cssMap[name]) { - return cssMap[name] - } - host = host || root.style - for (var i = 0, n = prefixes.length; i < n; i++) { - camelCase = camelize(prefixes[i] + name) - if (camelCase in host) { - return (cssMap[name] = camelCase) - } - } - return null -} -cssHooks["@:set"] = function(node, name, value) { - try { //node.style.width = NaN;node.style.width = "xxxxxxx";node.style.width = undefine 在旧式IE下会抛异常 - node.style[name] = value - } catch (e) {} -} -if (window.getComputedStyle) { - cssHooks["@:get"] = function(node, name) { - if (!node || !node.style) { - throw new Error("getComputedStyle要求传入一个节点 " + node) - } - var ret, styles = getComputedStyle(node, null) - if (styles) { - ret = name === "filter" ? styles.getPropertyValue(name) : styles[name] - if (ret === "") { - ret = node.style[name] //其他浏览器需要我们手动取内联样式 - } - } - return ret - } - cssHooks["opacity:get"] = function(node) { - var ret = cssHooks["@:get"](node, "opacity") - return ret === "" ? "1" : ret - } -} else { - var rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i - var rposition = /^(top|right|bottom|left)$/ - var ralpha = /alpha\([^)]*\)/i - var ie8 = !! window.XDomainRequest - var salpha = "DXImageTransform.Microsoft.Alpha" - var border = { - thin: ie8 ? '1px' : '2px', - medium: ie8 ? '3px' : '4px', - thick: ie8 ? '5px' : '6px' - } - cssHooks["@:get"] = function(node, name) { - //取得精确值,不过它有可能是带em,pc,mm,pt,%等单位 - var currentStyle = node.currentStyle - var ret = currentStyle[name] - if ((rnumnonpx.test(ret) && !rposition.test(ret))) { - //①,保存原有的style.left, runtimeStyle.left, - var style = node.style, - left = style.left, - rsLeft = node.runtimeStyle.left - //②由于③处的style.left = xxx会影响到currentStyle.left, - //因此把它currentStyle.left放到runtimeStyle.left, - //runtimeStyle.left拥有最高优先级,不会style.left影响 - node.runtimeStyle.left = currentStyle.left - //③将精确值赋给到style.left,然后通过IE的另一个私有属性 style.pixelLeft - //得到单位为px的结果;fontSize的分支见http://bugs.jquery.com/ticket/760 - style.left = name === 'fontSize' ? '1em' : (ret || 0) - ret = style.pixelLeft + "px" - //④还原 style.left,runtimeStyle.left - style.left = left - node.runtimeStyle.left = rsLeft - } - if (ret === "medium") { - name = name.replace("Width", "Style") - //border width 默认值为medium,即使其为0" - if (currentStyle[name] === "none") { - ret = "0px" - } - } - return ret === "" ? "auto" : border[ret] || ret - } - cssHooks["opacity:set"] = function(node, name, value) { - var style = node.style - var opacity = isFinite(value) && value <= 1 ? "alpha(opacity=" + value * 100 + ")" : "" - var filter = style.filter || ""; - style.zoom = 1 - //不能使用以下方式设置透明度 - //node.filters.alpha.opacity = value * 100 - style.filter = (ralpha.test(filter) ? - filter.replace(ralpha, opacity) : - filter + " " + opacity).trim() - if (!style.filter) { - style.removeAttribute("filter") - } - } - cssHooks["opacity:get"] = function(node) { - //这是最快的获取IE透明值的方式,不需要动用正则了! - var alpha = node.filters.alpha || node.filters[salpha], - op = alpha && alpha.enabled ? alpha.opacity : 100 - return (op / 100) + "" //确保返回的是字符串 - } -} - -"top,left".replace(rword, function(name) { - cssHooks[name + ":get"] = function(node) { - var computed = cssHooks["@:get"](node, name) - return /px$/.test(computed) ? computed : - avalon(node).position()[name] + "px" - } -}) - -var cssShow = { - position: "absolute", - visibility: "hidden", - display: "block" -} - -var rdisplayswap = /^(none|table(?!-c[ea]).+)/ - - function showHidden(node, array) { - //http://www.cnblogs.com/rubylouvre/archive/2012/10/27/2742529.html - if (node.offsetWidth <= 0) { //opera.offsetWidth可能小于0 - if (rdisplayswap.test(cssHooks["@:get"](node, "display"))) { - var obj = { - node: node - } - for (var name in cssShow) { - obj[name] = node.style[name] - node.style[name] = cssShow[name] - } - array.push(obj) - } - var parent = node.parentNode - if (parent && parent.nodeType === 1) { - showHidden(parent, array) - } - } - } - "Width,Height".replace(rword, function(name) { //fix 481 - var method = name.toLowerCase(), - clientProp = "client" + name, - scrollProp = "scroll" + name, - offsetProp = "offset" + name - cssHooks[method + ":get"] = function(node, which, override) { - var boxSizing = -4 - if (typeof override === "number") { - boxSizing = override - } - which = name === "Width" ? ["Left", "Right"] : ["Top", "Bottom"] - var ret = node[offsetProp] // border-box 0 - if (boxSizing === 2) { // margin-box 2 - return ret + avalon.css(node, "margin" + which[0], true) + avalon.css(node, "margin" + which[1], true) - } - if (boxSizing < 0) { // padding-box -2 - ret = ret - avalon.css(node, "border" + which[0] + "Width", true) - avalon.css(node, "border" + which[1] + "Width", true) - } - if (boxSizing === -4) { // content-box -4 - ret = ret - avalon.css(node, "padding" + which[0], true) - avalon.css(node, "padding" + which[1], true) - } - return ret - } - cssHooks[method + "&get"] = function(node) { - var hidden = []; - showHidden(node, hidden); - var val = cssHooks[method + ":get"](node) - for (var i = 0, obj; obj = hidden[i++];) { - node = obj.node - for (var n in obj) { - if (typeof obj[n] === "string") { - node.style[n] = obj[n] - } - } - } - return val; - } - avalon.fn[method] = function(value) { //会忽视其display - var node = this[0] - if (arguments.length === 0) { - if (node.setTimeout) { //取得窗口尺寸,IE9后可以用node.innerWidth /innerHeight代替 - return node["inner" + name] || node.document.documentElement[clientProp] - } - if (node.nodeType === 9) { //取得页面尺寸 - var doc = node.documentElement - //FF chrome html.scrollHeight< body.scrollHeight - //IE 标准模式 : html.scrollHeight> body.scrollHeight - //IE 怪异模式 : html.scrollHeight 最大等于可视窗口多一点? - return Math.max(node.body[scrollProp], doc[scrollProp], node.body[offsetProp], doc[offsetProp], doc[clientProp]) - } - return cssHooks[method + "&get"](node) - } else { - return this.css(method, value) - } - } - avalon.fn["inner" + name] = function() { - return cssHooks[method + ":get"](this[0], void 0, -2) - } - avalon.fn["outer" + name] = function(includeMargin) { - return cssHooks[method + ":get"](this[0], void 0, includeMargin === true ? 2 : 0) - } - }) - avalon.fn.offset = function() { //取得距离页面左右角的坐标 - var node = this[0], - box = { - left: 0, - top: 0 - } - if (!node || !node.tagName || !node.ownerDocument) { - return box - } - var doc = node.ownerDocument, - body = doc.body, - root = doc.documentElement, - win = doc.defaultView || doc.parentWindow - if (!avalon.contains(root, node)) { - return box - } - //http://hkom.blog1.fc2.com/?mode=m&no=750 body的偏移量是不包含margin的 - //我们可以通过getBoundingClientRect来获得元素相对于client的rect. - //http://msdn.microsoft.com/en-us/library/ms536433.aspx - if (node.getBoundingClientRect) { - box = node.getBoundingClientRect() // BlackBerry 5, iOS 3 (original iPhone) - } - //chrome/IE6: body.scrollTop, firefox/other: root.scrollTop - var clientTop = root.clientTop || body.clientTop, - clientLeft = root.clientLeft || body.clientLeft, - scrollTop = Math.max(win.pageYOffset || 0, root.scrollTop, body.scrollTop), - scrollLeft = Math.max(win.pageXOffset || 0, root.scrollLeft, body.scrollLeft) - // 把滚动距离加到left,top中去。 - // IE一些版本中会自动为HTML元素加上2px的border,我们需要去掉它 - // http://msdn.microsoft.com/en-us/library/ms533564(VS.85).aspx - return { - top: box.top + scrollTop - clientTop, - left: box.left + scrollLeft - clientLeft - } - } - - //==================================val相关============================ - - function getValType(elem) { - var ret = elem.tagName.toLowerCase() - return ret === "input" && /checkbox|radio/.test(elem.type) ? "checked" : ret - } -var roption = /^]+))?)*\s+value[\s=]/i -var valHooks = { - "option:get": IEVersion ? function(node) { - //在IE11及W3C,如果没有指定value,那么node.value默认为node.text(存在trim作),但IE9-10则是取innerHTML(没trim操作) - //specified并不可靠,因此通过分析outerHTML判定用户有没有显示定义value - return roption.test(node.outerHTML) ? node.value : node.text.trim() - } : function(node) { - return node.value - }, - "select:get": function(node, value) { - var option, options = node.options, - index = node.selectedIndex, - getter = valHooks["option:get"], - one = node.type === "select-one" || index < 0, - values = one ? null : [], - max = one ? index + 1 : options.length, - i = index < 0 ? max : one ? index : 0 - for (; i < max; i++) { - option = options[i] - //旧式IE在reset后不会改变selected,需要改用i === index判定 - //我们过滤所有disabled的option元素,但在safari5下,如果设置select为disable,那么其所有孩子都disable - //因此当一个元素为disable,需要检测其是否显式设置了disable及其父节点的disable情况 - if ((option.selected || i === index) && !option.disabled) { - value = getter(option) - if (one) { - return value - } - //收集所有selected值组成数组返回 - values.push(value) - } - } - return values - }, - "select:set": function(node, values, optionSet) { - values = [].concat(values) //强制转换为数组 - var getter = valHooks["option:get"] - for (var i = 0, el; el = node.options[i++];) { - if ((el.selected = values.indexOf(getter(el)) > -1)) { - optionSet = true - } - } - if (!optionSet) { - node.selectedIndex = -1 - } - } -} - -/********************************************************************* - * 编译系统 * - **********************************************************************/ -var meta = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"': '\\"', - '\\': '\\\\' -} -var quote = window.JSON && JSON.stringify || function(str) { - return '"' + str.replace(/[\\\"\x00-\x1f]/g, function(a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' -} - -var keywords = [ - "break,case,catch,continue,debugger,default,delete,do,else,false", - "finally,for,function,if,in,instanceof,new,null,return,switch,this", - "throw,true,try,typeof,var,void,while,with", /* 关键字*/ - "abstract,boolean,byte,char,class,const,double,enum,export,extends", - "final,float,goto,implements,import,int,interface,long,native", - "package,private,protected,public,short,static,super,synchronized", - "throws,transient,volatile", /*保留字*/ - "arguments,let,yield,undefined" /* ECMA 5 - use strict*/].join(",") -var rrexpstr = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g -var rsplit = /[^\w$]+/g -var rkeywords = new RegExp(["\\b" + keywords.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g') -var rnumber = /\b\d[^,]*/g -var rcomma = /^,+|,+$/g -var variablePool = new Cache(512) -var getVariables = function (code) { - var key = "," + code.trim() - var ret = variablePool.get(key) - if (ret) { - return ret - } - var match = code - .replace(rrexpstr, "") - .replace(rsplit, ",") - .replace(rkeywords, "") - .replace(rnumber, "") - .replace(rcomma, "") - .split(/^$|,+/) - return variablePool.put(key, uniqSet(match)) -} -/*添加赋值语句*/ - -function addAssign(vars, scope, name, data) { - var ret = [], - prefix = " = " + name + "." - for (var i = vars.length, prop; prop = vars[--i]; ) { - if (scope.hasOwnProperty(prop)) { - ret.push(prop + prefix + prop) - data.vars.push(prop) - if (data.type === "duplex") { - vars.get = name + "." + prop - } - vars.splice(i, 1) - } - } - return ret -} - -function uniqSet(array) { - var ret = [], - unique = {} - for (var i = 0; i < array.length; i++) { - var el = array[i] - var id = el && typeof el.$id === "string" ? el.$id : el - if (!unique[id]) { - unique[id] = ret.push(el) - } - } - return ret -} -//缓存求值函数,以便多次利用 -var evaluatorPool = new Cache(128) -//取得求值函数及其传参 -var rduplex = /\w\[.*\]|\w\.\w/ -var rproxy = /(\$proxy\$[a-z]+)\d+$/ -var rthimRightParentheses = /\)\s*$/ -var rthimOtherParentheses = /\)\s*\|/g -var rquoteFilterName = /\|\s*([$\w]+)/g -var rpatchBracket = /"\s*\["/g -var rthimLeftParentheses = /"\s*\(/g -function parseFilter(val, filters) { - filters = filters - .replace(rthimRightParentheses, "")//处理最后的小括号 - .replace(rthimOtherParentheses, function () {//处理其他小括号 - return "],|" - }) - .replace(rquoteFilterName, function (a, b) { //处理|及它后面的过滤器的名字 - return "[" + quote(b) - }) - .replace(rpatchBracket, function () { - return '"],["' - }) - .replace(rthimLeftParentheses, function () { - return '",' - }) + "]" - return "return avalon.filters.$filter(" + val + ", " + filters + ")" -} - -function parseExpr(code, scopes, data) { - var dataType = data.type - var filters = data.filters || "" - var exprId = scopes.map(function (el) { - return String(el.$id).replace(rproxy, "$1") - }) + code + dataType + filters - var vars = getVariables(code).concat(), - assigns = [], - names = [], - args = [], - prefix = "" - //args 是一个对象数组, names 是将要生成的求值函数的参数 - scopes = uniqSet(scopes) - data.vars = [] - for (var i = 0, sn = scopes.length; i < sn; i++) { - if (vars.length) { - var name = "vm" + expose + "_" + i - names.push(name) - args.push(scopes[i]) - assigns.push.apply(assigns, addAssign(vars, scopes[i], name, data)) - } - } - if (!assigns.length && dataType === "duplex") { - return - } - if (dataType !== "duplex" && (code.indexOf("||") > -1 || code.indexOf("&&") > -1)) { - //https://github.com/RubyLouvre/avalon/issues/583 - data.vars.forEach(function (v) { - var reg = new RegExp("\\b" + v + "(?:\\.\\w+|\\[\\w+\\])+", "ig") - code = code.replace(reg, function (_) { - var c = _.charAt(v.length) - var r = IEVersion ? code.slice(arguments[1] + _.length) : RegExp.rightContext - var method = /^\s*\(/.test(r) - if (c === "." || c === "[" || method) {//比如v为aa,我们只匹配aa.bb,aa[cc],不匹配aaa.xxx - var name = "var" + String(Math.random()).replace(/^0\./, "") - if (method) {//array.size() - var array = _.split(".") - if (array.length > 2) { - var last = array.pop() - assigns.push(name + " = " + array.join(".")) - return name + "." + last - } else { - return _ - } - } - assigns.push(name + " = " + _) - return name - } else { - return _ - } - }) - }) - } - //---------------args---------------- - data.args = args - //---------------cache---------------- - delete data.vars - var fn = evaluatorPool.get(exprId) //直接从缓存,免得重复生成 - if (fn) { - data.evaluator = fn - return - } - prefix = assigns.join(", ") - if (prefix) { - prefix = "var " + prefix - } - if (/\S/.test(filters)) { //文本绑定,双工绑定才有过滤器 - if (!/text|html/.test(data.type)) { - throw Error("ms-" + data.type + "不支持过滤器") - } - code = "\nvar ret" + expose + " = " + code + ";\r\n" - code += parseFilter("ret" + expose, filters) - } else if (dataType === "duplex") { //双工绑定 - var _body = "'use strict';\nreturn function(vvv){\n\t" + - prefix + - ";\n\tif(!arguments.length){\n\t\treturn " + - code + - "\n\t}\n\t" + (!rduplex.test(code) ? vars.get : code) + - "= vvv;\n} " - try { - fn = Function.apply(noop, names.concat(_body)) - data.evaluator = evaluatorPool.put(exprId, fn) - } catch (e) { - log("debug: parse error," + e.message) - } - return - } else if (dataType === "on") { //事件绑定 - if (code.indexOf("(") === -1) { - code += ".call(this, $event)" - } else { - code = code.replace("(", ".call(this,") - } - names.push("$event") - code = "\nreturn " + code + ";" //IE全家 Function("return ")出错,需要Function("return ;") - var lastIndex = code.lastIndexOf("\nreturn") - var header = code.slice(0, lastIndex) - var footer = code.slice(lastIndex) - code = header + "\n" + footer - } else { //其他绑定 - code = "\nreturn " + code + ";" //IE全家 Function("return ")出错,需要Function("return ;") - } - try { - fn = Function.apply(noop, names.concat("'use strict';\n" + prefix + code)) - data.evaluator = evaluatorPool.put(exprId, fn) - } catch (e) { - log("debug: parse error," + e.message) - } finally { - vars = assigns = names = null //释放内存 - } -} - - -//parseExpr的智能引用代理 - -function parseExprProxy(code, scopes, data, tokens, noRegister) { - if (Array.isArray(tokens)) { - code = tokens.map(function (el) { - return el.expr ? "(" + el.value + ")" : quote(el.value) - }).join(" + ") - } - parseExpr(code, scopes, data) - if (data.evaluator && !noRegister) { - data.handler = bindingExecutors[data.handlerName || data.type] - //方便调试 - //这里非常重要,我们通过判定视图刷新函数的element是否在DOM树决定 - //将它移出订阅者列表 - avalon.injectBinding(data) - } -} -avalon.parseExprProxy = parseExprProxy -/********************************************************************* - * 扫描系统 * - **********************************************************************/ - -avalon.scan = function(elem, vmodel) { - elem = elem || root - var vmodels = vmodel ? [].concat(vmodel) : [] - scanTag(elem, vmodels) -} - -//http://www.w3.org/TR/html5/syntax.html#void-elements -var stopScan = oneObject("area,base,basefont,br,col,command,embed,hr,img,input,link,meta,param,source,track,wbr,noscript,script,style,textarea".toUpperCase()) - -function checkScan(elem, callback, innerHTML) { - var id = setTimeout(function() { - var currHTML = elem.innerHTML - clearTimeout(id) - if (currHTML === innerHTML) { - callback() - } else { - checkScan(elem, callback, currHTML) - } - }) -} - - -function createSignalTower(elem, vmodel) { - var id = elem.getAttribute("avalonctrl") || vmodel.$id - elem.setAttribute("avalonctrl", id) - vmodel.$events.expr = elem.tagName + '[avalonctrl="' + id + '"]' -} - -var getBindingCallback = function(elem, name, vmodels) { - var callback = elem.getAttribute(name) - if (callback) { - for (var i = 0, vm; vm = vmodels[i++]; ) { - if (vm.hasOwnProperty(callback) && typeof vm[callback] === "function") { - return vm[callback] - } - } - } -} - -function executeBindings(bindings, vmodels) { - for (var i = 0, data; data = bindings[i++]; ) { - data.vmodels = vmodels - bindingHandlers[data.type](data, vmodels) - if (data.evaluator && data.element && data.element.nodeType === 1) { //移除数据绑定,防止被二次解析 - //chrome使用removeAttributeNode移除不存在的特性节点时会报错 https://github.com/RubyLouvre/avalon/issues/99 - data.element.removeAttribute(data.name) - } - } - bindings.length = 0 -} - -//https://github.com/RubyLouvre/avalon/issues/636 -var mergeTextNodes = IEVersion && window.MutationObserver ? function (elem) { - var node = elem.firstChild, text - while (node) { - var aaa = node.nextSibling - if (node.nodeType === 3) { - if (text) { - text.nodeValue += node.nodeValue - elem.removeChild(node) - } else { - text = node - } - } else { - text = null - } - node = aaa - } -} : 0 -var roneTime = /^\s*::/ -var rmsAttr = /ms-(\w+)-?(.*)/ -var priorityMap = { - "if": 10, - "repeat": 90, - "data": 100, - "widget": 110, - "each": 1400, - "with": 1500, - "duplex": 2000, - "on": 3000 -} - -var events = oneObject("animationend,blur,change,input,click,dblclick,focus,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,scan,scroll,submit") -var obsoleteAttrs = oneObject("value,title,alt,checked,selected,disabled,readonly,enabled") -function bindingSorter(a, b) { - return a.priority - b.priority -} - -function scanAttr(elem, vmodels, match) { - var scanNode = true - if (vmodels.length) { - var attributes = getAttributes ? getAttributes(elem) : elem.attributes - var bindings = [] - var fixAttrs = [] - var msData = {} - for (var i = 0, attr; attr = attributes[i++]; ) { - if (attr.specified) { - if (match = attr.name.match(rmsAttr)) { - //如果是以指定前缀命名的 - var type = match[1] - var param = match[2] || "" - var value = attr.value - var name = attr.name - if (events[type]) { - param = type - type = "on" - } else if (obsoleteAttrs[type]) { - if (type === "enabled") {//吃掉ms-enabled绑定,用ms-disabled代替 - log("warning!ms-enabled或ms-attr-enabled已经被废弃") - type = "disabled" - value = "!(" + value + ")" - } - param = type - type = "attr" - name = "ms-" + type + "-"+ param - fixAttrs.push([attr.name, name, value]) - } - msData[name] = value - if (typeof bindingHandlers[type] === "function") { - var newValue = value.replace(roneTime, "") - var oneTime = value !== newValue - var binding = { - type: type, - param: param, - element: elem, - name: name, - value: newValue, - oneTime: oneTime, - uuid: name+"-"+getUid(elem), - //chrome与firefox下Number(param)得到的值不一样 #855 - priority: (priorityMap[type] || type.charCodeAt(0) * 10 )+ (Number(param.replace(/\D/g, "")) || 0) - } - if (type === "html" || type === "text") { - var token = getToken(value) - avalon.mix(binding, token) - binding.filters = binding.filters.replace(rhasHtml, function () { - binding.type = "html" - binding.group = 1 - return "" - })// jshint ignore:line - } else if (type === "duplex") { - var hasDuplex = name - } else if (name === "ms-if-loop") { - binding.priority += 100 - } - bindings.push(binding) - if (type === "widget") { - elem.msData = elem.msData || msData - } - } - } - } - } - if (bindings.length) { - bindings.sort(bindingSorter) - fixAttrs.forEach(function (arr) { - log("warning!请改用" + arr[1] + "代替" + arr[0] + "!") - elem.removeAttribute(arr[0]) - elem.setAttribute(arr[1], arr[2]) - }) - //http://bugs.jquery.com/ticket/7071 - //在IE下对VML读取type属性,会让此元素所有属性都变成 - if (hasDuplex) { - if (msData["ms-attr-checked"]) { - log("warning!一个控件不能同时定义ms-attr-checked与" + hasDuplex) - } - if (msData["ms-attr-value"]) { - log("warning!一个控件不能同时定义ms-attr-value与" + hasDuplex) - } - } - for (i = 0; binding = bindings[i]; i++) { - type = binding.type - if (rnoscanAttrBinding.test(type)) { - return executeBindings(bindings.slice(0, i + 1), vmodels) - } else if (scanNode) { - scanNode = !rnoscanNodeBinding.test(type) - } - } - executeBindings(bindings, vmodels) - } - } - if (scanNode && !stopScan[elem.tagName] && rbind.test(elem.innerHTML.replace(rlt, "<").replace(rgt, ">"))) { - mergeTextNodes && mergeTextNodes(elem) - scanNodeList(elem, vmodels) //扫描子孙元素 - } -} -var rnoscanAttrBinding = /^if|widget|repeat$/ -var rnoscanNodeBinding = /^each|with|html|include$/ -//IE67下,在循环绑定中,一个节点如果是通过cloneNode得到,自定义属性的specified为false,无法进入里面的分支, -//但如果我们去掉scanAttr中的attr.specified检测,一个元素会有80+个特性节点(因为它不区分固有属性与自定义属性),很容易卡死页面 -if (!"1" [0]) { - var attrPool = new Cache(512) - var rattrs = /\s+(ms-[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g, - rquote = /^['"]/, - rtag = /<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/i, - ramp = /&/g - //IE6-8解析HTML5新标签,会将它分解两个元素节点与一个文本节点 - //
    ddd
    - // window.onload = function() { - // var body = document.body - // for (var i = 0, el; el = body.children[i++]; ) { - // avalon.log(el.outerHTML) - // } - // } - //依次输出
    ,
    - var getAttributes = function (elem) { - var html = elem.outerHTML - //处理IE6-8解析HTML5新标签的情况,及
    等半闭合标签outerHTML为空的情况 - if (html.slice(0, 2) === " ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100) - //--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后 - var a = elem.getAttribute("ms-skip") - //#360 在旧式IE中 Object标签在引入Flash等资源时,可能出现没有getAttributeNode,innerHTML的情形 - if (!elem.getAttributeNode) { - return log("warning " + elem.tagName + " no getAttributeNode method") - } - var b = elem.getAttributeNode("ms-important") - var c = elem.getAttributeNode("ms-controller") - if (typeof a === "string") { - return - } else if (node = b || c) { - var newVmodel = avalon.vmodels[node.value] - if (!newVmodel) { - return - } - //ms-important不包含父VM,ms-controller相反 - vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels) - var name = node.name - elem.removeAttribute(name) //removeAttributeNode不会刷新[ms-controller]样式规则 - avalon(elem).removeClass(name) - createSignalTower(elem, newVmodel) - } - scanAttr(elem, vmodels) //扫描特性节点 -} -var rhasHtml = /\|\s*html(?:\b|$)/, - r11a = /\|\|/g, - rlt = /</g, - rgt = />/g, - rstringLiteral = /(['"])(\\\1|.)+?\1/g -function getToken(value) { - if (value.indexOf("|") > 0) { - var scapegoat = value.replace(rstringLiteral, function (_) { - return Array(_.length + 1).join("1")// jshint ignore:line - }) - var index = scapegoat.replace(r11a, "\u1122\u3344").indexOf("|") //干掉所有短路或 - if (index > -1) { - return { - filters: value.slice(index), - value: value.slice(0, index), - expr: true - } - } - } - return { - value: value, - filters: "", - expr: true - } -} - -function scanExpr(str) { - var tokens = [], - value, start = 0, - stop - do { - stop = str.indexOf(openTag, start) - if (stop === -1) { - break - } - value = str.slice(start, stop) - if (value) { // {{ 左边的文本 - tokens.push({ - value: value, - filters: "", - expr: false - }) - } - start = stop + openTag.length - stop = str.indexOf(closeTag, start) - if (stop === -1) { - break - } - value = str.slice(start, stop) - if (value) { //处理{{ }}插值表达式 - tokens.push(getToken(value, start)) - } - start = stop + closeTag.length - } while (1) - value = str.slice(start) - if (value) { //}} 右边的文本 - tokens.push({ - value: value, - expr: false, - filters: "" - }) - } - return tokens -} - -function scanText(textNode, vmodels, index) { - var bindings = [] - tokens = scanExpr(textNode.data) - if (tokens.length) { - for (var i = 0; token = tokens[i++]; ) { - var node = DOC.createTextNode(token.value) //将文本转换为文本节点,并替换原来的文本节点 - if (token.expr) { - token.value = token.value.replace(roneTime, function () { - token.oneTime = true - return "" - }) - token.type = "text" - token.element = node - token.filters = token.filters.replace(rhasHtml, function (a, b,c) { - token.type = "html" - return "" - })// jshint ignore:line - token.pos = index * 1000 + i - bindings.push(token) //收集带有插值表达式的文本 - } - avalonFragment.appendChild(node) - } - textNode.parentNode.replaceChild(avalonFragment, textNode) - if (bindings.length) - executeBindings(bindings, vmodels) - } -} - -var bools = ["autofocus,autoplay,async,allowTransparency,checked,controls", - "declare,disabled,defer,defaultChecked,defaultSelected", - "contentEditable,isMap,loop,multiple,noHref,noResize,noShade", - "open,readOnly,selected" -].join(",") -var boolMap = {} -bools.replace(rword, function(name) { - boolMap[name.toLowerCase()] = name -}) - -var propMap = { //属性名映射 - "accept-charset": "acceptCharset", - "char": "ch", - "charoff": "chOff", - "class": "className", - "for": "htmlFor", - "http-equiv": "httpEquiv" -} - -var anomaly = ["accessKey,bgColor,cellPadding,cellSpacing,codeBase,codeType,colSpan", - "dateTime,defaultValue,frameBorder,longDesc,maxLength,marginWidth,marginHeight", - "rowSpan,tabIndex,useMap,vSpace,valueType,vAlign" -].join(",") -anomaly.replace(rword, function(name) { - propMap[name.toLowerCase()] = name -}) - -var rnoscripts = /(?:[\s\S]+?)<\/noscript>/img -var rnoscriptText = /([\s\S]+?)<\/noscript>/im - -var getXHR = function() { - return new(window.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP") // jshint ignore:line -} - -var templatePool = avalon.templateCache = {} - -bindingHandlers.attr = function(data, vmodels) { - var text = data.value.trim(), - simple = true - if (text.indexOf(openTag) > -1 && text.indexOf(closeTag) > 2) { - simple = false - if (rexpr.test(text) && RegExp.rightContext === "" && RegExp.leftContext === "") { - simple = true - text = RegExp.$1 - } - } - if (data.type === "include") { - var elem = data.element - data.includeRendered = getBindingCallback(elem, "data-include-rendered", vmodels) - data.includeLoaded = getBindingCallback(elem, "data-include-loaded", vmodels) - var outer = data.includeReplace = !! avalon(elem).data("includeReplace") - if (avalon(elem).data("includeCache")) { - data.templateCache = {} - } - data.startInclude = DOC.createComment("ms-include") - data.endInclude = DOC.createComment("ms-include-end") - if (outer) { - data.element = data.startInclude - elem.parentNode.insertBefore(data.startInclude, elem) - elem.parentNode.insertBefore(data.endInclude, elem.nextSibling) - } else { - elem.insertBefore(data.startInclude, elem.firstChild) - elem.appendChild(data.endInclude) - } - } - data.handlerName = "attr" //handleName用于处理多种绑定共用同一种bindingExecutor的情况 - parseExprProxy(text, vmodels, data, (simple ? 0 : scanExpr(data.value))) -} - -bindingExecutors.attr = function(val, elem, data) { - var method = data.type, - attrName = data.param - if (method === "css") { - avalon(elem).css(attrName, val) - } else if (method === "attr") { - - // ms-attr-class="xxx" vm.xxx="aaa bbb ccc"将元素的className设置为aaa bbb ccc - // ms-attr-class="xxx" vm.xxx=false 清空元素的所有类名 - // ms-attr-name="yyy" vm.yyy="ooo" 为元素设置name属性 - var toRemove = (val === false) || (val === null) || (val === void 0) - - if (!W3C && propMap[attrName]) { //旧式IE下需要进行名字映射 - attrName = propMap[attrName] - } - var bool = boolMap[attrName] - if (typeof elem[bool] === "boolean") { - elem[bool] = !! val //布尔属性必须使用el.xxx = true|false方式设值 - if (!val) { //如果为false, IE全系列下相当于setAttribute(xxx,''),会影响到样式,需要进一步处理 - toRemove = true - } - } - if (toRemove) { - return elem.removeAttribute(attrName) - } - //SVG只能使用setAttribute(xxx, yyy), VML只能使用elem.xxx = yyy ,HTML的固有属性必须elem.xxx = yyy - var isInnate = rsvg.test(elem) ? false : (DOC.namespaces && isVML(elem)) ? true : attrName in elem.cloneNode(false) - if (isInnate) { - elem[attrName] = val+"" - } else { - elem.setAttribute(attrName, val) - } - } else if (method === "include" && val) { - var vmodels = data.vmodels - var rendered = data.includeRendered - var loaded = data.includeLoaded - var replace = data.includeReplace - var target = replace ? elem.parentNode : elem - var scanTemplate = function(text) { - if (loaded) { - var newText = loaded.apply(target, [text].concat(vmodels)) - if (typeof newText === "string") - text = newText - } - if (rendered) { - checkScan(target, function() { - rendered.call(target) - }, NaN) - } - var lastID = data.includeLastID - if (data.templateCache && lastID && lastID !== val) { - var lastTemplate = data.templateCache[lastID] - if (!lastTemplate) { - lastTemplate = data.templateCache[lastID] = DOC.createElement("div") - ifGroup.appendChild(lastTemplate) - } - } - data.includeLastID = val - while (true) { - var node = data.startInclude.nextSibling - if (node && node !== data.endInclude) { - target.removeChild(node) - if (lastTemplate) - lastTemplate.appendChild(node) - } else { - break - } - } - var dom = getTemplateNodes(data, val, text) - var nodes = avalon.slice(dom.childNodes) - target.insertBefore(dom, data.endInclude) - scanNodeArray(nodes, vmodels) - } - - if (data.param === "src") { - if (typeof templatePool[val] === "string") { - avalon.nextTick(function() { - scanTemplate(templatePool[val]) - }) - } else if (Array.isArray(templatePool[val])) { //#805 防止在循环绑定中发出许多相同的请求 - templatePool[val].push(scanTemplate) - } else { - var xhr = getXHR() - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - var s = xhr.status - if (s >= 200 && s < 300 || s === 304 || s === 1223) { - var text = xhr.responseText - for (var f = 0, fn; fn = templatePool[val][f++];) { - fn(text) - } - templatePool[val] = text - } - } - } - templatePool[val] = [scanTemplate] - xhr.open("GET", val, true) - if ("withCredentials" in xhr) { - xhr.withCredentials = true - } - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest") - xhr.send(null) - } - } else { - //IE系列与够新的标准浏览器支持通过ID取得元素(firefox14+) - //http://tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/ - var el = val && val.nodeType === 1 ? val : DOC.getElementById(val) - if (el) { - if (el.tagName === "NOSCRIPT" && !(el.innerHTML || el.fixIE78)) { //IE7-8 innerText,innerHTML都无法取得其内容,IE6能取得其innerHTML - xhr = getXHR() //IE9-11与chrome的innerHTML会得到转义的内容,它们的innerText可以 - xhr.open("GET", location, false) //谢谢Nodejs 乱炖群 深圳-纯属虚构 - xhr.send(null) - //http://bbs.csdn.net/topics/390349046?page=1#post-393492653 - var noscripts = DOC.getElementsByTagName("noscript") - var array = (xhr.responseText || "").match(rnoscripts) || [] - var n = array.length - for (var i = 0; i < n; i++) { - var tag = noscripts[i] - if (tag) { //IE6-8中noscript标签的innerHTML,innerText是只读的 - tag.style.display = "none" //http://haslayout.net/css/noscript-Ghost-Bug - tag.fixIE78 = (array[i].match(rnoscriptText) || ["", " "])[1] - } - } - } - avalon.nextTick(function() { - scanTemplate(el.fixIE78 || el.value || el.innerText || el.innerHTML) - }) - } - } - } else { - if (!root.hasAttribute && typeof val === "string" && (method === "src" || method === "href")) { - val = val.replace(/&/g, "&") //处理IE67自动转义的问题 - } - elem[method] = val - if (window.chrome && elem.tagName === "EMBED") { - var parent = elem.parentNode //#525 chrome1-37下embed标签动态设置src不能发生请求 - var comment = document.createComment("ms-src") - parent.replaceChild(comment, elem) - parent.replaceChild(elem, comment) - } - } -} - -function getTemplateNodes(data, id, text) { - var div = data.templateCache && data.templateCache[id] - if (div) { - var dom = DOC.createDocumentFragment(), - firstChild - while (firstChild = div.firstChild) { - dom.appendChild(firstChild) - } - return dom - } - return avalon.parseHTML(text) -} - -//这几个指令都可以使用插值表达式,如ms-src="aaa/{{b}}/{{c}}.html" -"title,alt,src,value,css,include,href".replace(rword, function(name) { - bindingHandlers[name] = bindingHandlers.attr -}) -//根据VM的属性值或表达式的值切换类名,ms-class="xxx yyy zzz:flag" -//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html -bindingHandlers["class"] = function(data, vmodels) { - var oldStyle = data.param, - text = data.value, - rightExpr - data.handlerName = "class" - if (!oldStyle || isFinite(oldStyle)) { - data.param = "" //去掉数字 - var noExpr = text.replace(rexprg, function(a) { - return a.replace(/./g, "0") - //return Math.pow(10, a.length - 1) //将插值表达式插入10的N-1次方来占位 - }) - var colonIndex = noExpr.indexOf(":") //取得第一个冒号的位置 - if (colonIndex === -1) { // 比如 ms-class="aaa bbb ccc" 的情况 - var className = text - } else { // 比如 ms-class-1="ui-state-active:checked" 的情况 - className = text.slice(0, colonIndex) - rightExpr = text.slice(colonIndex + 1) - parseExpr(rightExpr, vmodels, data) //决定是添加还是删除 - if (!data.evaluator) { - log("debug: ms-class '" + (rightExpr || "").trim() + "' 不存在于VM中") - return false - } else { - data._evaluator = data.evaluator - data._args = data.args - } - } - var hasExpr = rexpr.test(className) //比如ms-class="width{{w}}"的情况 - if (!hasExpr) { - data.immobileClass = className - } - parseExprProxy("", vmodels, data, (hasExpr ? scanExpr(className) : 0)) - } else { - data.immobileClass = data.oldStyle = data.param - parseExprProxy(text, vmodels, data) - } -} - -bindingExecutors["class"] = function(val, elem, data) { - var $elem = avalon(elem), - method = data.type - if (method === "class" && data.oldStyle) { //如果是旧风格 - $elem.toggleClass(data.oldStyle, !! val) - } else { - //如果存在冒号就有求值函数 - data.toggleClass = data._evaluator ? !! data._evaluator.apply(elem, data._args) : true - data.newClass = data.immobileClass || val - if (data.oldClass && data.newClass !== data.oldClass) { - $elem.removeClass(data.oldClass) - } - data.oldClass = data.newClass - switch (method) { - case "class": - $elem.toggleClass(data.newClass, data.toggleClass) - break - case "hover": - case "active": - if (!data.hasBindEvent) { //确保只绑定一次 - var activate = "mouseenter" //在移出移入时切换类名 - var abandon = "mouseleave" - if (method === "active") { //在聚焦失焦中切换类名 - elem.tabIndex = elem.tabIndex || -1 - activate = "mousedown" - abandon = "mouseup" - var fn0 = $elem.bind("mouseleave", function() { - data.toggleClass && $elem.removeClass(data.newClass) - }) - } - var fn1 = $elem.bind(activate, function() { - data.toggleClass && $elem.addClass(data.newClass) - }) - var fn2 = $elem.bind(abandon, function() { - data.toggleClass && $elem.removeClass(data.newClass) - }) - data.rollback = function() { - $elem.unbind("mouseleave", fn0) - $elem.unbind(activate, fn1) - $elem.unbind(abandon, fn2) - } - data.hasBindEvent = true - } - break; - } - } -} - -"hover,active".replace(rword, function(method) { - bindingHandlers[method] = bindingHandlers["class"] -}) -//ms-controller绑定已经在scanTag 方法中实现 -//ms-css绑定已由ms-attr绑定实现 - - -// bindingHandlers.data 定义在if.js -bindingExecutors.data = function(val, elem, data) { - var key = "data-" + data.param - if (val && typeof val === "object") { - elem[key] = val - } else { - elem.setAttribute(key, String(val)) - } -} -//双工绑定 -var duplexBinding = bindingHandlers.duplex = function(data, vmodels) { - var elem = data.element, - hasCast - parseExprProxy(data.value, vmodels, data, 0, 1) - - data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop - if (data.evaluator && data.args) { - var params = [] - var casting = oneObject("string,number,boolean,checked") - if (elem.type === "radio" && data.param === "") { - data.param = "checked" - } - if (elem.msData) { - elem.msData["ms-duplex"] = data.value - } - data.param.replace(/\w+/g, function(name) { - if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) { - if (name === "radio") - log("ms-duplex-radio已经更名为ms-duplex-checked") - name = "checked" - data.isChecked = true - } - if (name === "bool") { - name = "boolean" - log("ms-duplex-bool已经更名为ms-duplex-boolean") - } else if (name === "text") { - name = "string" - log("ms-duplex-text已经更名为ms-duplex-string") - } - if (casting[name]) { - hasCast = true - } - avalon.Array.ensure(params, name) - }) - if (!hasCast) { - params.push("string") - } - data.param = params.join("-") - data.bound = function(type, callback) { - if (elem.addEventListener) { - elem.addEventListener(type, callback, false) - } else { - elem.attachEvent("on" + type, callback) - } - var old = data.rollback - data.rollback = function() { - elem.avalonSetter = null - avalon.unbind(elem, type, callback) - old && old() - } - } - for (var i in avalon.vmodels) { - var v = avalon.vmodels[i] - v.$fire("avalon-ms-duplex-init", data) - } - var cpipe = data.pipe || (data.pipe = pipe) - cpipe(null, data, "init") - var tagName = elem.tagName - duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data) - } -} -//不存在 bindingExecutors.duplex - - function fixNull(val) { - return val == null ? "" : val - } -avalon.duplexHooks = { - checked: { - get: function(val, data) { - return !data.element.oldValue - } - }, - string: { - get: function(val) { //同步到VM - return val - }, - set: fixNull - }, - "boolean": { - get: function(val) { - return val === "true" - }, - set: fixNull - }, - number: { - get: function(val, data) { - var number = parseFloat(val) - if (-val === -number) { - return number - } - var arr = /strong|medium|weak/.exec(data.element.getAttribute("data-duplex-number")) || ["medium"] - switch (arr[0]) { - case "strong": - return 0 - case "medium": - return val === "" ? "" : 0 - case "weak": - return val - } - }, - set: fixNull - } -} - -function pipe(val, data, action, e) { - data.param.replace(/\w+/g, function(name) { - var hook = avalon.duplexHooks[name] - if (hook && typeof hook[action] === "function") { - val = hook[action](val, data) - } - }) - return val -} - -var TimerID, ribbon = [] - - avalon.tick = function(fn) { - if (ribbon.push(fn) === 1) { - TimerID = setInterval(ticker, 60) - } - } - - function ticker() { - for (var n = ribbon.length - 1; n >= 0; n--) { - var el = ribbon[n] - if (el() === false) { - ribbon.splice(n, 1) - } - } - if (!ribbon.length) { - clearInterval(TimerID) - } - } - -var watchValueInTimer = noop -var rmsinput = /text|password|hidden/ -new function() { // jshint ignore:line - try { //#272 IE9-IE11, firefox - var setters = {} - var aproto = HTMLInputElement.prototype - var bproto = HTMLTextAreaElement.prototype - function newSetter(value) { // jshint ignore:line - setters[this.tagName].call(this, value) - if (rmsinput.test(this.type) && !this.msFocus && this.avalonSetter) { - this.avalonSetter() - } - } - var inputProto = HTMLInputElement.prototype - Object.getOwnPropertyNames(inputProto) //故意引发IE6-8等浏览器报错 - setters["INPUT"] = Object.getOwnPropertyDescriptor(aproto, "value").set - - Object.defineProperty(aproto, "value", { - set: newSetter - }) - setters["TEXTAREA"] = Object.getOwnPropertyDescriptor(bproto, "value").set - Object.defineProperty(bproto, "value", { - set: newSetter - }) - } catch (e) { - //在chrome 43中 ms-duplex终于不需要使用定时器实现双向绑定了 - // http://updates.html5rocks.com/2015/04/DOM-attributes-now-on-the-prototype - // https://docs.google.com/document/d/1jwA8mtClwxI-QJuHT7872Z0pxpZz8PBkf2bGAbsUtqs/edit?pli=1 - watchValueInTimer = avalon.tick - } -} // jshint ignore:line -if (IEVersion) { - avalon.bind(DOC, "selectionchange", function(e) { - var el = DOC.activeElement - if (el && typeof el.avalonSetter === "function") { - el.avalonSetter() - } - }) -} - -//处理radio, checkbox, text, textarea, password -duplexBinding.INPUT = function(element, evaluator, data) { - var $type = element.type, - bound = data.bound, - $elem = avalon(element), - composing = false - - function callback(value) { - data.changed.call(this, value, data) - } - - function compositionStart() { - composing = true - } - - function compositionEnd() { - composing = false - } - //当value变化时改变model的值 - var updateVModel = function() { - if (composing) //处理中文输入法在minlengh下引发的BUG - return - var val = element.oldValue = element.value //防止递归调用形成死循环 - var lastValue = data.pipe(val, data, "get") - if ($elem.data("duplexObserve") !== false) { - evaluator(lastValue) - callback.call(element, lastValue) - if ($elem.data("duplex-focus")) { - avalon.nextTick(function() { - element.focus() - }) - } - } - } - //当model变化时,它就会改变value的值 - data.handler = function() { - var val = data.pipe(evaluator(), data, "set") + "" //fix #673 - if (val !== element.oldValue) { - element.value = val - } - } - if (data.isChecked || $type === "radio") { - var IE6 = IEVersion === 6 - updateVModel = function() { - if ($elem.data("duplexObserve") !== false) { - var lastValue = data.pipe(element.value, data, "get") - evaluator(lastValue) - callback.call(element, lastValue) - } - } - data.handler = function() { - var val = evaluator() - var checked = data.isChecked ? !! val : val + "" === element.value - element.oldValue = checked - if (IE6) { - setTimeout(function() { - //IE8 checkbox, radio是使用defaultChecked控制选中状态, - //并且要先设置defaultChecked后设置checked - //并且必须设置延迟 - element.defaultChecked = checked - element.checked = checked - }, 31) - } else { - element.checked = checked - } - } - bound("click", updateVModel) - } else if ($type === "checkbox") { - updateVModel = function() { - if ($elem.data("duplexObserve") !== false) { - var method = element.checked ? "ensure" : "remove" - var array = evaluator() - if (!Array.isArray(array)) { - log("ms-duplex应用于checkbox上要对应一个数组") - array = [array] - } - var val = data.pipe(element.value, data, "get") - avalon.Array[method](array, val) - callback.call(element, array) - } - } - - data.handler = function() { - var array = [].concat(evaluator()) //强制转换为数组 - var val = data.pipe(element.value, data, "get") - element.checked = array.indexOf(val) > -1 - } - bound(W3C ? "change" : "click", updateVModel) - } else { - var events = element.getAttribute("data-duplex-event") || "input" - if (element.attributes["data-event"]) { - log("data-event指令已经废弃,请改用data-duplex-event") - } - - function delay(e) { // jshint ignore:line - setTimeout(function() { - updateVModel(e) - }) - } - events.replace(rword, function(name) { - switch (name) { - case "input": - if (!IEVersion) { // W3C - bound("input", updateVModel) - //非IE浏览器才用这个 - bound("compositionstart", compositionStart) - bound("compositionend", compositionEnd) - bound("DOMAutoComplete", updateVModel) - } else { //onpropertychange事件无法区分是程序触发还是用户触发 - // IE下通过selectionchange事件监听IE9+点击input右边的X的清空行为,及粘贴,剪切,删除行为 - if (IEVersion > 8) { - bound("input", updateVModel) //IE9使用propertychange无法监听中文输入改动 - } else { - bound("propertychange", function(e) { //IE6-8下第一次修改时不会触发,需要使用keydown或selectionchange修正 - if (e.propertyName === "value") { - updateVModel() - } - }) - } - bound("dragend", delay) - //http://www.cnblogs.com/rubylouvre/archive/2013/02/17/2914604.html - //http://www.matts411.com/post/internet-explorer-9-oninput/ - } - break - default: - bound(name, updateVModel) - break - } - }) - bound("focus", function() { - element.msFocus = true - }) - bound("blur", function() { - element.msFocus = false - }) - - if (rmsinput.test($type)) { - watchValueInTimer(function() { - if (root.contains(element)) { - if (!element.msFocus && element.oldValue !== element.value) { - updateVModel() - } - } else if (!element.msRetain) { - return false - } - }) - } - - element.avalonSetter = updateVModel //#765 - } - - element.oldValue = element.value - avalon.injectBinding(data) - callback.call(element, element.value) -} -duplexBinding.TEXTAREA = duplexBinding.INPUT -duplexBinding.SELECT = function(element, evaluator, data) { - var $elem = avalon(element) - - function updateVModel() { - if ($elem.data("duplexObserve") !== false) { - var val = $elem.val() //字符串或字符串数组 - if (Array.isArray(val)) { - val = val.map(function(v) { - return data.pipe(v, data, "get") - }) - } else { - val = data.pipe(val, data, "get") - } - if (val + "" !== element.oldValue) { - evaluator(val) - } - data.changed.call(element, val, data) - } - } - data.handler = function() { - var val = evaluator() - val = val && val.$model || val - if (Array.isArray(val)) { - if (!element.multiple) { - log("ms-duplex在不能对应一个数组") - } - } - //必须变成字符串后才能比较 - val = Array.isArray(val) ? val.map(String) : val + "" - if (val + "" !== element.oldValue) { - $elem.val(val) - element.oldValue = val + "" - } - } - data.bound("change", updateVModel) - element.msCallback = function() { - avalon.injectBinding(data) - data.changed.call(element, evaluator(), data) - } -} -// bindingHandlers.html 定义在if.js -bindingExecutors.html = function (val, elem, data) { - var isHtmlFilter = elem.nodeType !== 1 - var parent = isHtmlFilter ? elem.parentNode : elem - if (!parent) - return - val = val == null ? "" : val - if (data.oldText !== val) { - data.oldText = val - } else { - return - } - if (elem.nodeType === 3) { - var signature = generateID("html") - parent.insertBefore(DOC.createComment(signature), elem) - data.element = DOC.createComment(signature + ":end") - parent.replaceChild(data.element, elem) - elem = data.element - } - if (typeof val !== "object") {//string, number, boolean - var fragment = avalon.parseHTML(String(val)) - } else if (val.nodeType === 11) { //将val转换为文档碎片 - fragment = val - } else if (val.nodeType === 1 || val.item) { - var nodes = val.nodeType === 1 ? val.childNodes : val.item - fragment = avalonFragment.cloneNode(true) - while (nodes[0]) { - fragment.appendChild(nodes[0]) - } - } - - nodes = avalon.slice(fragment.childNodes) - //插入占位符, 如果是过滤器,需要有节制地移除指定的数量,如果是html指令,直接清空 - if (isHtmlFilter) { - var endValue = elem.nodeValue.slice(0, -4) - while (true) { - var node = elem.previousSibling - if (!node || node.nodeType === 8 && node.nodeValue === endValue) { - break - } else { - parent.removeChild(node) - } - } - parent.insertBefore(fragment, elem) - } else { - avalon.clearHTML(elem).appendChild(fragment) - } - scanNodeArray(nodes, data.vmodels) -} -bindingHandlers["if"] = - bindingHandlers.data = - bindingHandlers.text = - bindingHandlers.html = - function(data, vmodels) { - parseExprProxy(data.value, vmodels, data) -} - -bindingExecutors["if"] = function(val, elem, data) { - try { - if(!elem.parentNode) return - } catch(e) {return} - if (val) { //插回DOM树 - if (elem.nodeType === 8) { - elem.parentNode.replaceChild(data.template, elem) - // animate.enter(data.template, elem.parentNode) - elem = data.element = data.template //这时可能为null - } - if (elem.getAttribute(data.name)) { - elem.removeAttribute(data.name) - scanAttr(elem, data.vmodels) - } - data.rollback = null - } else { //移出DOM树,并用注释节点占据原位置 - if (elem.nodeType === 1) { - var node = data.element = DOC.createComment("ms-if") - elem.parentNode.replaceChild(node, elem) - // animate.leave(elem, node.parentNode, node) - data.template = elem //元素节点 - ifGroup.appendChild(elem) - data.rollback = function() { - if (elem.parentNode === ifGroup) { - ifGroup.removeChild(elem) - } - } - } - } -} -//ms-important绑定已经在scanTag 方法中实现 -//ms-include绑定已由ms-attr绑定实现 - -var rdash = /\(([^)]*)\)/ -bindingHandlers.on = function(data, vmodels) { - var value = data.value - data.type = "on" - var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10 - if (typeof bindingHandlers.on[eventType + "Hook"] === "function") { - bindingHandlers.on[eventType + "Hook"](data) - } - if (value.indexOf("(") > 0 && value.indexOf(")") > -1) { - var matched = (value.match(rdash) || ["", ""])[1].trim() - if (matched === "" || matched === "$event") { // aaa() aaa($event)当成aaa处理 - value = value.replace(rdash, "") - } - } - parseExprProxy(value, vmodels, data) -} - -bindingExecutors.on = function(callback, elem, data) { - callback = function(e) { - var fn = data.evaluator || noop - return fn.apply(this, data.args.concat(e)) - } - var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10 - if (eventType === "scan") { - callback.call(elem, { - type: eventType - }) - } else if (typeof data.specialBind === "function") { - data.specialBind(elem, callback) - } else { - var removeFn = avalon.bind(elem, eventType, callback) - } - data.rollback = function() { - if (typeof data.specialUnbind === "function") { - data.specialUnbind() - } else { - avalon.unbind(elem, eventType, removeFn) - } - } -} -bindingHandlers.repeat = function (data, vmodels) { - var type = data.type - parseExprProxy(data.value, vmodels, data, 0, 1) - data.proxies = [] - var freturn = false - try { - var $repeat = data.$repeat = data.evaluator.apply(0, data.args || []) - var xtype = avalon.type($repeat) - if (xtype !== "object" && xtype !== "array") { - freturn = true - avalon.log("warning:" + data.value + "只能是对象或数组") - } - } catch (e) { - freturn = true - } - var arr = data.value.split(".") || [] - if (arr.length > 1) { - arr.pop() - var n = arr[0] - for (var i = 0, v; v = vmodels[i++]; ) { - if (v && v.hasOwnProperty(n)) { - var events = v[n].$events || {} - events[subscribers] = events[subscribers] || [] - events[subscribers].push(data) - break - } - } - } - - var elem = data.element - if (elem.nodeType === 1) { - elem.removeAttribute(data.name) - data.sortedCallback = getBindingCallback(elem, "data-with-sorted", vmodels) - data.renderedCallback = getBindingCallback(elem, "data-" + type + "-rendered", vmodels) - var signature = generateID(type) - var start = DOC.createComment(signature) - var end = DOC.createComment(signature + ":end") - data.signature = signature - data.template = avalonFragment.cloneNode(false) - if (type === "repeat") { - var parent = elem.parentNode - parent.replaceChild(end, elem) - parent.insertBefore(start, end) - data.template.appendChild(elem) - } else { - while (elem.firstChild) { - data.template.appendChild(elem.firstChild) - } - elem.appendChild(start) - elem.appendChild(end) - } - data.element = end - data.handler = bindingExecutors.repeat - data.rollback = function () { - var elem = data.element - if (!elem) - return - data.handler("clear") - } - } - - if (freturn) { - return - } - - data.$outer = {} - var check0 = "$key" - var check1 = "$val" - if (Array.isArray($repeat)) { - check0 = "$first" - check1 = "$last" - } - - for (i = 0; v = vmodels[i++]; ) { - if (v.hasOwnProperty(check0) && v.hasOwnProperty(check1)) { - data.$outer = v - break - } - } - var $events = $repeat.$events - var $list = ($events || {})[subscribers] - injectDependency($list, data) - if (xtype === "object") { - data.$with = true - $repeat.$proxy || ($repeat.$proxy = {}) - data.handler("append", $repeat) - } else if ($repeat.length) { - data.handler("add", 0, $repeat.length) - } -} - -bindingExecutors.repeat = function (method, pos, el) { - if (!method && this.$with) { - method = "append" - var flag = "update" - } - if (method) { - var data = this, start, fragment - var end = data.element - var comments = getComments(data) - var parent = end.parentNode - var proxies = data.proxies - var transation = avalonFragment.cloneNode(false) - switch (method) { - case "add": //在pos位置后添加el数组(pos为插入位置,el为要插入的个数) - var n = pos + el - var fragments = [] - for (var i = pos; i < n; i++) { - var proxy = eachProxyAgent(i, data) - proxies.splice(i, 0, proxy) - shimController(data, transation, proxy, fragments) - } - var now = new Date() - 0 - avalon.optimize = avalon.optimize || now - for (i = 0; fragment = fragments[i++]; ) { - scanNodeArray(fragment.nodes, fragment.vmodels) - fragment.nodes = fragment.vmodels = null - } - if (avalon.optimize === now) { - avalon.optimize = null - } - parent.insertBefore(transation, comments[pos] || end) - avalon.profile("插入操作花费了 " + (new Date - now)) - break - case "del": //将pos后的el个元素删掉(pos, el都是数字) - sweepNodes(comments[pos], comments[pos + el] || end) - var removed = proxies.splice(pos, el) - recycleProxies(removed, "each") - break - case "clear": - start = comments[0] - if (start) { - sweepNodes(start, end) - if (data.$with) { - parent.insertBefore(start, end) - } - } - recycleProxies(proxies, "each") - break - case "move": - start = comments[0] - if (start) { - var signature = start.nodeValue - var rooms = [] - var room = [], - node - sweepNodes(start, end, function () { - room.unshift(this) - if (this.nodeValue === signature) { - rooms.unshift(room) - room = [] - } - }) - sortByIndex(rooms, pos) - sortByIndex(proxies, pos) - while (room = rooms.shift()) { - while (node = room.shift()) { - transation.appendChild(node) - } - } - parent.insertBefore(transation, end) - } - break - case "index": //将proxies中的第pos个起的所有元素重新索引 - var last = proxies.length - 1 - for (; el = proxies[pos]; pos++) { - el.$index = pos - el.$first = pos === 0 - el.$last = pos === last - } - return - case "set": //将proxies中的第pos个元素的VM设置为el(pos为数字,el任意) - proxy = proxies[pos] - if (proxy) { - fireDependencies(proxy.$events[data.param || "el"]) - } - break - case "append": - var object = data.$repeat //原来第2参数, 被循环对象 - var oldProxy = object.$proxy //代理对象组成的hash - var keys = [] - now = new Date() - 0 - avalon.optimize = avalon.optimize || now - if (flag === "update") { - if (!data.evaluator) { - parseExprProxy(data.value, data.vmodels, data, 0, 1) - } - object = data.$repeat = data.evaluator.apply(0, data.args || []) - object.$proxy = oldProxy - } - var pool = object.$proxy || {} - removed = [] - var nodes = data.element.parentNode.childNodes - var add = false - for (i = 0; node = nodes[i++]; ) { - if (node.nodeValue === data.signature) { - add = true - } else if (node.nodeValue === data.signature + ":end") { - add = false - } - if (add) { - removed.push(node) - } - } - - var indexNode = [], item - var keyIndex = data.keyIndex || (data.keyIndex = {}) - //将现有的节点全部移出DOM树 - for ( i = 0; i < removed.length; i++) { - el = removed[i] - if (el.nodeValue === data.signature) { - item = avalonFragment.cloneNode(false) - indexNode.push(item) - } - item.appendChild(el) - } - - - for (var key in object) { //当前对象的所有键名 - if (object.hasOwnProperty(key) && key !== "hasOwnProperty" && key !== "$proxy") { - keys.push(key) - } - } - - for (var i = 0; key = keys[i++]; ) { - if (!pool.hasOwnProperty(key)) {//添加缺失的代理VM - pool[key] = withProxyAgent(pool[key], key, data) - } else { - pool[key].$val = object[key] - } - } - - for ( key in pool) { - if (keys.indexOf(key) === -1) {//删除没用的代理VM - proxyRecycler(pool[key], withProxyPool) //去掉之前的代理VM - delete pool[key] - } - } - var fragments = [] - var renderKeys = keys //需要渲染到DOM树去的键名 - var end = data.element - if (data.sortedCallback) { //如果有回调,则让它们排序 - var keys2 = data.sortedCallback.call(parent, keys) - if (keys2 && Array.isArray(keys2)) { - renderKeys = keys2 - } - } - - for (i = 0; i < renderKeys.length; i++) { - key = renderKeys[i] - if (typeof keyIndex[key] === "number") { - transation.appendChild(indexNode[keyIndex[key]]) - fragments.push({}) - } else { - shimController(data, transation, pool[key], fragments) - } - } - - for (i = 0; i < renderKeys.length; i++) { - keyIndex[renderKeys[i]] = i - } - - for (i = 0; fragment = fragments[i++]; ) { - if (fragment.nodes) { - scanNodeArray(fragment.nodes, fragment.vmodels) - fragment.nodes = fragment.vmodels = null - } - } - if (avalon.optimize === now) { - avalon.optimize = null - } - parent.insertBefore(transation, end) - avalon.profile("插入操作花费了 " + (new Date - now)) - break - } - if (!data.$repeat || data.$repeat.hasOwnProperty("$lock")) //IE6-8 VBScript对象会报错, 有时候data.$repeat不存在 - return - if (method === "clear") - method = "del" - var callback = data.renderedCallback || noop, - args = arguments - if (parent.oldValue && parent.tagName === "SELECT") { //fix #503 - avalon(parent).val(parent.oldValue.split(",")) - } - callback.apply(parent, args) - } -} -"with,each".replace(rword, function (name) { - bindingHandlers[name] = bindingHandlers.repeat -}) - -function shimController(data, transation, proxy, fragments) { - var content = data.template.cloneNode(true) - var nodes = avalon.slice(content.childNodes) - content.insertBefore(DOC.createComment(data.signature), content.firstChild) - transation.appendChild(content) - var nv = [proxy].concat(data.vmodels) - var fragment = { - nodes: nodes, - vmodels: nv - } - fragments.push(fragment) -} - -function getComments(data) { - var ret = [] - var nodes = data.element.parentNode.childNodes - for(var i= 0, node; node = nodes[i++];){ - if(node.nodeValue === data.signature){ - ret.push( node ) - }else if(node.nodeValue === data.signature+":end"){ - break - } - } - return ret -} - - -//移除掉start与end之间的节点(保留end) -function sweepNodes(start, end, callback) { - while (true) { - var node = end.previousSibling - if (!node) - break - node.parentNode.removeChild(node) - callback && callback.call(node) - if (node === start) { - break - } - } -} - -// 为ms-each,ms-with, ms-repeat会创建一个代理VM, -// 通过它们保持一个下上文,让用户能调用$index,$first,$last,$remove,$key,$val,$outer等属性与方法 -// 所有代理VM的产生,消费,收集,存放通过xxxProxyFactory,xxxProxyAgent, recycleProxies,xxxProxyPool实现 -var withProxyPool = [] -function withProxyFactory() { - var proxy = modelFactory({ - $key: "", - $outer: {}, - $host: {}, - $val: { - get: function () { - return this.$host[this.$key] - }, - set: function (val) { - this.$host[this.$key] = val - } - } - }, { - $val: 1 - }) - proxy.$id = generateID("$proxy$with") - return proxy -} - -function withProxyAgent(proxy, key, data) { - proxy = proxy || withProxyPool.pop() - if (!proxy) { - proxy = withProxyFactory() - } else { - proxy.$reinitialize() - } - var host = data.$repeat - proxy.$key = key - proxy.$host = host - proxy.$outer = data.$outer - if (host.$events) { - proxy.$events.$val = host.$events[key] - } else { - proxy.$events = {} - } - return proxy -} - - -function recycleProxies(proxies) { - eachProxyRecycler(proxies) -} -function eachProxyRecycler(proxies) { - proxies.forEach(function (proxy) { - proxyRecycler(proxy, eachProxyPool) - }) - proxies.length = 0 -} - - -var eachProxyPool = [] -function eachProxyFactory(name) { - var source = { - $host: [], - $outer: {}, - $index: 0, - $first: false, - $last: false, - $remove: avalon.noop - } - source[name] = { - get: function () { - var e = this.$events - var array = e.$index - e.$index = e[name] //#817 通过$index为el收集依赖 - try { - return this.$host[this.$index] - } finally { - e.$index = array - } - }, - set: function (val) { - try { - var e = this.$events - var array = e.$index - e.$index = [] - this.$host.set(this.$index, val) - } finally { - e.$index = array - } - } - } - var second = { - $last: 1, - $first: 1, - $index: 1 - } - var proxy = modelFactory(source, second) - proxy.$id = generateID("$proxy$each") - return proxy -} - -function eachProxyAgent(index, data) { - var param = data.param || "el", - proxy - for (var i = 0, n = eachProxyPool.length; i < n; i++) { - var candidate = eachProxyPool[i] - if (candidate && candidate.hasOwnProperty(param)) { - proxy = candidate - eachProxyPool.splice(i, 1) - } - } - if (!proxy) { - proxy = eachProxyFactory(param) - } - var host = data.$repeat - var last = host.length - 1 - proxy.$index = index - proxy.$first = index === 0 - proxy.$last = index === last - proxy.$host = host - proxy.$outer = data.$outer - proxy.$remove = function () { - return host.removeAt(proxy.$index) - } - return proxy -} - - -function proxyRecycler(proxy, proxyPool) { - for (var i in proxy.$events) { - if (Array.isArray(proxy.$events[i])) { - proxy.$events[i].forEach(function (data) { - if (typeof data === "object") - disposeData(data) - })// jshint ignore:line - proxy.$events[i].length = 0 - } - } - proxy.$host = proxy.$outer = {} - if (proxyPool.unshift(proxy) > kernel.maxRepeatSize) { - proxyPool.pop() - } -} -/********************************************************************* - * 各种指令 * - **********************************************************************/ -//ms-skip绑定已经在scanTag 方法中实现 -// bindingHandlers.text 定义在if.js -bindingExecutors.text = function(val, elem) { - val = val == null ? "" : val //不在页面上显示undefined null - if (elem.nodeType === 3) { //绑定在文本节点上 - try { //IE对游离于DOM树外的节点赋值会报错 - elem.data = val - } catch (e) {} - } else { //绑定在特性节点上 - if ("textContent" in elem) { - elem.textContent = val - } else { - elem.innerText = val - } - } -} -function parseDisplay(nodeName, val) { - //用于取得此类标签的默认display值 - var key = "_" + nodeName - if (!parseDisplay[key]) { - var node = DOC.createElement(nodeName) - root.appendChild(node) - if (W3C) { - val = getComputedStyle(node, null).display - } else { - val = node.currentStyle.display - } - root.removeChild(node) - parseDisplay[key] = val - } - return parseDisplay[key] -} - -avalon.parseDisplay = parseDisplay - -bindingHandlers.visible = function(data, vmodels) { - var elem = data.element - var display = elem.style.display - if(display === "none"){ - display = parseDisplay(elem.nodeName) - } - data.display = display - parseExprProxy(data.value, vmodels, data) -} - -bindingExecutors.visible = function(val, elem, data) { - elem.style.display = val ? data.display : "none" -} -bindingHandlers.widget = function(data, vmodels) { - var args = data.value.match(rword) - var elem = data.element - var widget = args[0] - var id = args[1] - if (!id || id === "$") { //没有定义或为$时,取组件名+随机数 - id = generateID(widget) - } - var optName = args[2] || widget //没有定义,取组件名 - var constructor = avalon.ui[widget] - if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname" - vmodels = elem.vmodels || vmodels - for (var i = 0, v; v = vmodels[i++];) { - if (v.hasOwnProperty(optName) && typeof v[optName] === "object") { - var vmOptions = v[optName] - vmOptions = vmOptions.$model || vmOptions - break - } - } - if (vmOptions) { - var wid = vmOptions[widget + "Id"] - if (typeof wid === "string") { - log("warning!不再支持" + widget + "Id") - id = wid - } - } - //抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象 - var widgetData = avalon.getWidgetData(elem, widget) - data.value = [widget, id, optName].join(",") - data[widget + "Id"] = id - data.evaluator = noop - elem.msData["ms-widget-id"] = id - var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData) - elem.removeAttribute("ms-widget") - var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM - if (vmodel.$id) { - avalon.vmodels[id] = vmodel - createSignalTower(elem, vmodel) - try { - vmodel.$init(function() { - avalon.scan(elem, [vmodel].concat(vmodels)) - if (typeof options.onInit === "function") { - options.onInit.call(elem, vmodel, options, vmodels) - } - }) - } catch (e) {} - data.rollback = function() { - try { - vmodel.widgetElement = null - vmodel.$remove() - } catch (e) {} - elem.msData = {} - delete avalon.vmodels[vmodel.$id] - } - injectDisposeQueue(data, widgetList) - if (window.chrome) { - elem.addEventListener("DOMNodeRemovedFromDocument", function() { - setTimeout(rejectDisposeQueue) - }) - } - } else { - avalon.scan(elem, vmodels) - } - } else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels - elem.vmodels = vmodels - } -} -var widgetList = [] -//不存在 bindingExecutors.widget -/********************************************************************* - * 自带过滤器 * - **********************************************************************/ -var rscripts = /]*>([\S\s]*?)<\/script\s*>/gim -var ron = /\s+(on[^=\s]+)(?:=("[^"]*"|'[^']*'|[^\s>]+))?/g -var ropen = /<\w+\b(?:(["'])[^"]*?(\1)|[^>])*>/ig -var rsanitize = { - a: /\b(href)\=("javascript[^"]*"|'javascript[^']*')/ig, - img: /\b(src)\=("javascript[^"]*"|'javascript[^']*')/ig, - form: /\b(action)\=("javascript[^"]*"|'javascript[^']*')/ig -} -var rsurrogate = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g -var rnoalphanumeric = /([^\#-~| |!])/g; - -function numberFormat(number, decimals, point, thousands) { - //form http://phpjs.org/functions/number_format/ - //number 必需,要格式化的数字 - //decimals 可选,规定多少个小数位。 - //point 可选,规定用作小数点的字符串(默认为 . )。 - //thousands 可选,规定用作千位分隔符的字符串(默认为 , ),如果设置了该参数,那么所有其他参数都是必需的。 - number = (number + '') - .replace(/[^0-9+\-Ee.]/g, '') - var n = !isFinite(+number) ? 0 : +number, - prec = !isFinite(+decimals) ? 3 : Math.abs(decimals), - sep = thousands || ",", - dec = point || ".", - s = '', - toFixedFix = function(n, prec) { - var k = Math.pow(10, prec) - return '' + (Math.round(n * k) / k) - .toFixed(prec) - } - // Fix for IE parseFloat(0.55).toFixed(0) = 0; - s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)) - .split('.') - if (s[0].length > 3) { - s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep) - } - if ((s[1] || '') - .length < prec) { - s[1] = s[1] || '' - s[1] += new Array(prec - s[1].length + 1) - .join('0') - } - return s.join(dec) -} - - -var filters = avalon.filters = { - uppercase: function(str) { - return str.toUpperCase() - }, - lowercase: function(str) { - return str.toLowerCase() - }, - truncate: function(str, length, truncation) { - //length,新字符串长度,truncation,新字符串的结尾的字段,返回新字符串 - length = length || 30 - truncation = typeof truncation === "string" ? truncation : "..." - return str.length > length ? str.slice(0, length - truncation.length) + truncation : String(str) - }, - $filter: function(val) { - for (var i = 1, n = arguments.length; i < n; i++) { - var array = arguments[i] - var fn = avalon.filters[array.shift()] - if (typeof fn === "function") { - var arr = [val].concat(array) - val = fn.apply(null, arr) - } - } - return val - }, - camelize: camelize, - //https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - // chrome - // chrome - // IE67chrome - // IE67chrome - // IE67chrome - sanitize: function(str) { - return str.replace(rscripts, "").replace(ropen, function(a, b) { - var match = a.toLowerCase().match(/<(\w+)\s/) - if (match) { //处理a标签的href属性,img标签的src属性,form标签的action属性 - var reg = rsanitize[match[1]] - if (reg) { - a = a.replace(reg, function(s, name, value) { - var quote = value.charAt(0) - return name + "=" + quote + "javascript:void(0)" + quote// jshint ignore:line - }) - } - } - return a.replace(ron, " ").replace(/\s+/g, " ") //移除onXXX事件 - }) - }, - escape: function(str) { - //将字符串经过 str 转义得到适合在页面中显示的内容, 例如替换 < 为 < - return String(str). - replace(/&/g, '&'). - replace(rsurrogate, function(value) { - var hi = value.charCodeAt(0) - var low = value.charCodeAt(1) - return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';' - }). - replace(rnoalphanumeric, function(value) { - return '&#' + value.charCodeAt(0) + ';' - }). - replace(//g, '>') - }, - currency: function(amount, symbol, fractionSize) { - return (symbol || "\uFFE5") + numberFormat(amount, isFinite(fractionSize) ? fractionSize : 2) - }, - number: numberFormat -} -/* - 'yyyy': 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) - 'yy': 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - 'y': 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) - 'MMMM': Month in year (January-December) - 'MMM': Month in year (Jan-Dec) - 'MM': Month in year, padded (01-12) - 'M': Month in year (1-12) - 'dd': Day in month, padded (01-31) - 'd': Day in month (1-31) - 'EEEE': Day in Week,(Sunday-Saturday) - 'EEE': Day in Week, (Sun-Sat) - 'HH': Hour in day, padded (00-23) - 'H': Hour in day (0-23) - 'hh': Hour in am/pm, padded (01-12) - 'h': Hour in am/pm, (1-12) - 'mm': Minute in hour, padded (00-59) - 'm': Minute in hour (0-59) - 'ss': Second in minute, padded (00-59) - 's': Second in minute (0-59) - 'a': am/pm marker - 'Z': 4 digit (+sign) representation of the timezone offset (-1200-+1200) - format string can also be one of the following predefined localizable formats: - - 'medium': equivalent to 'MMM d, y h:mm:ss a' for en_US locale (e.g. Sep 3, 2010 12:05:08 pm) - 'short': equivalent to 'M/d/yy h:mm a' for en_US locale (e.g. 9/3/10 12:05 pm) - 'fullDate': equivalent to 'EEEE, MMMM d,y' for en_US locale (e.g. Friday, September 3, 2010) - 'longDate': equivalent to 'MMMM d, y' for en_US locale (e.g. September 3, 2010 - 'mediumDate': equivalent to 'MMM d, y' for en_US locale (e.g. Sep 3, 2010) - 'shortDate': equivalent to 'M/d/yy' for en_US locale (e.g. 9/3/10) - 'mediumTime': equivalent to 'h:mm:ss a' for en_US locale (e.g. 12:05:08 pm) - 'shortTime': equivalent to 'h:mm a' for en_US locale (e.g. 12:05 pm) - */ -new function() {// jshint ignore:line - function toInt(str) { - return parseInt(str, 10) || 0 - } - - function padNumber(num, digits, trim) { - var neg = "" - if (num < 0) { - neg = '-' - num = -num - } - num = "" + num - while (num.length < digits) - num = "0" + num - if (trim) - num = num.substr(num.length - digits) - return neg + num - } - - function dateGetter(name, size, offset, trim) { - return function(date) { - var value = date["get" + name]() - if (offset > 0 || value > -offset) - value += offset - if (value === 0 && offset === -12) { - value = 12 - } - return padNumber(value, size, trim) - } - } - - function dateStrGetter(name, shortForm) { - return function(date, formats) { - var value = date["get" + name]() - var get = (shortForm ? ("SHORT" + name) : name).toUpperCase() - return formats[get][value] - } - } - - function timeZoneGetter(date) { - var zone = -1 * date.getTimezoneOffset() - var paddedZone = (zone >= 0) ? "+" : "" - paddedZone += padNumber(Math[zone > 0 ? "floor" : "ceil"](zone / 60), 2) + padNumber(Math.abs(zone % 60), 2) - return paddedZone - } - //取得上午下午 - - function ampmGetter(date, formats) { - return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1] - } - var DATE_FORMATS = { - yyyy: dateGetter("FullYear", 4), - yy: dateGetter("FullYear", 2, 0, true), - y: dateGetter("FullYear", 1), - MMMM: dateStrGetter("Month"), - MMM: dateStrGetter("Month", true), - MM: dateGetter("Month", 2, 1), - M: dateGetter("Month", 1, 1), - dd: dateGetter("Date", 2), - d: dateGetter("Date", 1), - HH: dateGetter("Hours", 2), - H: dateGetter("Hours", 1), - hh: dateGetter("Hours", 2, -12), - h: dateGetter("Hours", 1, -12), - mm: dateGetter("Minutes", 2), - m: dateGetter("Minutes", 1), - ss: dateGetter("Seconds", 2), - s: dateGetter("Seconds", 1), - sss: dateGetter("Milliseconds", 3), - EEEE: dateStrGetter("Day"), - EEE: dateStrGetter("Day", true), - a: ampmGetter, - Z: timeZoneGetter - } - var rdateFormat = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/ - var raspnetjson = /^\/Date\((\d+)\)\/$/ - filters.date = function(date, format) { - var locate = filters.date.locate, - text = "", - parts = [], - fn, match - format = format || "mediumDate" - format = locate[format] || format - if (typeof date === "string") { - if (/^\d+$/.test(date)) { - date = toInt(date) - } else if (raspnetjson.test(date)) { - date = +RegExp.$1 - } else { - var trimDate = date.trim() - var dateArray = [0, 0, 0, 0, 0, 0, 0] - var oDate = new Date(0) - //取得年月日 - trimDate = trimDate.replace(/^(\d+)\D(\d+)\D(\d+)/, function(_, a, b, c) { - var array = c.length === 4 ? [c, a, b] : [a, b, c] - dateArray[0] = toInt(array[0]) //å¹´ - dateArray[1] = toInt(array[1]) - 1 //月 - dateArray[2] = toInt(array[2]) //日 - return "" - }) - var dateSetter = oDate.setFullYear - var timeSetter = oDate.setHours - trimDate = trimDate.replace(/[T\s](\d+):(\d+):?(\d+)?\.?(\d)?/, function(_, a, b, c, d) { - dateArray[3] = toInt(a) //小时 - dateArray[4] = toInt(b) //分钟 - dateArray[5] = toInt(c) //秒 - if (d) { //毫秒 - dateArray[6] = Math.round(parseFloat("0." + d) * 1000) - } - return "" - }) - var tzHour = 0 - var tzMin = 0 - trimDate = trimDate.replace(/Z|([+-])(\d\d):?(\d\d)/, function(z, symbol, c, d) { - dateSetter = oDate.setUTCFullYear - timeSetter = oDate.setUTCHours - if (symbol) { - tzHour = toInt(symbol + c) - tzMin = toInt(symbol + d) - } - return "" - }) - - dateArray[3] -= tzHour - dateArray[4] -= tzMin - dateSetter.apply(oDate, dateArray.slice(0, 3)) - timeSetter.apply(oDate, dateArray.slice(3)) - date = oDate - } - } - if (typeof date === "number") { - date = new Date(date) - } - if (avalon.type(date) !== "date") { - return - } - while (format) { - match = rdateFormat.exec(format) - if (match) { - parts = parts.concat(match.slice(1)) - format = parts.pop() - } else { - parts.push(format) - format = null - } - } - parts.forEach(function(value) { - fn = DATE_FORMATS[value] - text += fn ? fn(date, locate) : value.replace(/(^'|'$)/g, "").replace(/''/g, "'") - }) - return text - } - var locate = { - AMPMS: { - 0: "上午", - 1: "下午" - }, - DAY: { - 0: "星期日", - 1: "星期一", - 2: "星期二", - 3: "星期三", - 4: "星期四", - 5: "星期五", - 6: "星期六" - }, - MONTH: { - 0: "1月", - 1: "2月", - 2: "3月", - 3: "4月", - 4: "5月", - 5: "6月", - 6: "7月", - 7: "8月", - 8: "9月", - 9: "10月", - 10: "11月", - 11: "12月" - }, - SHORTDAY: { - "0": "周日", - "1": "周一", - "2": "周二", - "3": "周三", - "4": "周四", - "5": "周五", - "6": "周六" - }, - fullDate: "yå¹´M月d日EEEE", - longDate: "yå¹´M月d日", - medium: "yyyy-M-d H:mm:ss", - mediumDate: "yyyy-M-d", - mediumTime: "H:mm:ss", - "short": "yy-M-d ah:mm", - shortDate: "yy-M-d", - shortTime: "ah:mm" - } - locate.SHORTMONTH = locate.MONTH - filters.date.locate = locate -}// jshint ignore:line -/********************************************************************* - * AMD加载器 * - **********************************************************************/ -//https://www.devbridge.com/articles/understanding-amd-requirejs/ -//http://maxogden.com/nested-dependencies.html -var modules = avalon.modules = { - "domReady!": { - exports: avalon, - state: 3 - }, - "avalon": { - exports: avalon, - state: 4 - } -} -//Object(modules[id]).state拥有如下值 -// undefined 没有定义 -// 1(send) 已经发出请求 -// 2(loading) 已经被执行但还没有执行完成,在这个阶段define方法会被执行 -// 3(loaded) 执行完毕,通过onload/onreadystatechange回调判定,在这个阶段checkDeps方法会执行 -// 4(execute) 其依赖也执行完毕, 值放到exports对象上,在这个阶段fireFactory方法会执行 -modules.exports = modules.avalon - -new function () {// jshint ignore:line - var loadings = [] //正在加载中的模块列表 - var factorys = [] //放置define方法的factory函数 - var rjsext = /\.js$/i - function makeRequest(name, config) { -//1. 去掉资源前缀 - var res = "js" - name = name.replace(/^(\w+)\!/, function (a, b) { - res = b - return "" - }) - if (res === "ready") { - log("debug: ready!已经被废弃,请使用domReady!") - res = "domReady" - } -//2. 去掉querystring, hash - var query = "" - name = name.replace(rquery, function (a) { - query = a - return "" - }) - //3. 去掉扩展名 - var suffix = "." + res - var ext = /js|css/.test(suffix) ? suffix : "" - name = name.replace(/\.[a-z0-9]+$/g, function (a) { - if (a === suffix) { - ext = a - return "" - } else { - return a - } - }) - var req = avalon.mix({ - query: query, - ext: ext, - res: res, - name: name, - toUrl: toUrl - }, config) - req.toUrl(name) - return req - } - - function fireRequest(req) { - var name = req.name - var res = req.res - //1. 如果该模块已经发出请求,直接返回 - var module = modules[name] - var urlNoQuery = name && req.urlNoQuery - if (module && module.state >= 1) { - return name - } - module = modules[urlNoQuery] - if (module && module.state >= 3) { - innerRequire(module.deps || [], module.factory, urlNoQuery) - return urlNoQuery - } - if (name && !module) { - module = modules[urlNoQuery] = { - id: urlNoQuery, - state: 1 //send - } - var wrap = function (obj) { - resources[res] = obj - obj.load(name, req, function (a) { - if (arguments.length && a !== void 0) { - module.exports = a - } - module.state = 4 - checkDeps() - }) - } - - if (!resources[res]) { - innerRequire([res], wrap) - } else { - wrap(resources[res]) - } - } - return name ? urlNoQuery : res + "!" - } - -//核心API之一 require - var requireQueue = [] - var isUserFirstRequire = false - innerRequire = avalon.require = function (array, factory, parentUrl, defineConfig) { - if (!isUserFirstRequire) { - requireQueue.push(avalon.slice(arguments)) - if (arguments.length <= 2) { - isUserFirstRequire = true - var queue = requireQueue.splice(0, requireQueue.length), args - while (args = queue.shift()) { - innerRequire.apply(null, args) - } - } - return - } - - if (!Array.isArray(array)) { - avalon.error("require方法的第一个参数应为数组 " + array) - } - var deps = [] // 放置所有依赖项的完整路径 - var uniq = {} - var id = parentUrl || "callback" + setTimeout("1")// jshint ignore:line - defineConfig = defineConfig || {} - defineConfig.baseUrl = kernel.baseUrl - var isBuilt = !!defineConfig.built - if (parentUrl) { - defineConfig.parentUrl = parentUrl.substr(0, parentUrl.lastIndexOf("/")) - defineConfig.mapUrl = parentUrl.replace(rjsext, "") - } - if (isBuilt) { - var req = makeRequest(defineConfig.defineName, defineConfig) - id = req.urlNoQuery - } else { - array.forEach(function (name) { - var req = makeRequest(name, defineConfig) - var url = fireRequest(req) //加载资源,并返回该资源的完整地址 - if (url) { - if (!uniq[url]) { - deps.push(url) - uniq[url] = "司徒正美" //去重 - } - } - }) - } - - var module = modules[id] - if (!module || module.state !== 4) { - modules[id] = { - id: id, - deps: isBuilt ? array.concat() : deps, - factory: factory || noop, - state: 3 - } - } - if (!module) { - //如果此模块是定义在另一个JS文件中, 那必须等该文件加载完毕, 才能放到检测列队中 - loadings.push(id) - } - checkDeps() - } - -//核心API之二 require - innerRequire.define = function (name, deps, factory) { //模块名,依赖列表,模块本身 - if (typeof name !== "string") { - factory = deps - deps = name - name = "anonymous" - } - if (!Array.isArray(deps)) { - factory = deps - deps = [] - } - var config = { - built: !isUserFirstRequire, //用r.js打包后,所有define会放到requirejs之前 - defineName: name - } - var args = [deps, factory, config] - factory.require = function (url) { - args.splice(2, 0, url) - if (modules[url]) { - modules[url].state = 3 //loaded - var isCycle = false - try { - isCycle = checkCycle(modules[url].deps, url) - } catch (e) { - } - if (isCycle) { - avalon.error(url + "模块与之前的模块存在循环依赖,请不要直接用script标签引入" + url + "模块") - } - } - delete factory.require //释放内存 - innerRequire.apply(null, args) //0,1,2 --> 1,2,0 - } -//根据标准,所有遵循W3C标准的浏览器,script标签会按标签的出现顺序执行。 -//老的浏览器中,加载也是按顺序的:一个文件下载完成后,才开始下载下一个文件。 -//较新的浏览器中(IE8+ 、FireFox3.5+ 、Chrome4+ 、Safari4+),为了减小请求时间以优化体验, -//下载可以是并行的,但是执行顺序还是按照标签出现的顺序。 -//但如果script标签是动态插入的, 就未必按照先请求先执行的原则了,目测只有firefox遵守 -//唯一比较一致的是,IE10+及其他标准浏览器,一旦开始解析脚本, 就会一直堵在那里,直接脚本解析完毕 -//亦即,先进入loading阶段的script标签(模块)必然会先进入loaded阶段 - var url = config.built ? "unknown" : getCurrentScript() - if (url) { - var module = modules[url] - if (module) { - module.state = 2 - } - factory.require(url) - } else {//合并前后的safari,合并后的IE6-9走此分支 - factorys.push(factory) - } - } -//核心API之三 require.config(settings) - innerRequire.config = kernel - //核心API之四 define.amd 标识其符合AMD规范 - innerRequire.define.amd = modules - - //==========================对用户配置项进行再加工========================== - var allpaths = kernel["orig.paths"] = {} - var allmaps = kernel["orig.map"] = {} - var allpackages = kernel["packages"] = [] - var allargs = kernel["orig.args"] = {} - avalon.mix(plugins, { - paths: function (hash) { - avalon.mix(allpaths, hash) - kernel.paths = makeIndexArray(allpaths) - }, - map: function (hash) { - avalon.mix(allmaps, hash) - var list = makeIndexArray(allmaps, 1, 1) - avalon.each(list, function (_, item) { - item.val = makeIndexArray(item.val) - }) - kernel.map = list - }, - packages: function (array) { - array = array.concat(allpackages) - var uniq = {} - var ret = [] - for (var i = 0, pkg; pkg = array[i++]; ) { - pkg = typeof pkg === "string" ? {name: pkg} : pkg - var name = pkg.name - if (!uniq[name]) { - var url = joinPath(pkg.location || name, pkg.main || "main") - url = url.replace(rjsext, "") - ret.push(pkg) - uniq[name] = pkg.location = url - pkg.reg = makeMatcher(name) - } - } - kernel.packages = ret.sort() - }, - urlArgs: function (hash) { - if (typeof hash === "string") { - hash = {"*": hash} - } - avalon.mix(allargs, hash) - kernel.urlArgs = makeIndexArray(allargs, 1) - }, - baseUrl: function (url) { - if (!isAbsUrl(url)) { - var baseElement = head.getElementsByTagName("base")[0] - if (baseElement) { - head.removeChild(baseElement) - } - var node = DOC.createElement("a") - node.href = url - url = getFullUrl(node, "href") - if (baseElement) { - head.insertBefore(baseElement, head.firstChild) - } - } - if (url.length > 3) - kernel.baseUrl = url - }, - shim: function (obj) { - for (var i in obj) { - var value = obj[i] - if (Array.isArray(value)) { - value = obj[i] = { - deps: value - } - } - if (!value.exportsFn && (value.exports || value.init)) { - value.exportsFn = makeExports(value) - } - } - kernel.shim = obj - } - - }) - - - //==============================内部方法================================= - function checkCycle(deps, nick) { - //检测是否存在循环依赖 - for (var i = 0, id; id = deps[i++]; ) { - if (modules[id].state !== 4 && - (id === nick || checkCycle(modules[id].deps, nick))) { - return true - } - } - } - - function checkFail(node, onError, fuckIE) { - var id = trimQuery(node.src) //检测是否死链 - node.onload = node.onreadystatechange = node.onerror = null - if (onError || (fuckIE && modules[id] && !modules[id].state)) { - setTimeout(function () { - head.removeChild(node) - node = null // 处理旧式IE下的循环引用问题 - }) - log("debug: 加载 " + id + " 失败" + onError + " " + (!modules[id].state)) - } else { - return true - } - } - - function checkDeps() { - //检测此JS模块的依赖是否都已安装完毕,是则安装自身 - loop: for (var i = loadings.length, id; id = loadings[--i]; ) { - var obj = modules[id], - deps = obj.deps - if (!deps) - continue - for (var j = 0, key; key = deps[j]; j++) { - if (Object(modules[key]).state !== 4) { - continue loop - } - } - //如果deps是空对象或者其依赖的模块的状态都是2 - if (obj.state !== 4) { - loadings.splice(i, 1) //必须先移除再安装,防止在IE下DOM树建完后手动刷新页面,会多次执行它 - fireFactory(obj.id, obj.deps, obj.factory) - checkDeps() //如果成功,则再执行一次,以防有些模块就差本模块没有安装好 - } - } - } - - var rreadyState = /complete|loaded/ - function loadJS(url, id, callback) { - //通过script节点加载目标模块 - var node = DOC.createElement("script") - node.className = subscribers //让getCurrentScript只处理类名为subscribers的script节点 - var supportLoad = "onload" in node - var onEvent = supportLoad ? "onload" : "onreadystatechange" - function onload() { - var factory = factorys.pop() - factory && factory.require(id) - if (callback) { - callback() - } - if (checkFail(node, false, !supportLoad)) { - log("debug: 已成功加载 " + url) - id && loadings.push(id) - checkDeps() - } - } - var index = 0, loadID - node[onEvent] = supportLoad ? onload : function () { - if (rreadyState.test(node.readyState)) { - ++index - if (index === 1) { - loadID = setTimeout(onload, 500) - } else { - clearTimeout(loadID) - onload() - } - } - } - node.onerror = function () { - checkFail(node, true) - } - - head.insertBefore(node, head.firstChild) //chrome下第二个参数不能为null - node.src = url //插入到head的第一个节点前,防止IE6下head标签没闭合前使用appendChild抛错 - log("debug: 正准备加载 " + url) //更重要的是IE6下可以收窄getCurrentScript的寻找范围 - } - - var resources = innerRequire.plugins = { - //三大常用资源插件 js!, css!, text!, ready! - ready: { - load: noop - }, - js: { - load: function (name, req, onLoad) { - var url = req.url - var id = req.urlNoQuery - var shim = kernel.shim[name.replace(rjsext, "")] - if (shim) { //shim机制 - innerRequire(shim.deps || [], function () { - var args = avalon.slice(arguments) - loadJS(url, id, function () { - onLoad(shim.exportsFn ? shim.exportsFn.apply(0, args) : void 0) - }) - }) - } else { - loadJS(url, id) - } - } - }, - css: { - load: function (name, req, onLoad) { - var url = req.url - var node = DOC.createElement("link") - node.rel = "stylesheet" - node.href = url - head.insertBefore(node, head.firstChild) - log("debug: 已成功加载 " + url) - onLoad() - } - }, - text: { - load: function (name, req, onLoad) { - var url = req.url - var xhr = getXHR() - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - var status = xhr.status; - if (status > 399 && status < 600) { - avalon.error(url + " 对应资源不存在或没有开启 CORS") - } else { - log("debug: 已成功加载 " + url) - onLoad(xhr.responseText) - } - } - } - var time = "_=" + (new Date() - 0) - var _url = url.indexOf("?") === -1 ? url + "?" + time : url + "&" + time - xhr.open("GET", _url, true) - if ("withCredentials" in xhr) {//这是处理跨域 - xhr.withCredentials = true - } - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")//告诉后端这是AJAX请求 - xhr.send() - log("debug: 正准备加载 " + url) - } - } - } - innerRequire.checkDeps = checkDeps - - var rquery = /(\?[^#]*)$/ - function trimQuery(url) { - return (url || "").replace(rquery, "") - } - - function isAbsUrl(path) { - //http://stackoverflow.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative - return /^(?:[a-z]+:)?\/\//i.test(String(path)) - } - - function getFullUrl(node, src) { - return"1"[0] ? node[src] : node.getAttribute(src, 4) - } - - function getCurrentScript() { - // inspireb by https://github.com/samyk/jiagra/blob/master/jiagra.js - var stack - try { - a.b.c() //强制报错,以便捕获e.stack - } catch (e) { //safari5的sourceURL,firefox的fileName,它们的效果与e.stack不一样 - stack = e.stack - if (!stack && window.opera) { - //opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取 - stack = (String(e).match(/of linked script \S+/g) || []).join(" ") - } - } - if (stack) { - /**e.stack最后一行在所有支持的浏览器大致如下: - *chrome23: - * at http://113.93.50.63/data.js:4:1 - *firefox17: - *@http://113.93.50.63/query.js:4 - *opera12:http://www.oldapps.com/opera.php?system=Windows_XP - *@http://113.93.50.63/data.js:4 - *IE10: - * at Global code (http://113.93.50.63/data.js:4:1) - * //firefox4+ 可以用document.currentScript - */ - stack = stack.split(/[@ ]/g).pop() //取得最后一行,最后一个空格或@之后的部分 - stack = stack[0] === "(" ? stack.slice(1, -1) : stack.replace(/\s/, "") //去掉换行符 - return trimQuery(stack.replace(/(:\d+)?:\d+$/i, "")) //去掉行号与或许存在的出错字符起始位置 - } - var nodes = head.getElementsByTagName("script") //只在head标签中寻找 - for (var i = nodes.length, node; node = nodes[--i]; ) { - if (node.className === subscribers && node.readyState === "interactive") { - var url = getFullUrl(node, "src") - return node.className = trimQuery(url) - } - } - } - - var rcallback = /^callback\d+$/ - function fireFactory(id, deps, factory) { - var module = Object(modules[id]) - module.state = 4 - for (var i = 0, array = [], d; d = deps[i++]; ) { - if (d === "exports") { - var obj = module.exports || (module.exports = {}) - array.push(obj) - } else { - array.push(modules[d].exports) - } - } - try { - var ret = factory.apply(window, array) - } catch (e) { - log("执行[" + id + "]模块的factory抛错: ", e) - } - if (ret !== void 0) { - module.exports = ret - } - if (rcallback.test(id)) { - delete modules[id] - } - delete module.factory - return ret - } - function toUrl(id) { - if (id.indexOf(this.res + "!") === 0) { - id = id.slice(this.res.length + 1) //处理define("css!style",[], function(){})的情况 - } - var url = id - //1. 是否命中paths配置项 - var usePath = 0 - var baseUrl = this.baseUrl - var rootUrl = this.parentUrl || baseUrl - eachIndexArray(id, kernel.paths, function (value, key) { - url = url.replace(key, value) - usePath = 1 - }) - //2. 是否命中packages配置项 - if (!usePath) { - eachIndexArray(id, kernel.packages, function (value, key, item) { - url = url.replace(item.name, item.location) - }) - } - //3. 是否命中map配置项 - if (this.mapUrl) { - eachIndexArray(this.mapUrl, kernel.map, function (array) { - eachIndexArray(url, array, function (mdValue, mdKey) { - url = url.replace(mdKey, mdValue) - rootUrl = baseUrl - }) - }) - } - var ext = this.ext - if (ext && usePath && url.slice(-ext.length) === ext) { - url = url.slice(0, -ext.length) - } - //4. 转换为绝对路径 - if (!isAbsUrl(url)) { - rootUrl = this.built || /^\w/.test(url) ? baseUrl : rootUrl - url = joinPath(rootUrl, url) - } - //5. 还原扩展名,query - var urlNoQuery = url + ext - url = urlNoQuery + this.query - //6. 处理urlArgs - eachIndexArray(id, kernel.urlArgs, function (value) { - url += (url.indexOf("?") === -1 ? "?" : "&") + value; - }) - this.url = url - return this.urlNoQuery = urlNoQuery - } - - function makeIndexArray(hash, useStar, part) { - //创建一个经过特殊算法排好序的数组 - var index = hash2array(hash, useStar, part) - index.sort(descSorterByName) - return index - } - - function makeMatcher(prefix) { - return new RegExp('^' + prefix + '(/|$)') - } - - function makeExports(value) { - return function () { - var ret - if (value.init) { - ret = value.init.apply(window, arguments) - } - return ret || (value.exports && getGlobal(value.exports)) - } - } - - - function hash2array(hash, useStar, part) { - var array = []; - for (var key in hash) { - if (ohasOwn.call(hash, key)) { - var item = { - name: key, - val: hash[key] - } - array.push(item) - item.reg = key === "*" && useStar ? /^/ : makeMatcher(key) - if (part && key !== "*") { - item.reg = new RegExp('\/' + key.replace(/^\//, "") + '(/|$)') - } - } - } - return array - } - - function eachIndexArray(moduleID, array, matcher) { - array = array || [] - for (var i = 0, el; el = array[i++]; ) { - if (el.reg.test(moduleID)) { - matcher(el.val, el.name, el) - return false - } - } - } - // 根据元素的name项进行数组字符数逆序的排序函数 - function descSorterByName(a, b) { - var aaa = a.name - var bbb = b.name - if (bbb === "*") { - return -1 - } - if (aaa === "*") { - return 1 - } - return bbb.length - aaa.length - } - - var rdeuce = /\/\w+\/\.\./ - function joinPath(a, b) { - if (a.charAt(a.length - 1) !== "/") { - a += "/" - } - if (b.slice(0, 2) === "./") { //相对于兄弟路径 - return a + b.slice(2) - } - if (b.slice(0, 2) === "..") { //相对于父路径 - a += b - while (rdeuce.test(a)) { - a = a.replace(rdeuce, "") - } - return a - } - if (b.slice(0, 1) === "/") { - return a + b.slice(1) - } - return a + b - } - - function getGlobal(value) { - if (!value) { - return value - } - var g = window - value.split(".").forEach(function (part) { - g = g[part] - }) - return g - } - - var mainNode = DOC.scripts[DOC.scripts.length - 1] - var dataMain = mainNode.getAttribute("data-main") - if (dataMain) { - plugins.baseUrl(dataMain) - var href = kernel.baseUrl - kernel.baseUrl = href.slice(0, href.lastIndexOf("/") + 1) - loadJS(href.replace(rjsext, "") + ".js") - } else { - var loaderUrl = trimQuery(getFullUrl(mainNode, "src")) - kernel.baseUrl = loaderUrl.slice(0, loaderUrl.lastIndexOf("/") + 1) - } -}// jshint ignore:line - -/********************************************************************* - * DOMReady * - **********************************************************************/ - -var readyList = [], isReady -var fireReady = function(fn) { - isReady = true - if (innerRequire) { - modules["domReady!"].state = 4 - innerRequire.checkDeps() - } - while(fn = readyList.shift()){ - fn(avalon) - } -} - -function doScrollCheck() { - try { //IE下通过doScrollCheck检测DOM树是否建完 - root.doScroll("left") - fireReady() - } catch (e) { - setTimeout(doScrollCheck) - } -} - -if (DOC.readyState === "complete") { - setTimeout(fireReady) //如果在domReady之外加载 -} else if (W3C) { - DOC.addEventListener("DOMContentLoaded", fireReady) -} else { - DOC.attachEvent("onreadystatechange", function() { - if (DOC.readyState === "complete") { - fireReady() - } - }) - try { - var isTop = window.frameElement === null - } catch (e) { - } - if (root.doScroll && isTop && window.external) {//fix IE iframe BUG - doScrollCheck() - } -} -avalon.bind(window, "load", fireReady) - -avalon.ready = function(fn) { - if (!isReady) { - readyList.push(fn) - } else { - fn(avalon) - } -} - -avalon.config({ - loader: true -}) - -avalon.ready(function() { - avalon.scan(DOC.body) -}) - -// Register as a named AMD module, since avalon can be concatenated with other -// files that may use define, but not via a proper concatenation script that -// understands anonymous AMD modules. A named AMD is safest and most robust -// way to register. Lowercase avalon is used because AMD module names are -// derived from file names, and Avalon is normally delivered in a lowercase -// file name. Do this after creating the global so that if an AMD module wants -// to call noConflict to hide this version of avalon, it will work. - -// Note that for maximum portability, libraries that are not avalon should -// declare themselves as anonymous modules, and avoid setting a global if an -// AMD loader is present. avalon is a special case. For more information, see -// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon - if (typeof define === "function" && define.amd) { - define("avalon", [], function() { - return avalon - }) - } -// Map over avalon in case of overwrite - var _avalon = window.avalon - avalon.noConflict = function(deep) { - if (deep && window.avalon === avalon) { - window.avalon = _avalon - } - return avalon - } -// Expose avalon identifiers, even in AMD -// and CommonJS for browser emulators - if (noGlobal === void 0) { - window.avalon = avalon - } - return avalon - -})); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js deleted file mode 100644 index c6c087b..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/bootstrap/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); \ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css deleted file mode 100644 index 4279313..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.css +++ /dev/null @@ -1,309 +0,0 @@ - -div.dataTables_length label { - font-weight: normal; - text-align: left; - white-space: nowrap; -} - -div.dataTables_length select { - width: 75px; - display: inline-block; -} - -div.dataTables_filter { - text-align: right; -} - -div.dataTables_filter label { - font-weight: normal; - white-space: nowrap; - text-align: left; -} - -div.dataTables_filter input { - margin-left: 0.5em; - display: inline-block; -} - -div.dataTables_info { - padding-top: 8px; - white-space: nowrap; -} - -div.dataTables_paginate { - margin: 0; - white-space: nowrap; - text-align: right; -} - -div.dataTables_paginate ul.pagination { - margin: 2px 0; - white-space: nowrap; -} - -@media screen and (max-width: 767px) { - div.dataTables_length, - div.dataTables_filter, - div.dataTables_info, - div.dataTables_paginate { - text-align: center; - } -} - - -table.dataTable td, -table.dataTable th { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - - -table.dataTable { - clear: both; - margin-top: 6px !important; - margin-bottom: 6px !important; - max-width: none !important; -} - -table.dataTable thead .sorting, -table.dataTable thead .sorting_asc, -table.dataTable thead .sorting_desc, -table.dataTable thead .sorting_asc_disabled, -table.dataTable thead .sorting_desc_disabled { - cursor: pointer; -} - - -table.dataTable thead > tr > th { - padding-left: 18px; - padding-right: 18px; -} - -table.dataTable th:active { - outline: none; -} - -/* Scrolling */ -div.dataTables_scrollHead table { - margin-bottom: 0 !important; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -div.dataTables_scrollHead table thead tr:last-child th:first-child, -div.dataTables_scrollHead table thead tr:last-child td:first-child { - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.dataTables_scrollBody table { - border-top: none; - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -div.dataTables_scrollBody tbody tr:first-child th, -div.dataTables_scrollBody tbody tr:first-child td { - border-top: none; -} - -div.dataTables_scrollFoot table { - margin-top: 0 !important; - border-top: none; -} - -/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column - width calculations when using scrolling impossible to align columns. We have - to use separate - */ -table.table-bordered.dataTable { - border-collapse: separate !important; -} -table.table-bordered thead th, -table.table-bordered thead td { - border-left-width: 0; - border-top-width: 0; -} -table.table-bordered tbody th, -table.table-bordered tbody td { - border-left-width: 0; - border-bottom-width: 0; -} -table.table-bordered th:last-child, -table.table-bordered td:last-child { - border-right-width: 0; -} -div.dataTables_scrollHead table.table-bordered { - border-bottom-width: 0; -} - - - - -/* - * TableTools styles - */ -.table.dataTable tbody tr.active td, -.table.dataTable tbody tr.active th { - background-color: #08C; - color: white; -} - -.table.dataTable tbody tr.active:hover td, -.table.dataTable tbody tr.active:hover th { - background-color: #0075b0 !important; -} - -.table.dataTable tbody tr.active th > a, -.table.dataTable tbody tr.active td > a { - color: white; -} - -.table-striped.dataTable tbody tr.active:nth-child(odd) td, -.table-striped.dataTable tbody tr.active:nth-child(odd) th { - background-color: #017ebc; -} - -table.DTTT_selectable tbody tr { - cursor: pointer; -} - -div.DTTT .btn:hover { - text-decoration: none !important; -} - -ul.DTTT_dropdown.dropdown-menu { - z-index: 2003; -} - -ul.DTTT_dropdown.dropdown-menu a { - color: #333 !important; /* needed only when demo_page.css is included */ -} - -ul.DTTT_dropdown.dropdown-menu li { - position: relative; -} - -ul.DTTT_dropdown.dropdown-menu li:hover a { - background-color: #0088cc; - color: white !important; -} - -div.DTTT_collection_background { - z-index: 2002; -} - -/* TableTools information display */ -div.DTTT_print_info { - position: fixed; - top: 50%; - left: 50%; - width: 400px; - height: 150px; - margin-left: -200px; - margin-top: -75px; - text-align: center; - color: #333; - padding: 10px 30px; - opacity: 0.95; - - background-color: white; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); -} - -div.DTTT_print_info h6 { - font-weight: normal; - font-size: 28px; - line-height: 28px; - margin: 1em; -} - -div.DTTT_print_info p { - font-size: 14px; - line-height: 20px; -} - -div.dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 100%; - height: 60px; - margin-left: -50%; - margin-top: -25px; - padding-top: 20px; - padding-bottom: 20px; - text-align: center; - font-size: 1.2em; - background-color: white; - background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0))); - background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); - background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); - background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); - background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); - background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); -} - - - -/* - * FixedColumns styles - */ -div.DTFC_LeftHeadWrapper table, -div.DTFC_LeftFootWrapper table, -div.DTFC_RightHeadWrapper table, -div.DTFC_RightFootWrapper table, -table.DTFC_Cloned tr.even { - background-color: white; - margin-bottom: 0; -} - -div.DTFC_RightHeadWrapper table , -div.DTFC_LeftHeadWrapper table { - border-bottom: none !important; - margin-bottom: 0 !important; - border-top-right-radius: 0 !important; - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, -div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, -div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, -div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.DTFC_RightBodyWrapper table, -div.DTFC_LeftBodyWrapper table { - border-top: none; - margin: 0 !important; -} - -div.DTFC_RightBodyWrapper tbody tr:first-child th, -div.DTFC_RightBodyWrapper tbody tr:first-child td, -div.DTFC_LeftBodyWrapper tbody tr:first-child th, -div.DTFC_LeftBodyWrapper tbody tr:first-child td { - border-top: none; -} - -div.DTFC_RightFootWrapper table, -div.DTFC_LeftFootWrapper table { - border-top: none; - margin-top: 0 !important; -} - - -/* - * FixedHeader styles - */ -div.FixedHeader_Cloned table { - margin: 0 !important -} - diff --git a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js b/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js deleted file mode 100644 index f0d09b9..0000000 --- a/msb-core/apiroute/apiroute-service/src/main/resources/iui-route/js/dataTables/dataTables.bootstrap.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - DataTables Bootstrap 3 integration - ©2011-2014 SpryMedia Ltd - datatables.net/license -*/ -(function(){var f=function(c,b){c.extend(!0,b.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'p>>",renderer:"bootstrap"});c.extend(b.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"});b.ext.renderer.pageButton.bootstrap=function(g,f,p,k,h,l){var q=new b.Api(g),r=g.oClasses,i=g.oLanguage.oPaginate,d,e,o=function(b,f){var j,m,n,a,k=function(a){a.preventDefault(); -c(a.currentTarget).hasClass("disabled")||q.page(a.data.action).draw(!1)};j=0;for(m=f.length;j",{"class":r.sPageButton+" "+ -e,"aria-controls":g.sTableId,tabindex:g.iTabIndex,id:0===p&&"string"===typeof a?g.sTableId+"_"+a:null}).append(c("",{href:"#"}).html(d)).appendTo(b),g.oApi._fnBindAction(n,{action:a},k))}};o(c(f).empty().html('