From d3ab0372565dbdbf202d819f071539e5047615dc Mon Sep 17 00:00:00 2001 From: lj1412 Date: Tue, 14 Feb 2017 15:10:01 +0000 Subject: Init dcae.dmaapbc Change-Id: I67a7bab881544651bbff6bedb9551975c7ee10ca Signed-off-by: lj1412 --- .classpath | 31 + .gitignore | 26 + .gitreview | 4 + .metadata/.lock | 0 .metadata/.log | 22 + .metadata/.mylyn/repositories.xml.zip | Bin 0 -> 442 bytes .../.indexes/properties.index | Bin 0 -> 80 bytes .../GitProjectData.properties | 3 + .../.root/.indexes/history.version | 1 + .../.root/.indexes/properties.index | Bin 0 -> 151 bytes .../.root/.indexes/properties.version | 1 + .../org.eclipse.core.resources/.root/1.tree | Bin 0 -> 228 bytes .../.safetable/org.eclipse.core.resources | Bin 0 -> 688 bytes .../org.eclipse.e4.workbench/workbench.xmi | 2602 +++ .../org.eclipse.jdt.core/invalidArchivesCache | Bin 0 -> 4 bytes .../org.eclipse.jdt.core/nonChainingJarsCache | Bin 0 -> 4 bytes .../variablesAndContainers.dat | Bin 0 -> 129 bytes .../org.eclipse.jdt.ui/OpenTypeHistory.xml | 2 + .../QualifiedTypeNameHistory.xml | 2 + .../org.eclipse.m2e.logback.configuration/0.log | 0 .../logback.1.4.0.20130601-0317.xml | 41 + .metadata/.plugins/org.eclipse.rse.core/.log | 0 ...nternal.core.RSELocalConnectionInitializer.mark | 0 .../FP.local.files_0/node.properties | 57 + .../PRF.lt-dlunanuova_0/H.local_16/node.properties | 25 + .../profiles/PRF.lt-dlunanuova_0/node.properties | 7 + .metadata/.plugins/org.eclipse.rse.ui/.log | 0 .../org.eclipse.ui.workbench/dialog_settings.xml | 15 + .metadata/version.ini | 1 + .project | 36 + Dockerfile | 26 + LICENSE.txt | 22 + README.md | 84 + RemoteSystemsTempFiles/.project | 12 + config/README | 5 + config/policyLogger.properties | 24 + curversion | 2 + misc/LocalKey | 27 + misc/PolicyEngineApi.properties.tmpl | 14 + misc/dmaapbc | 151 + misc/dmaapbc.properties.tmpl | 152 + misc/doaction | 43 + misc/havecert.tmpl | 11 + misc/log4j.properties.tmpl | 11 + misc/opensource.env | 99 + misc/policyLogger.properties | 24 + policyLogger.properties | 24 + pom.xml | 274 + .../org/openecomp/dmaapbc/aaf/AafConnection.java | 194 + .../java/org/openecomp/dmaapbc/aaf/AafObject.java | 33 + .../java/org/openecomp/dmaapbc/aaf/AafService.java | 131 + .../org/openecomp/dmaapbc/aaf/AndrewDecryptor.java | 68 + .../java/org/openecomp/dmaapbc/aaf/DmaapGrant.java | 67 + .../java/org/openecomp/dmaapbc/aaf/DmaapPerm.java | 71 + .../AuthenticationErrorException.java | 29 + .../dmaapbc/authentication/DecisionPolicy.java | 157 + .../openecomp/dmaapbc/client/DrProvConnection.java | 453 + .../openecomp/dmaapbc/client/MrProvConnection.java | 187 + .../dmaapbc/client/MrTopicConnection.java | 168 + .../openecomp/dmaapbc/database/ConnWrapper.java | 63 + .../dmaapbc/database/ConnectionFactory.java | 77 + .../openecomp/dmaapbc/database/DBException.java | 31 + .../openecomp/dmaapbc/database/DBFieldHandler.java | 194 + .../java/org/openecomp/dmaapbc/database/DBMap.java | 138 + .../openecomp/dmaapbc/database/DBSingleton.java | 98 + .../openecomp/dmaapbc/database/DatabaseClass.java | 268 + .../org/openecomp/dmaapbc/database/LoadSchema.java | 105 + .../openecomp/dmaapbc/database/TableHandler.java | 115 + .../java/org/openecomp/dmaapbc/model/ApiError.java | 56 + .../java/org/openecomp/dmaapbc/model/BrTopic.java | 65 + .../java/org/openecomp/dmaapbc/model/DR_Node.java | 78 + .../java/org/openecomp/dmaapbc/model/DR_Pub.java | 136 + .../java/org/openecomp/dmaapbc/model/DR_Sub.java | 206 + .../org/openecomp/dmaapbc/model/DcaeLocation.java | 103 + .../java/org/openecomp/dmaapbc/model/Dmaap.java | 133 + .../org/openecomp/dmaapbc/model/DmaapObject.java | 68 + .../java/org/openecomp/dmaapbc/model/Feed.java | 279 + .../org/openecomp/dmaapbc/model/MR_Client.java | 121 + .../org/openecomp/dmaapbc/model/MR_Cluster.java | 124 + .../org/openecomp/dmaapbc/model/MirrorMaker.java | 202 + .../openecomp/dmaapbc/model/ReplicationVector.java | 104 + .../java/org/openecomp/dmaapbc/model/Topic.java | 165 + .../openecomp/dmaapbc/resources/ApiResource.java | 45 + .../dmaapbc/resources/BridgeResource.java | 111 + .../dmaapbc/resources/DR_NodeResource.java | 183 + .../dmaapbc/resources/DR_PubResource.java | 270 + .../dmaapbc/resources/DR_SubResource.java | 253 + .../dmaapbc/resources/DcaeLocationResource.java | 185 + .../openecomp/dmaapbc/resources/DmaapResource.java | 140 + .../openecomp/dmaapbc/resources/FeedResource.java | 227 + .../dmaapbc/resources/MR_ClientResource.java | 267 + .../dmaapbc/resources/MR_ClusterResource.java | 195 + .../dmaapbc/resources/RequiredFieldException.java | 30 + .../openecomp/dmaapbc/resources/TopicResource.java | 184 + .../org/openecomp/dmaapbc/server/JettyServer.java | 144 + .../java/org/openecomp/dmaapbc/server/Main.java | 70 + .../org/openecomp/dmaapbc/service/ApiService.java | 176 + .../openecomp/dmaapbc/service/DR_NodeService.java | 118 + .../openecomp/dmaapbc/service/DR_PubService.java | 144 + .../openecomp/dmaapbc/service/DR_SubService.java | 141 + .../dmaapbc/service/DcaeLocationService.java | 86 + .../openecomp/dmaapbc/service/DmaapService.java | 233 + .../org/openecomp/dmaapbc/service/FeedService.java | 314 + .../dmaapbc/service/MR_ClientService.java | 181 + .../dmaapbc/service/MR_ClusterService.java | 133 + .../dmaapbc/service/MirrorMakerService.java | 137 + .../openecomp/dmaapbc/service/TopicService.java | 240 + .../org/openecomp/dmaapbc/util/DmaapConfig.java | 50 + .../org/openecomp/dmaapbc/util/DmaapTimestamp.java | 51 + .../java/org/openecomp/dmaapbc/util/Graph.java | 111 + .../org/openecomp/dmaapbc/util/RandomInteger.java | 61 + .../org/openecomp/dmaapbc/util/RandomString.java | 55 + .../java/org/openecomp/dmaapbc/util/Singleton.java | 28 + src/main/resources/log4j.properties | 29 + src/main/resources/schema_0.sql | 35 + src/main/resources/schema_1.sql | 136 + src/main/resources/schema_2.sql | 51 + src/main/resources/schema_3.sql | 29 + src/main/resources/schema_4.sql | 33 + src/main/resources/schema_5.sql | 25 + src/main/resources/schema_6.sql | 33 + src/main/webapp/HelloJetty.html | 30 + src/main/webapp/WEB-INF/log4j.xml | 45 + src/main/webapp/WEB-INF/web.xml | 38 + src/main/webapp/index.jsp | 28 + www/curversion | 2 + www/dmaapBC_1_1_4.pdf | Bin 0 -> 403381 bytes www/index.html | 29 + www/policyLogger.properties | 24 + www/swagger/404.html | 133 + www/swagger/CNAME | 1 + www/swagger/css/print.css | 1361 ++ www/swagger/css/reset.css | 125 + www/swagger/css/screen.css | 1488 ++ www/swagger/css/style.css | 250 + www/swagger/css/typography.css | 14 + www/swagger/fonts/DroidSans-Bold.ttf | Bin 0 -> 42480 bytes www/swagger/fonts/DroidSans.ttf | Bin 0 -> 41028 bytes www/swagger/images/collapse.gif | Bin 0 -> 69 bytes www/swagger/images/expand.gif | Bin 0 -> 73 bytes www/swagger/images/explorer_icons.png | Bin 0 -> 5763 bytes www/swagger/images/favicon-16x16.png | Bin 0 -> 645 bytes www/swagger/images/favicon-32x32.png | Bin 0 -> 1654 bytes www/swagger/images/favicon.ico | Bin 0 -> 5430 bytes www/swagger/images/logo_small.png | Bin 0 -> 770 bytes www/swagger/images/pet_store_api.png | Bin 0 -> 824 bytes www/swagger/images/throbber.gif | Bin 0 -> 9257 bytes www/swagger/images/wordnik_api.png | Bin 0 -> 980 bytes www/swagger/index.html | 128 + www/swagger/lang/en.js | 56 + www/swagger/lang/es.js | 53 + www/swagger/lang/fr.js | 54 + www/swagger/lang/geo.js | 56 + www/swagger/lang/it.js | 52 + www/swagger/lang/ja.js | 53 + www/swagger/lang/pl.js | 53 + www/swagger/lang/pt.js | 53 + www/swagger/lang/ru.js | 56 + www/swagger/lang/tr.js | 53 + www/swagger/lang/translator.js | 39 + www/swagger/lang/zh-cn.js | 53 + www/swagger/lib/backbone-min.js | 15 + www/swagger/lib/handlebars-2.0.0.js | 28 + www/swagger/lib/highlight.9.1.0.pack.js | 2 + www/swagger/lib/highlight.9.1.0.pack_extended.js | 34 + www/swagger/lib/jquery-1.8.0.min.js | 2 + www/swagger/lib/jquery.ba-bbq.min.js | 18 + www/swagger/lib/jquery.slideto.min.js | 1 + www/swagger/lib/jquery.wiggle.min.js | 8 + www/swagger/lib/js-yaml.min.js | 3 + www/swagger/lib/jsoneditor.min.js | 11 + www/swagger/lib/lodash.min.js | 102 + www/swagger/lib/marked.js | 1272 ++ www/swagger/lib/swagger-oauth.js | 339 + www/swagger/spec-files/basic-auth.yaml | 28 + www/swagger/spec-files/default.yaml | 277 + www/swagger/spec-files/echo.yaml | 43 + www/swagger/spec-files/guide.yaml | 49 + www/swagger/spec-files/heroku-pets.yaml | 82 + www/swagger/spec-files/instagram.yaml | 1064 + www/swagger/spec-files/minimal.yaml | 11 + www/swagger/spec-files/petstore_full.yaml | 576 + www/swagger/spec-files/petstore_simple.yaml | 157 + www/swagger/spec-files/security.yaml | 171 + www/swagger/spec-files/twitter.yaml | 3083 +++ www/swagger/swagger-ui.js | 22190 +++++++++++++++++++ www/swagger/swagger-ui.min.js | 9 + 187 files changed, 47204 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .gitreview create mode 100644 .metadata/.lock create mode 100644 .metadata/.log create mode 100644 .metadata/.mylyn/repositories.xml.zip create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.root/1.tree create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources create mode 100644 .metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi create mode 100644 .metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache create mode 100644 .metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache create mode 100644 .metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml create mode 100644 .metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml create mode 100644 .metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log create mode 100644 .metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.4.0.20130601-0317.xml create mode 100644 .metadata/.plugins/org.eclipse.rse.core/.log create mode 100644 .metadata/.plugins/org.eclipse.rse.core/initializerMarks/org.eclipse.rse.internal.core.RSELocalConnectionInitializer.mark create mode 100644 .metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/FP.local.files_0/node.properties create mode 100644 .metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/H.local_16/node.properties create mode 100644 .metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/node.properties create mode 100644 .metadata/.plugins/org.eclipse.rse.ui/.log create mode 100644 .metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml create mode 100644 .metadata/version.ini create mode 100644 .project create mode 100644 Dockerfile create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 RemoteSystemsTempFiles/.project create mode 100644 config/README create mode 100644 config/policyLogger.properties create mode 100644 curversion create mode 100644 misc/LocalKey create mode 100644 misc/PolicyEngineApi.properties.tmpl create mode 100755 misc/dmaapbc create mode 100755 misc/dmaapbc.properties.tmpl create mode 100644 misc/doaction create mode 100644 misc/havecert.tmpl create mode 100755 misc/log4j.properties.tmpl create mode 100644 misc/opensource.env create mode 100644 misc/policyLogger.properties create mode 100644 policyLogger.properties create mode 100644 pom.xml create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/AafConnection.java create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/AafObject.java create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/AafService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/AndrewDecryptor.java create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/DmaapGrant.java create mode 100644 src/main/java/org/openecomp/dmaapbc/aaf/DmaapPerm.java create mode 100644 src/main/java/org/openecomp/dmaapbc/authentication/AuthenticationErrorException.java create mode 100644 src/main/java/org/openecomp/dmaapbc/authentication/DecisionPolicy.java create mode 100644 src/main/java/org/openecomp/dmaapbc/client/DrProvConnection.java create mode 100644 src/main/java/org/openecomp/dmaapbc/client/MrProvConnection.java create mode 100644 src/main/java/org/openecomp/dmaapbc/client/MrTopicConnection.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/ConnWrapper.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/ConnectionFactory.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/DBException.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/DBFieldHandler.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/DBMap.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/DBSingleton.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/DatabaseClass.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/LoadSchema.java create mode 100644 src/main/java/org/openecomp/dmaapbc/database/TableHandler.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/ApiError.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/BrTopic.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/DR_Node.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/DR_Pub.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/DR_Sub.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/DcaeLocation.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/Dmaap.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/DmaapObject.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/Feed.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/MR_Client.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/MR_Cluster.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/MirrorMaker.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/ReplicationVector.java create mode 100644 src/main/java/org/openecomp/dmaapbc/model/Topic.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/ApiResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/BridgeResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/DR_NodeResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/DR_PubResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/DR_SubResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/DcaeLocationResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/DmaapResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/FeedResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/MR_ClientResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/MR_ClusterResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/RequiredFieldException.java create mode 100644 src/main/java/org/openecomp/dmaapbc/resources/TopicResource.java create mode 100644 src/main/java/org/openecomp/dmaapbc/server/JettyServer.java create mode 100644 src/main/java/org/openecomp/dmaapbc/server/Main.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/ApiService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/DR_NodeService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/DR_PubService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/DR_SubService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/DcaeLocationService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/DmaapService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/FeedService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/MR_ClientService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/MR_ClusterService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/MirrorMakerService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/service/TopicService.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/DmaapConfig.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/DmaapTimestamp.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/Graph.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/RandomInteger.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/RandomString.java create mode 100644 src/main/java/org/openecomp/dmaapbc/util/Singleton.java create mode 100644 src/main/resources/log4j.properties create mode 100644 src/main/resources/schema_0.sql create mode 100644 src/main/resources/schema_1.sql create mode 100644 src/main/resources/schema_2.sql create mode 100644 src/main/resources/schema_3.sql create mode 100644 src/main/resources/schema_4.sql create mode 100644 src/main/resources/schema_5.sql create mode 100644 src/main/resources/schema_6.sql create mode 100644 src/main/webapp/HelloJetty.html create mode 100644 src/main/webapp/WEB-INF/log4j.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.jsp create mode 100644 www/curversion create mode 100644 www/dmaapBC_1_1_4.pdf create mode 100644 www/index.html create mode 100644 www/policyLogger.properties create mode 100644 www/swagger/404.html create mode 100644 www/swagger/CNAME create mode 100644 www/swagger/css/print.css create mode 100644 www/swagger/css/reset.css create mode 100644 www/swagger/css/screen.css create mode 100644 www/swagger/css/style.css create mode 100644 www/swagger/css/typography.css create mode 100644 www/swagger/fonts/DroidSans-Bold.ttf create mode 100644 www/swagger/fonts/DroidSans.ttf create mode 100644 www/swagger/images/collapse.gif create mode 100644 www/swagger/images/expand.gif create mode 100644 www/swagger/images/explorer_icons.png create mode 100644 www/swagger/images/favicon-16x16.png create mode 100644 www/swagger/images/favicon-32x32.png create mode 100644 www/swagger/images/favicon.ico create mode 100644 www/swagger/images/logo_small.png create mode 100644 www/swagger/images/pet_store_api.png create mode 100644 www/swagger/images/throbber.gif create mode 100644 www/swagger/images/wordnik_api.png create mode 100644 www/swagger/index.html create mode 100644 www/swagger/lang/en.js create mode 100644 www/swagger/lang/es.js create mode 100644 www/swagger/lang/fr.js create mode 100644 www/swagger/lang/geo.js create mode 100644 www/swagger/lang/it.js create mode 100644 www/swagger/lang/ja.js create mode 100644 www/swagger/lang/pl.js create mode 100644 www/swagger/lang/pt.js create mode 100644 www/swagger/lang/ru.js create mode 100644 www/swagger/lang/tr.js create mode 100644 www/swagger/lang/translator.js create mode 100644 www/swagger/lang/zh-cn.js create mode 100644 www/swagger/lib/backbone-min.js create mode 100644 www/swagger/lib/handlebars-2.0.0.js create mode 100644 www/swagger/lib/highlight.9.1.0.pack.js create mode 100644 www/swagger/lib/highlight.9.1.0.pack_extended.js create mode 100644 www/swagger/lib/jquery-1.8.0.min.js create mode 100644 www/swagger/lib/jquery.ba-bbq.min.js create mode 100644 www/swagger/lib/jquery.slideto.min.js create mode 100644 www/swagger/lib/jquery.wiggle.min.js create mode 100644 www/swagger/lib/js-yaml.min.js create mode 100644 www/swagger/lib/jsoneditor.min.js create mode 100644 www/swagger/lib/lodash.min.js create mode 100644 www/swagger/lib/marked.js create mode 100644 www/swagger/lib/swagger-oauth.js create mode 100644 www/swagger/spec-files/basic-auth.yaml create mode 100644 www/swagger/spec-files/default.yaml create mode 100644 www/swagger/spec-files/echo.yaml create mode 100644 www/swagger/spec-files/guide.yaml create mode 100644 www/swagger/spec-files/heroku-pets.yaml create mode 100644 www/swagger/spec-files/instagram.yaml create mode 100644 www/swagger/spec-files/minimal.yaml create mode 100644 www/swagger/spec-files/petstore_full.yaml create mode 100644 www/swagger/spec-files/petstore_simple.yaml create mode 100644 www/swagger/spec-files/security.yaml create mode 100644 www/swagger/spec-files/twitter.yaml create mode 100644 www/swagger/swagger-ui.js create mode 100644 www/swagger/swagger-ui.min.js diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..3f7590f --- /dev/null +++ b/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca8db20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# ignore all bin directories +# matches "bin" in any subfolder +bin/ + +# ignore all target directories +target/ + +# ignore logs that might be laying around +logs/ + +# ignore laptop eclipse settings +.settings/ +localEclipse/ + +# ignore local targets +dmaapbc.jar +repository/ +misc/dmaapbc_init.dat + +# ignore package tmp dirs +stage/ +tmp/ + +# ignore blackduck files +*.jsonld + diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..a66e424 --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=gerrit.openecomp.org +port=29418 +project=dcae/dmaapbc.git diff --git a/.metadata/.lock b/.metadata/.lock new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.log b/.metadata/.log new file mode 100644 index 0000000..50f33b9 --- /dev/null +++ b/.metadata/.log @@ -0,0 +1,22 @@ +!SESSION 2016-04-13 08:59:56.943 ----------------------------------------------- +eclipse.buildId=4.3.2.M20140221-1700 +java.version=1.8.0_77 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.egit.ui 2 0 2016-04-13 09:00:29.644 +!MESSAGE Warning: EGit couldn't detect the installation path "gitPrefix" of native Git. Hence EGit can't respect system level +Git settings which might be configured in ${gitPrefix}/etc/gitconfig under the native Git installation directory. +The most important of these settings is core.autocrlf. Git for Windows by default sets this parameter to true in +this system level configuration. The Git installation location can be configured on the +Team > Git > Configuration preference page's 'System Settings' tab. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.egit.ui 2 0 2016-04-13 09:00:29.646 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\dgl'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. diff --git a/.metadata/.mylyn/repositories.xml.zip b/.metadata/.mylyn/repositories.xml.zip new file mode 100644 index 0000000..45a4787 Binary files /dev/null and b/.metadata/.mylyn/repositories.xml.zip differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index new file mode 100644 index 0000000..1e099f3 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties new file mode 100644 index 0000000..aebf3c8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/org.eclipse.egit.core/GitProjectData.properties @@ -0,0 +1,3 @@ +#GitProjectData +#Wed Apr 13 09:00:32 EDT 2016 +.gitdir=../../.git diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version new file mode 100644 index 0000000..25cb955 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index new file mode 100644 index 0000000..3542955 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version new file mode 100644 index 0000000..6b2aaa7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree new file mode 100644 index 0000000..bf75d6f Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources new file mode 100644 index 0000000..cdb7082 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi new file mode 100644 index 0000000..2cfa328 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -0,0 +1,2602 @@ + + + + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration + ModelMigrationProcessor.001 + + + + + + topLevel + + + + + persp.actionSet:org.eclipse.mylyn.context.ui.actionSet + persp.actionSet:org.eclipse.mylyn.doc.actionSet + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation + persp.actionSet:org.eclipse.ui.cheatsheets.actionSet + persp.actionSet:org.eclipse.rse.core.search.searchActionSet + persp.actionSet:org.eclipse.search.searchActionSet + persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo + persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet + persp.actionSet:org.eclipse.ui.actionSet.keyBindings + persp.actionSet:org.eclipse.ui.actionSet.openFiles + persp.actionSet:org.eclipse.jst.j2ee.J2eeMainActionSet + persp.actionSet:org.eclipse.jdt.ui.JavaActionSet + persp.actionSet:org.eclipse.debug.ui.launchActionSet + persp.actionSet:org.eclipse.debug.ui.debugActionSet + persp.actionSet:org.eclipse.ui.NavigateActionSet + persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer + persp.viewSC:org.eclipse.wst.server.ui.ServersView + persp.viewSC:org.eclipse.datatools.connectivity.DataSourceExplorerNavigator + persp.viewSC:org.eclipse.ui.views.BookmarkView + persp.viewSC:org.eclipse.ui.views.ContentOutline + persp.viewSC:org.eclipse.ui.views.PropertySheet + persp.viewSC:org.eclipse.ui.views.ResourceNavigator + persp.viewSC:org.eclipse.wst.common.snippets.internal.ui.SnippetsView + persp.viewSC:org.eclipse.ui.views.AllMarkersView + persp.viewSC:org.eclipse.mylyn.tasks.ui.views.tasks + persp.viewSC:org.eclipse.search.ui.views.SearchView + persp.viewSC:org.eclipse.ui.console.ConsoleView + persp.showIn:org.eclipse.ui.navigator.ProjectExplorer + persp.newWizSC:org.eclipse.jpt.jpa.ui.wizard.newJpaProject + persp.perspSC:org.eclipse.jpt.ui.jpaPerspective + persp.perspSC:org.eclipse.debug.ui.DebugPerspective + persp.perspSC:org.eclipse.jdt.ui.JavaPerspective + persp.perspSC:org.eclipse.ui.resourcePerspective + persp.perspSC:org.eclipse.wst.web.ui.webDevPerspective + persp.newWizSC:org.eclipse.jst.j2ee.ui.project.facet.EarProjectWizard + persp.newWizSC:org.eclipse.jst.servlet.ui.project.facet.WebProjectWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.project.facet.EjbProjectWizard + persp.newWizSC:org.eclipse.jst.j2ee.jca.ui.internal.wizard.ConnectorProjectWizard + persp.newWizSC:org.eclipse.jst.j2ee.ui.project.facet.appclient.AppClientProjectWizard + persp.newWizSC:org.eclipse.wst.web.ui.internal.wizards.SimpleWebProjectWizard + persp.newWizSC:org.eclipse.jpt.ui.wizard.newJpaProject + persp.newWizSC:org.eclipse.jst.servlet.ui.internal.wizard.AddServletWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.internal.wizard.AddSessionBeanWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.internal.wizard.AddMessageDrivenBeanWizard + persp.newWizSC:org.eclipse.jpt.ui.wizard.newEntity + persp.newWizSC:org.eclipse.jst.ws.creation.ui.wizard.serverwizard + persp.newWizSC:org.eclipse.ui.wizards.new.folder + persp.newWizSC:org.eclipse.ui.wizards.new.file + persp.actionSet:org.eclipse.wst.server.ui.internal.webbrowser.actionSet + persp.actionSet:org.eclipse.debug.ui.breakpointActionSet + persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard + persp.actionSet:org.eclipse.wst.ws.explorer.explorer + + + newtablook + + + + + + + + + + newtablook + + + + + + newtablook + + + + + + + + + + + + + + + + + + active + + + + + + + View + categoryTag:Help + + + View + categoryTag:General + active + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:Help + + + + newtablook + org.eclipse.e4.primaryDataStack + EditorStack + + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:General + + + View + categoryTag:Java + + + View + categoryTag:Java Browsing + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:General + + + View + categoryTag:Server + + + View + categoryTag:Data Management + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:Mylyn + + + + toolbarSeparator + + + + Draggable + + + + + + + + + + + + + + + toolbarSeparator + + + + Draggable + + + + + + + Draggable + + + + + + Draggable + + + + + + + Draggable + + + + + Draggable + + + + + toolbarSeparator + + + + Draggable + + + + + + + + + + + + toolbarSeparator + + + + toolbarSeparator + + + + Draggable + + + + + stretch + + + glue + + + + glue + + + Draggable + + + + + stretch + + + + Draggable + + + + + TrimStack + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + platform:win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Editor + + + View + categoryTag:Ant + + + View + categoryTag:Data Management + + + View + categoryTag:Data Management + + + View + categoryTag:Data Management + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:General + + + View + categoryTag:Help + + + View + categoryTag:Debug + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java + + + View + categoryTag:General + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:JPA + + + View + categoryTag:JPA + + + View + categoryTag:JavaServer Faces + + + View + categoryTag:JavaServer Faces + + + View + categoryTag:Web Services + + + View + categoryTag:Maven + + + View + categoryTag:Maven + + + View + categoryTag:Mylyn + + + View + categoryTag:Mylyn + + + View + categoryTag:Mylyn + + + View + categoryTag:API Tools + + + View + categoryTag:Plug-in Development + + + View + categoryTag:Plug-in Development + + + View + categoryTag:Plug-in Development + + + View + categoryTag:Plug-in Development + + + View + categoryTag:Plug-in Development + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:Remote Systems + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:CVS + + + View + categoryTag:CVS + + + View + categoryTag:Team + + + View + categoryTag:Team + + + View + categoryTag:Terminal + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:Help + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:Debug + + + View + categoryTag:JavaScript + + + View + categoryTag:JavaScript + + + View + categoryTag:JavaScript + + + View + categoryTag:JavaScript + + + View + categoryTag:JavaScript + + + View + categoryTag:Server + + + View + categoryTag:XML + + + View + categoryTag:XML + + + View + categoryTag:XML + + + View + categoryTag:XML + + + View + categoryTag:XML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat new file mode 100644 index 0000000..3de398e Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml new file mode 100644 index 0000000..6cd9562 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml new file mode 100644 index 0000000..8c365b7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.4.0.20130601-0317.xml b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.4.0.20130601-0317.xml new file mode 100644 index 0000000..e0de515 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.4.0.20130601-0317.xml @@ -0,0 +1,41 @@ + + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + ${org.eclipse.m2e.log.dir}/0.log + + ${org.eclipse.m2e.log.dir}/%i.log + 1 + 10 + + + 100MB + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + WARN + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.rse.core/.log b/.metadata/.plugins/org.eclipse.rse.core/.log new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.rse.core/initializerMarks/org.eclipse.rse.internal.core.RSELocalConnectionInitializer.mark b/.metadata/.plugins/org.eclipse.rse.core/initializerMarks/org.eclipse.rse.internal.core.RSELocalConnectionInitializer.mark new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/FP.local.files_0/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/FP.local.files_0/node.properties new file mode 100644 index 0000000..ea0d336 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/FP.local.files_0/node.properties @@ -0,0 +1,57 @@ +# RSE DOM Node +00-name=lt-dlunanuova\:local.files +01-type=FilterPool +03-attr.default=true +03-attr.deletable=true +03-attr.id=local.files +03-attr.nonRenamable=false +03-attr.owningParentName=null +03-attr.release=200 +03-attr.singleFilterStringOnly=false +03-attr.singleFilterStringOnlyESet=false +03-attr.stringsCaseSensitive=true +03-attr.supportsDuplicateFilterStrings=false +03-attr.supportsNestedFilters=true +03-attr.type=default +06-child.00000.00-name=My Home +06-child.00000.01-type=Filter +06-child.00000.03-attr.default=false +06-child.00000.03-attr.filterType=default +06-child.00000.03-attr.id=My Home +06-child.00000.03-attr.nonChangable=false +06-child.00000.03-attr.nonDeletable=false +06-child.00000.03-attr.nonRenamable=false +06-child.00000.03-attr.promptable=false +06-child.00000.03-attr.relativeOrder=0 +06-child.00000.03-attr.release=200 +06-child.00000.03-attr.singleFilterStringOnly=false +06-child.00000.03-attr.stringsCaseSensitive=false +06-child.00000.03-attr.stringsNonChangable=false +06-child.00000.03-attr.supportsDuplicateFilterStrings=false +06-child.00000.03-attr.supportsNestedFilters=true +06-child.00000.06-child.00000.00-name=C\:\\Users\\dgl\\* +06-child.00000.06-child.00000.01-type=FilterString +06-child.00000.06-child.00000.03-attr.default=false +06-child.00000.06-child.00000.03-attr.string=C\:\\Users\\dgl\\* +06-child.00000.06-child.00000.03-attr.type=default +06-child.00001.00-name=Drives +06-child.00001.01-type=Filter +06-child.00001.03-attr.default=false +06-child.00001.03-attr.filterType=default +06-child.00001.03-attr.id=Drives +06-child.00001.03-attr.nonChangable=false +06-child.00001.03-attr.nonDeletable=false +06-child.00001.03-attr.nonRenamable=false +06-child.00001.03-attr.promptable=false +06-child.00001.03-attr.relativeOrder=0 +06-child.00001.03-attr.release=200 +06-child.00001.03-attr.singleFilterStringOnly=false +06-child.00001.03-attr.stringsCaseSensitive=false +06-child.00001.03-attr.stringsNonChangable=false +06-child.00001.03-attr.supportsDuplicateFilterStrings=false +06-child.00001.03-attr.supportsNestedFilters=true +06-child.00001.06-child.00000.00-name=* +06-child.00001.06-child.00000.01-type=FilterString +06-child.00001.06-child.00000.03-attr.default=false +06-child.00001.06-child.00000.03-attr.string=* +06-child.00001.06-child.00000.03-attr.type=default diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/H.local_16/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/H.local_16/node.properties new file mode 100644 index 0000000..68769c4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/H.local_16/node.properties @@ -0,0 +1,25 @@ +# RSE DOM Node +00-name=Local +01-type=Host +03-attr.description= +03-attr.hostname=LOCALHOST +03-attr.offline=false +03-attr.promptable=false +03-attr.systemType=org.eclipse.rse.systemtype.local +03-attr.type=Local +06-child.00000.00-name=Local Connector Service +06-child.00000.01-type=ConnectorService +06-child.00000.03-attr.group=Local Connector Service +06-child.00000.03-attr.port=0 +06-child.00000.03-attr.useSSL=false +06-child.00000.06-child.00000.00-name=Local Files +06-child.00000.06-child.00000.01-type=SubSystem +06-child.00000.06-child.00000.03-attr.hidden=false +06-child.00000.06-child.00000.03-attr.type=local.files +06-child.00000.06-child.00000.06-child.00000.00-name=lt-dlunanuova___lt-dlunanuova\:local.files +06-child.00000.06-child.00000.06-child.00000.01-type=FilterPoolReference +06-child.00000.06-child.00000.06-child.00000.03-attr.refID=local.files +06-child.00000.06-child.00001.00-name=Local Shells +06-child.00000.06-child.00001.01-type=SubSystem +06-child.00000.06-child.00001.03-attr.hidden=false +06-child.00000.06-child.00001.03-attr.type=local.shells diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/node.properties new file mode 100644 index 0000000..1f1ab79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.lt-dlunanuova_0/node.properties @@ -0,0 +1,7 @@ +# RSE DOM Node +00-name=lt-dlunanuova +01-type=Profile +03-attr.defaultPrivate=true +03-attr.isActive=true +05-ref.00000=FP.local.files_0 +05-ref.00001=H.local_16 diff --git a/.metadata/.plugins/org.eclipse.rse.ui/.log b/.metadata/.plugins/org.eclipse.rse.ui/.log new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml new file mode 100644 index 0000000..855e625 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -0,0 +1,15 @@ + +
+
+ + + + + + + + + + +
+
diff --git a/.metadata/version.ini b/.metadata/version.ini new file mode 100644 index 0000000..c51ff74 --- /dev/null +++ b/.metadata/version.ini @@ -0,0 +1 @@ +org.eclipse.core.runtime=1 \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..7ac3fc1 --- /dev/null +++ b/.project @@ -0,0 +1,36 @@ + + + dcae_dmaapbc + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..591fc05 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM java:openjdk-8-jre +MAINTAINER Dominic Lunanuova +ENV insdir /opt/app/dmaapbc +RUN \ + mkdir -p ${insdir}/lib \ + && mkdir -p ${insdir}/etc \ + && mkdir -p ${insdir}/logs \ + && mkdir -p ${insdir}/www && mkdir -p ${insdir}/www/doc \ + && mkdir -p ${insdir}/config \ + && mkdir -p ${insdir}/misc \ + && mkdir -p ${insdir}/bin +WORKDIR ${insdir} +USER root +COPY target/dcae_dmaapbc.jar ${insdir}/lib/ +COPY target/deps/*.jar ${insdir}/lib/ +COPY src/main/resources/log4j.properties ${insdir}/etc/ +COPY www/ ${insdir}/www/ +COPY target/site/apidocs/ ${insdir}/www/doc/ +COPY misc/LocalKey ${insdir}/etc/ +COPY misc/opensource.env ${insdir}/misc/ +COPY misc/*.tmpl ${insdir}/misc/ +COPY misc/dmaapbc ${insdir}/bin/ +COPY misc/doaction ${insdir}/bin/ + +VOLUME ${insdir}/log +CMD ["./bin/dmaapbc", "deploy" ] diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..06dc301 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END============================================ + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + * + */ diff --git a/README.md b/README.md new file mode 100644 index 0000000..52e6897 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +DMaaP Bus Controller API +======================= + +Data Movement as a Platform (DMaaP) Bus Controller provides an API for other OpenDCAE infrastructure components to provision DMaaP resources. +A typical DMaaP resource is a Data Router Feed or a Message Router Topic, and their associated publishers and subscribers. +Other infrastucture resources such as DR Nodes and MR Clusters are also provisioned through this API. + +### Build Instructions for a Continuous Integration environment using Jenkins + +When this component is included in a Continuous Integration environment, such as structured by the Linux Foundation, the artifacts can be created and deployed via Jenkins. The following maven targets are currently supported in the Build step: +``` +clean install +javadoc:javadoc +sonar:sonar +``` + +In addition, the docker image is deployed during the Post Build step. + +### Build Instructions for external developers + +This project is organized as a mvn project for a jar package. +After cloning from this git repo: + +``` +mvn clean install javadoc:javadoc +``` + + +### Docker Packaging + +We can utilize docker to build and register the dmaapBC container in a local dev repository. +Note the Dockerfile follows OpenECOMP convention of running app as root. + +``` + + +$ docker build -f ./Dockerfile . +``` + + +### OpenECOMP 1701 deployment + +Assumes a DCAE Controller deployment on a Docker host which has access to Rackspace Nexus server, and likely running other OpenECOMP containers. +Prior to starting container, place environment specific vars in /tmp/docker-databus-controller.conf on the Docker host, +and map that file to /opt/app/config/conf. +Run the container with the dmaapbc deploy command, which will update the container runtime properties appropriately. +For example, in IAD1 environment, /tmp/docker-databus-controller.conf looks like: +``` + +# DMaaP Bus Controller OpenSource environment vars +CONT_DOMAIN=dcae.simpledemo.openecomp.org +DMAAPBC_INSTANCE_NAME=iad1 + +# The https port +# set to 0 if certificate is not ready +DMAAPBC_INT_HTTPS_PORT=0 + +DMAAPBC_KSTOREFILE=/opt/app/dcae-certificates +DMAAPBC_KSTOREPASS=foofoofoo +DMAAPBC_PVTKEYPASS=barbarbar + +DMAAPBC_PG_ENABLED=true +DMAAPBC_PGHOST=zldciad1vipstg00.simpledemo.openecomp.org +DMAAPBC_PGCRED=test234-ftl + +DMAAPBC_DRPROV_FQDN=zldciad1vidrps00.simpledemo.openecomp.org + +DMAAPBC_AAF_URL=https://aafapi.${CONT_DOMAIN}:8095/proxy/ + +DMAAPBC_TOPICMGR_USER=m99751@dmaapBC.openecomp.org +DMAAPBC_TOPICMGR_PWD=enc:zyRL9zbI0py3rJAjMS0dFOnYfEw_mJhO +DMAAPBC_ADMIN_USER=m99501@dcae.openecomp.org +DMAAPBC_ADMIN_PWD=enc:YEaHwOJrwhDY8a6usetlhbB9mEjUq9m + +DMAAPBC_PE_ENABLED=false +DMAAPBC_PE_AAF_ENV=TBD +``` +Then the following steps could be used to pull and run the Bus Controller. +``` +$ +$ docker pull ecomp-nexus:51212/dcae_dmaapbc:1.0.0 +$ docker run -d -p 18080:8080 -v /tmp/docker-databus-controller.conf:/opt/app/config/conf ecomp-nexus:51212/dcae_dmaapbc:1.0.0 +``` + diff --git a/RemoteSystemsTempFiles/.project b/RemoteSystemsTempFiles/.project new file mode 100644 index 0000000..7675629 --- /dev/null +++ b/RemoteSystemsTempFiles/.project @@ -0,0 +1,12 @@ + + + RemoteSystemsTempFiles + + + + + + + org.eclipse.rse.ui.remoteSystemsTempNature + + diff --git a/config/README b/config/README new file mode 100644 index 0000000..b0b7482 --- /dev/null +++ b/config/README @@ -0,0 +1,5 @@ +# README +# {projectRoot}/config directory is used to hold files expected of 3rd party libaries +# and those libraries look in config by default. +# this avoids having to find a hook in the library for telling it where to look, assuming it even has such a hook. +# \ No newline at end of file diff --git a/config/policyLogger.properties b/config/policyLogger.properties new file mode 100644 index 0000000..83190e0 --- /dev/null +++ b/config/policyLogger.properties @@ -0,0 +1,24 @@ +################################### Set concurrentHashMap and timer info ####################### +#Timer initial delay and the delay between in milliseconds before task is to be execute. +timer.delay.time=1000 +#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions. +check.interval= 30000 +#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds. +event.expired.time=86400 +#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed +#to remove all expired records from this concurrentHashMap. +concurrentHashMap.limit=5000 +#Size of the concurrentHashMap - when its size drops to this point, stop the Timer +stop.check.point=2500 +################################### Set logging format ############################################# +# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println +logger.type=EELF +#################################### Set level for EELF or SYSTEMOUT logging ################################## +# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all +debugLogger.level=OFF +# Set level for metrics file. Set OFF to disable; set ON to enable +metricsLogger.level=ON +# Set level for error file. Set OFF to disable; set ON to enable +error.level=ON +# Set level for audit file. Set OFF to disable; set ON to enable +audit.level=ON diff --git a/curversion b/curversion new file mode 100644 index 0000000..ca4f70f --- /dev/null +++ b/curversion @@ -0,0 +1,2 @@ +PFX=DMAAPBC1_1_ +VER=0 diff --git a/misc/LocalKey b/misc/LocalKey new file mode 100644 index 0000000..38ede55 --- /dev/null +++ b/misc/LocalKey @@ -0,0 +1,27 @@ +7ntUvubggJ1h6AXwQENQScrnlqmLMno_583XufLsguAT11bnBk0DVLE2GtCZ0pNQzlR8I3PJ1_nZ +UEVQs1G_qZzV-MHQZvz54solEp8dNUVji4JUzP7WiPuJdvCX8vvGLc8-jOVzEJ2DAGmV3gNp60_F +jrKx7F7Dz-h94jWZ45rNn7-Re_BneSto6HiSj0DN_SKSNhE5z9Qf3tFyFLGIYmlQoxzbTYC38uN0 +FjAYuKz6W_pTLzyOjHNAagYwEjTUUU-ei-QA5pL20-oG3jSYGnj_V94kd8X5ncB1-nybUsy5OOvZ +huCxf9hSetn2fpIszkRcuFxaxiwubpmEWp2L_zovhcRI1OMFPIIK0IckRHD1a5CpFVzR7P5L7LQk +FErATsQkHsPS9BJN5wlj1EoIhA2uaELjXjmOqPQg76eyQqXXcMHRJTA6czbXPYfTQMQx1r2USC9o +HdoLT4-so7zARZidmYmvPPT9qvNisK6BF4M32K-_s6YyJspSEB1MscNPujsD7zczIsBct7BTRoeZ +CbtkskT_yFhQzdzdSMzFN_NJ7Yb9p3d1G4gSkj2rbA-BDybHHPij8k6-k-ipvi_T_LW9B_J8Jf5f +aRclZqVgwwSG-mUKUyk9bI3cVc-1P2ICUmr59EjuauDAtlMQL-hnTJUs1rUerh4Q7d4XgrNLjLHY +Oue8MEj24VSMl-f28DDIV1N6ODiBKDHUmdENsmlbqeNpzQxu7FoSbLu6gN6zDP8Jw4ck1NHEIv8H +ecUf-hBGdB0HINClaV9X2ycafWcmRY-NCzX65cp7a1Rpl1kCEW5u79LLN28aJeTzmriewhy87hJf +rAah8z3dHteIN1fuvRoGsFwZ4jKo6olFxcBOlpHQIW5JJ1roO1vQ2Dx_l-Foo7wV_AD127zCu7ci +lYodnAOocKbhAub4sf90P3D2NMKb20e5CQrBSchtIEaD3G7J-vL5xYydLuLu5WipOdZuq3VhSSZm +TZIR3Ya2QiZVokxKgH-N0gPDz-TimNV_MkUSCNsv2NxjBM7oPF3dzEHbHS5eue41_R4vqxFdTdva +o0ASTFkARmmnMFBx1a73jmcoBBx-i4el8Rce7RvFWn1PALOnRsIQPy_Pgx0OE9_6eHfOSvyxbyMM +0FwE5f77gO967tgc4LwqB1pzz2Uk7hfizLKNc6nrrgDxSb_9rDWwiE4rWw7WYcRKvRQ270lCH4FQ +ezrPacnnK3cKM5L6brOyhbhiL4MnNX714L0K8C6TQnIVisQCLHwif40G_DSEWxICQ5V2DMzFn3JT +PefaubHlqxRZVikNH71b_2ZRLEi84m5iUuy8Ir1s3W6xuyIdt-yKLnjgnLjOPPxTDC5G_xaXAAuM +SkSOjvPzOArMUUnwYk68jAxXS2tBT8JN6OnglN8dHC-P24tYzfs4B4tMYJ1ibz6BUsQ6nYxsRUak +4ZjRmo3UG0OFJbOY-f0ja6Q4pISe1IXmlM4Ly9QdCfeHyDV-7Fiud9V_zo92lpQwttwSpBvFoDYQ +oePdA0zmCx6GIX_8L9e8a03hUx4aUtZ8C3Kf0PzOWTcjrV7nGb99ctjmRtfGw5GPWudH6CI3WFK2 +5wFDhrQSbRhzV4iQalYVPJQ7LO4WEi4EsBTRSiz074UpvkMV3UfMGDlpXAAq5rEjj-d5WbHhzbs8 +MGKzZLTfUz9lP4CME9AOwto_ey1ly3H-yaEgCpnshm-CZoSqVDmuFYM0QR_NcrqmSQ9ZKJEF_wTa +TEAXNJ99CYE0ZLvU9FjgCqH1-q1zL7z3NLX1uFYazEZWGMZFPVD5XOcCtUlVyUz9KuAO9ARVyu5C +7kzo_AFePtnsA_JUvvkauo6RwO6qhLJjZuSjvmiSdOAohiXUalDFjWVW8CMfgLF4PbRDklsAcsiT +P0xUdyWJ5slu87f9PunXDwQZWNv6haTIhVX7bilCDpRPbTbmimmE_C2J7tgV2EvazD7o8V_jeu0g +cnIpzRnaPG9l-uy2UKoxOXI4CSymcJoyV2xxC0SF7Q5quAhf3UGAdQUeFtHwxZtYiAMXLs06 \ No newline at end of file diff --git a/misc/PolicyEngineApi.properties.tmpl b/misc/PolicyEngineApi.properties.tmpl new file mode 100644 index 0000000..0e72d3f --- /dev/null +++ b/misc/PolicyEngineApi.properties.tmpl @@ -0,0 +1,14 @@ +cat < etc/dmaapbc.properties + . misc/PolicyEngineApi.properties.tmpl > config/PolicyEngineApi.properties + set +x +} + +start() { + set -x + ID=`id -n -u` + GRP=`id -n -g` + if [ "$ID" != "$USER" ] + then + echo $COMPONENT must be started as user $USER not $ID + exit 1 + fi + if [ "$GRP" != "$USER" ] + then + echo $COMPONENT must be started as group $USER not $GRP + exit 1 + fi + cd $APP_ROOT + +# disable until we use certs +# if etc/havecert +# then + echo >/dev/null +# else +# echo No certificate file available. Cannot start +# exit 0 +# fi + PIDS=`pids` + if [ "$PIDS" != "" ] + then + echo $COMPONENT already running + exit 0 + fi + rm -f $APP_ROOT/etc/SHUTDOWN + + # JVM flags +#old line from Dockerfile...keep for reference only + FLAGS="-cp etc:lib/* -Dlog4j.configuration=etc/log4j.properties -Ddmaapbc.properties=etc/dmaapbc.properties -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + nohup java $FLAGS $MAIN /dev/null 2>&1 & + sleep 5 + PIDS=`pids` + if [ "$PIDS" = "" ] + then + echo $COMPONENT startup failed + tail -100 $APP_ROOT/logs/dmaap*.log + else + echo $COMPONENT started + fi + set +x +} + +stop() { + ID=`id -n -u` + GRP=`id -n -g` + if [ "$ID" != "$USER" ] + then + echo $COMPONENT must be stopped as user $USER not $ID + exit 1 + fi + if [ "$GRP" != "$USER" ] + then + echo $COMPONENT must be stopped as group $USER not $GRP + exit 1 + fi + touch $APP_ROOT/etc/SHUTDOWN + PIDS=`pids` + if [ "$PIDS" != "" ] + then + sleep 5 + kill -9 $PIDS + sleep 5 + echo $COMPONENT stopped + else + echo $COMPONENT not running + fi +} + +status() { + PIDS=`pids` + if [ "$PIDS" != "" ] + then + echo $COMPONENT running + else + echo $COMPONENT not running + fi +} + +case "$1" in +'deploy') + config + start + wait + ;; +'start') + start + ;; +'stop') + stop + ;; +'restart') + stop + sleep 20 + start + ;; +'status') + status + ;; +*) + echo "Usage: $0 { start | stop | restart }" + exit 1 + ;; +esac +exit 0 diff --git a/misc/dmaapbc.properties.tmpl b/misc/dmaapbc.properties.tmpl new file mode 100755 index 0000000..7dfeefa --- /dev/null +++ b/misc/dmaapbc.properties.tmpl @@ -0,0 +1,152 @@ +cat </dev/null + cp dmaapbc.properties dmaapbc.properties.save 2>/dev/null + cp havecert havecert.save 2>/dev/null + ;; +'stop') + /opt/app/platform/init.d/dmaapbc stop + ;; +'start') + /opt/app/platform/init.d/dmaapbc start || exit 1 + ;; +'config') + /bin/bash log4j.properties.tmpl >log4j.properties + /bin/bash dmaapbc.properties.tmpl >dmaapbc.properties + /bin/bash havecert.tmpl >havecert + /bin/bash PolicyEngineApi.properties.tmpl > ../config/PolicyEngineApi.properties + echo "$AFTSWM_ACTION_NEW_VERSION" >VERSION.dmaapbc + chmod +x havecert + rm -f /opt/app/platform/rc.d/K90dmaapbc /opt/app/platform/rc.d/S10dmaapbc + ln -s ../init.d/dmaapbc /opt/app/platform/rc.d/K90dmaapbc + ln -s ../init.d/dmaapbc /opt/app/platform/rc.d/S10dmaapbc + ;; +'restore') + cp log4j.properties.save log4j.properties 2>/dev/null + cp dmaapbc.properties.save dmaapbc.properties 2>/dev/null + cp havecert.save havecert 2>/dev/null + ;; +'clean') + rm -f log4j.properties dmaapbc.properties havecert log4j.properties.save dmaapbc.properties.save havecert.save SHUTDOWN redirections.dat VERSION.dmaapbc + rm -f /opt/app/platform/rc.d/K90dmaapbc /opt/app/platform/rc.d/S10dmaapbc + ;; +*) + exit 1 + ;; +esac +done +exit 0 diff --git a/misc/havecert.tmpl b/misc/havecert.tmpl new file mode 100644 index 0000000..00a0a34 --- /dev/null +++ b/misc/havecert.tmpl @@ -0,0 +1,11 @@ +#!/bin/bash +cat <>${DMAAPBC_LOGS:-logs}/dmaapbc.log +exit 1 +!EOF diff --git a/misc/log4j.properties.tmpl b/misc/log4j.properties.tmpl new file mode 100755 index 0000000..c896723 --- /dev/null +++ b/misc/log4j.properties.tmpl @@ -0,0 +1,11 @@ +cat < + + 4.0.0 + + org.openecomp.dcae.dmaapbc + dcae_dmaapbc + 1.0.0 + dcae_dmaapbc + + + + osecomp-nexus-releases + OSECOMP Release Repository + https://162.242.254.138:8443/repository/maven-releases + + + osecomp-nexus-snapshots + OSECOMP Snapshot Repository + https://162.242.254.138:8443/repository/maven-snapshots + + + mso-javadoc + dav:https://ecomp-nexus:8443/repository/mso-javadoc/org.openecomp.dmaapbc/${project.version} + + + + + + osecomp-nexus + OSECOMP Repository + https://162.242.254.138:8443/maven-central + + + + dcae_dmaapbc + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + true + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/deps + false + false + true + + + + + + + com.blackducksoftware.integration + hub-maven-plugin + 1.0.4 + false + + ${project.basedir} + + + + create-bdio-file + package + + createHubOutput + + + + + + + org.codehaus.mojo + license-maven-plugin + 1.10 + + false + ============LICENSE_START======================================================= + ============LICENSE_END========================================================= + ================================================================================ + apache_v2 + 2017 + AT&T Intellectual Property. All rights reserved. + OpenECOMP - org.openecomp.dmaapbc + true + true + true + true + + + + first + + update-file-header + + process-sources + + + + + org.codehaus.mojo + sonar-maven-plugin + 3.2 + + + org.apache.maven.plugins + maven-site-plugin + 3.6 + + + org.apache.maven.wagon + wagon-webdav-jackrabbit + 2.10 + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.maven.plugins + + + maven-dependency-plugin + + + [2.10,) + + + + copy-dependencies + + + + + + + + + + + + + + + + + + + org.glassfish.jersey + jersey-bom + ${jersey.version} + pom + import + + + + + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + + + org.glassfish.jersey.media + jersey-media-moxy + + + log4j + log4j + 1.2.17 + + + org.eclipse.jetty + jetty-server + ${jettyVersion} + + + org.eclipse.jetty + jetty-servlet + ${jettyVersion} + compile + + + org.eclipse.jetty + jetty-servlets + ${jettyVersion} + compile + + + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + + commons-codec + commons-codec + 1.6 + + + + org.postgresql + postgresql + 9.4.1208.jre7 + + + + + + + + osecomp-nexus + OSECOMP Repository + https://162.242.254.138:8443/maven-central + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + false + org.umlgraph.doclet.UmlGraphDoc + + org.umlgraph + umlgraph + 5.6 + + -views + true + + + + + + 2.16 + UTF-8 + 9.0.2.v20130417 + + Data Movement as a Platform (DMaaP) Bus Controller provides an API for other DCAE infrastructure components to provision DMaaP resources. A DMaaP resource is a Data Router Feed or a Message Router Topic, and their associated publishers and subscribers. + diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/AafConnection.java b/src/main/java/org/openecomp/dmaapbc/aaf/AafConnection.java new file mode 100644 index 0000000..421e948 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/AafConnection.java @@ -0,0 +1,194 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + + + + + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ProtocolException; +import java.net.URL; +import java.net.UnknownHostException; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLHandshakeException; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.service.DmaapService; + + +public class AafConnection { + + static final Logger logger = Logger.getLogger(AafConnection.class); + + + private String dmaapName; + private String aafCred; + + + private HttpsURLConnection uc; + + + public AafConnection( String cred ) { + dmaapName = new DmaapService().getDmaap().getDmaapName(); + if ( dmaapName.length() < 1 ) { + logger.fatal( "Attempting to access AAF before dmaap object is set"); + } + aafCred = cred; + } + + + private boolean makeConnection( String pURL ) { + + try { + URL u = new URL( pURL ); + uc = (HttpsURLConnection) u.openConnection(); + uc.setInstanceFollowRedirects(false); + logger.info( "successful connect to " + pURL ); + return(true); + } catch (Exception e) { + logger.error("Unexpected error during openConnection of " + pURL ); + e.printStackTrace(); + return(false); + } + + } + + static String bodyToString( InputStream is ) { + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader( new InputStreamReader(is)); + String line; + try { + while ((line = br.readLine()) != null ) { + sb.append( line ); + } + } catch (IOException ex ) { + logger.error( "IOexception:" + ex); + } + + return sb.toString(); + } + + + + public int postAaf( AafObject obj, String pURL ) { + + String auth = "Basic " + Base64.encodeBase64String(aafCred.getBytes()); + int rc = -1; + // TODO Auto-generated method stub + logger.info( "entry: setPerm() " ); + + if ( ! makeConnection( pURL ) ) { + return rc; + }; + + + byte[] postData = obj.getBytes(); + //logger.info( "post fields=" + postData ); //byte isn't very readable + String responsemessage = null; + String responseBody = null; + + try { + if (auth != null) { + uc.setRequestProperty("Authorization", auth); + } + uc.setRequestMethod("POST"); + uc.setRequestProperty("Content-Type", "application/json"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } catch ( SSLHandshakeException she ) { + logger.error( "SSLHandshakeException from AAF URL " + pURL); + } catch ( UnknownHostException uhe ) { + logger.error( "UnknownHostException from AAF for URL " + pURL ); + rc = 500; + return rc; + } + try { + rc = uc.getResponseCode(); + } catch ( SSLHandshakeException she ) { + logger.error( "SSLHandshakeException from AAF URL " + pURL); + rc = 500; + return rc; + } + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if ( rc >= 200 && rc < 300 ) { + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + } else { + logger.warn( "Unsuccessful response: " + responsemessage ); + } + + } catch (Exception e) { + System.err.println("Unable to read response " ); + e.printStackTrace(); + } + finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + //return responseBody; + + return rc; + + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/AafObject.java b/src/main/java/org/openecomp/dmaapbc/aaf/AafObject.java new file mode 100644 index 0000000..f674fa0 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/AafObject.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + +import java.nio.charset.StandardCharsets; + +public abstract class AafObject { + + abstract String toJSON(); + + public byte[] getBytes() { + return toJSON().getBytes(StandardCharsets.UTF_8); + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/AafService.java b/src/main/java/org/openecomp/dmaapbc/aaf/AafService.java new file mode 100644 index 0000000..4de41e3 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/AafService.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + +import java.io.IOException; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.util.DmaapConfig; + +public class AafService { + public enum ServiceType { + AAF_Admin, + AAF_TopicMgr + } + static final Logger logger = Logger.getLogger(AafService.class); + + private AafConnection aaf; + private ServiceType ctype; + private String aafURL ; + + private String getCred( boolean wPwd ) { + String mechIdProperty = null; + String pwdProperty = null; + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + + if ( ctype == ServiceType.AAF_Admin ) { + mechIdProperty = "aaf.AdminUser"; + pwdProperty = "aaf.AdminPassword"; + } else if ( ctype == ServiceType.AAF_TopicMgr ){ + mechIdProperty = "aaf.TopicMgrUser"; + pwdProperty = "aaf.TopicMgrPassword"; + } else { + logger.error( "Unexpected case for AAF credential type: " + ctype ); + return null; + } + String user = p.getProperty( mechIdProperty, "noMechId@domain.netset.com" ); + String pwd = AndrewDecryptor.valueOf(p.getProperty( pwdProperty, "notSet" )); + + if ( wPwd ) { + return user + ":" + pwd; + } else { + return user; + } + + + } + + public AafService(ServiceType t ) { + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + aafURL = p.getProperty( "aaf.URL", "https://authentication.domain.netset.com:8095/proxy/"); + ctype = t; + aaf = new AafConnection( getCred( true ) ); + } + + public int addPerm(DmaapPerm perm) { + + int rc = -1; + logger.info( "entry: setPerm() " ); + String pURL = aafURL + "authz/perm"; + rc = aaf.postAaf( perm, pURL ); + switch( rc ) { + case 401: + logger.fatal( "Service credentials (" + getCred( false ) + ") are not valid for AAF connection"); + break; + case 403: + logger.fatal( "Service credentials (" + getCred( false ) + ") are not authorized for requested action"); + break; + + case 409: + logger.warn( "Perm already exists. Possible conflict."); + break; + + case 201: + logger.info( "expected response" ); + break; + default : + logger.error( "Unexpected response: " + rc ); + break; + } + + return rc; + } + public int addGrant(DmaapGrant grant ) { + + int rc = -1; + logger.info( "entry: setPerm() " ); + + String pURL = aafURL + "authz/role/perm"; + rc = aaf.postAaf( grant, pURL ); + switch( rc ) { + case 401: + logger.fatal( "Service credentials (" + getCred( false ) + ") are not valid for AAF connection"); + break; + case 403: + logger.fatal( "Service credentials (" + getCred( false ) + ") are not authorized for requested action"); + break; + + case 409: + logger.warn( "Perm already exists. Possible conflict."); + break; + + case 201: + logger.info( "expected response" ); + break; + default : + logger.error( "Unexpected response: " + rc ); + break; + } + + return rc; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/AndrewDecryptor.java b/src/main/java/org/openecomp/dmaapbc/aaf/AndrewDecryptor.java new file mode 100644 index 0000000..a4f6d9d --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/AndrewDecryptor.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + +import java.io.*; + +import org.openecomp.dmaapbc.util.DmaapConfig; + +// Commented out this package and the code that uses it until it becomes available. + +//import com.xxx.cadi.*; + +public class AndrewDecryptor { + private static AndrewDecryptor instance; + //private Symm symm; + + private AndrewDecryptor() { + InputStream is = null; + try { + is = new FileInputStream(DmaapConfig.getConfig().getProperty("CredentialCodecKeyfile", "LocalKey")); + //symm = Symm.obtain(is); + } catch (Exception e) { + } finally { + try { + if (is != null) { + is.close(); + } + } catch (Exception x) { + + } + } + } + public String decrypt(String enc) throws IOException { + return(enc); + //return((enc != null && enc.startsWith(Symm.ENC))? symm.depass(enc): enc); + } + public static AndrewDecryptor getInstance() { + if (instance == null) { + instance = new AndrewDecryptor(); + } + return(instance); + } + public static String valueOf(String enc) { + try { + return(getInstance().decrypt(enc)); + } catch (Exception e) { + return(null); + } + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/DmaapGrant.java b/src/main/java/org/openecomp/dmaapbc/aaf/DmaapGrant.java new file mode 100644 index 0000000..743dd83 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/DmaapGrant.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + +import org.apache.log4j.Logger; + +public class DmaapGrant extends AafObject { + static final Logger logger = Logger.getLogger(DmaapGrant.class); + + private DmaapPerm perm; + private String role; + + public DmaapGrant(){ + + } + + public DmaapGrant( DmaapPerm p, String r ) { + this.perm = p; + this.role = r; + } + + public DmaapPerm getPerm() { + return perm; + } + + public void setPerm(DmaapPerm perm) { + this.perm = perm; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String toJSON() { + + String postJSON = String.format(" { \"perm\": %s, \"role\": \"%s\"}", + this.perm.toJSON(), + this.getRole() ); + logger.info( "returning JSON: " + postJSON); + + return postJSON; + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/aaf/DmaapPerm.java b/src/main/java/org/openecomp/dmaapbc/aaf/DmaapPerm.java new file mode 100644 index 0000000..d53c270 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/aaf/DmaapPerm.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.aaf; + +import org.apache.log4j.Logger; + + +public class DmaapPerm extends AafObject { + static final Logger logger = Logger.getLogger(DmaapPerm.class); + + private String permission; + private String ptype; + private String action; + + public DmaapPerm(String permission, String ptype, String action) { + super(); + this.permission = permission; + this.ptype = ptype; + this.action = action; + } + public String getPermission() { + return permission; + } + public void setPermission(String permission) { + this.permission = permission; + } + public String getPtype() { + return ptype; + } + public void setPtype(String ptype) { + this.ptype = ptype; + } + public String getAction() { + return action; + } + public void setAction(String action) { + this.action = action; + } + public String toJSON() { + + String postJSON = String.format(" { \"type\": \"%s\", \"instance\": \"%s\", \"action\": \"%s\"}", + this.getPermission(), + this.getPtype(), + this.getAction() ); + logger.info( "returning JSON: " + postJSON); + + return postJSON; + } + + + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/authentication/AuthenticationErrorException.java b/src/main/java/org/openecomp/dmaapbc/authentication/AuthenticationErrorException.java new file mode 100644 index 0000000..cce010c --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/authentication/AuthenticationErrorException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.authentication; + +public class AuthenticationErrorException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/org/openecomp/dmaapbc/authentication/DecisionPolicy.java b/src/main/java/org/openecomp/dmaapbc/authentication/DecisionPolicy.java new file mode 100644 index 0000000..4384c56 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/authentication/DecisionPolicy.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.authentication; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + + + + + + + + + + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.aaf.DmaapPerm; +import org.openecomp.dmaapbc.util.DmaapConfig; + +/* disable until available... +import org.openecomp.policy.api.DecisionRequestParameters; +import org.openecomp.policy.api.PolicyDecision; +import org.openecomp.policy.api.DecisionResponse; +import org.openecomp.policy.api.PolicyDecisionException; +import org.openecomp.policy.api.PolicyEngine; +import org.openecomp.policy.api.PolicyEngineException; +*/ + +public class DecisionPolicy { + static final Logger logger = Logger.getLogger(DecisionPolicy.class); + //PolicyEngine policyEngine = null; + String aafEnvironment; + + public DecisionPolicy() { + logger.info("Constructing DecisionPolicy using property"); + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + String config = p.getProperty("PolicyEngineProperties", "etc/PolicyEngineApi.properties"); + aafEnvironment = p.getProperty("PeAafEnvironment", "PROD"); // TEST= UAT, PROD = PROD, DEVL = TEST + logger.info( "Initializing DecisionPolicy for env " + aafEnvironment + " using " + config); + this.init( config ); + } + public DecisionPolicy( String config ) { + logger.info("Constructing DecisionPolicy using arg " + config ); + this.init( config ); + } + + public void init( String config ) { + logger.info( "stubbed out PolicyEngine()" ); +/* + try { + policyEngine = new PolicyEngine( config ); + } catch (PolicyEngineException e) { + logger.error( "Trying to read " + config + " and caught PolicyEngineException" + e ); + } +*/ + } + public void check( String mechid, String pwd, DmaapPerm p ) throws AuthenticationErrorException { + logger.debug( mechid + " Permitted to do action " + p.getPermission() + "|" + p.getPtype() + "|" + p.getAction()); + +/* + // Create a Decision Policy Request. + DecisionRequestParameters decisionRequestParameters = new DecisionRequestParameters(); + decisionRequestParameters.setECOMPComponentName("DMaaP"); // Required ECOMP Name + decisionRequestParameters.setRequestID(UUID.randomUUID()); // Optional UUID Request + // Put all the required Attributes into Decision Attributes. + + HashMap decisionAttributes = new HashMap(); + decisionAttributes.put("AAF_ID", mechid); // Fully qualified ID. + decisionAttributes.put("AAF_PASS", pwd); + decisionAttributes.put("AAF_TYPE", p.getPermission()); + decisionAttributes.put("AAF_INSTANCE", p.getPtype()); + decisionAttributes.put("AAF_ACTION", p.getAction()); + decisionAttributes.put("AAF_ENVIRONMENT", aafEnvironment); // TEST= UAT, PROD = PROD, DEVL = TEST + decisionRequestParameters.setDecisionAttributes(decisionAttributes); + // Send the request to Policy Engine and that returns a PolicyDecision Object. + try { + DecisionResponse response = policyEngine.getDecision(decisionRequestParameters); + if(response.getDecision().equals(PolicyDecision.PERMIT)){ + logger.debug( mechid + " Permitted to do action " + p.getPermission() + "|" + p.getPtype() + "|" + p.getAction()); + }else{ + logger.debug( mechid + " NOT Permited to do action "+ p.getPermission() + "|" + p.getPtype() + "|" + p.getAction()); + logger.debug(response.getDetails()); + throw new AuthenticationErrorException(); + } + } catch (PolicyDecisionException e) { + System.err.println(e); + logger.error(e); + throw new AuthenticationErrorException(); + } +*/ + + + + } + +/* + public static void main(String args[]){ + DecisionPolicy d = new DecisionPolicy(); + d.test(); + } + + public void test() { + + // TODO: pass in users and pwd from cmd line + String[] ids = {"user1@namespace1", + "user2@namespace2"}; + String[] pwds = { + "pwd1", + "pwd2" + }; + List perms = new ArrayList(); + + + perms.add( new DmaapPerm("org.openecomp.dmaapBC.dmaap", "mtnje2", "POST")); + perms.add( new DmaapPerm("org.openecomp.dmaapBC.dcaeLocations", "mtnje2", "POST")); + perms.add( new DmaapPerm("org.openecomp.dmaapBC.dmaap", "mtnje2", "GET")); + perms.add( new DmaapPerm("org.openecomp.dmaapBC.dmaap", "mtnje2", "PUT")); + perms.add( new DmaapPerm("org.openecomp.dmaapBC.dmaap", "mtnje2", "DELETE")); + + + + for( DmaapPerm p : perms ) { + for( int i = 0; i < ids.length; i++) { + try { + this.check( ids[i], pwds[i], p); + System.out.println( "PERMIT! for "+ ids[i] + " " + p.getPermission() + "|" + p.getPtype() + "|" + p.getAction()); + } catch ( AuthenticationErrorException aee ) { + System.out.println( "FAILED! for "+ ids[i] + " " + p.getPermission() + "|" + p.getPtype() + "|" + p.getAction()); + } + } + } + + } +*/ + +} diff --git a/src/main/java/org/openecomp/dmaapbc/client/DrProvConnection.java b/src/main/java/org/openecomp/dmaapbc/client/DrProvConnection.java new file mode 100644 index 0000000..e4fe3cc --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/client/DrProvConnection.java @@ -0,0 +1,453 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ConnectException; +import java.net.ProtocolException; +import java.net.SocketException; +import java.net.URL; +import java.util.ArrayList; + +import javax.net.ssl.HttpsURLConnection; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.DR_Sub; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.service.DmaapService; +import org.openecomp.dmaapbc.util.RandomInteger; + + + +public class DrProvConnection { + static final Logger logger = Logger.getLogger(DrProvConnection.class); + + + private String provURL; + + private HttpsURLConnection uc; + + + public DrProvConnection() { + provURL = new DmaapService().getDmaap().getDrProvUrl(); + if ( provURL.length() < 1 ) { + logger.error( "Attempting to access PROV before dmaap object is set"); + } + + } + + public boolean makeFeedConnection() { + return makeConnection( provURL ); + } + public boolean makeFeedConnection(String feedId) { + return makeConnection( provURL + "/feed/" + feedId ); + } + public boolean makeSubConnection( String subURL ) { + String[] parts = subURL.split("/"); + String revisedURL = provURL + "/" + parts[3] + "/" + parts[4]; + logger.info( "mapping " + subURL + " to " + revisedURL ); + return makeConnection( revisedURL ); + } + public boolean makeIngressConnection( String feed, String user, String subnet, String nodep ) { + String uri = String.format("/internal/route/ingress/?feed=%s&user=%s&subnet=%s&nodepatt=%s", + feed, user, subnet, nodep ); + return makeConnection( provURL + uri ); + } + + private boolean makeConnection( String pURL ) { + + try { + URL u = new URL( pURL ); + uc = (HttpsURLConnection) u.openConnection(); + uc.setInstanceFollowRedirects(false); + logger.info( "successful connect to " + pURL ); + return(true); + } catch (Exception e) { + logger.error("Unexpected error during openConnection of " + pURL ); + e.printStackTrace(); + return(false); + } + + } + + private String bodyToString( InputStream is ) { + logger.info( "is=" + is ); + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader( new InputStreamReader(is)); + String line; + try { + while ((line = br.readLine()) != null ) { + sb.append( line ); + } + } catch (IOException ex ) { + logger.error( "IOexception:" + ex); + } + + return sb.toString(); + } + + + public String doPostFeed( Feed postFeed, ApiError err ) { + + byte[] postData = postFeed.getBytes(); + logger.info( "post fields=" + postData.toString() ); + String responsemessage = null; + String responseBody = null; + + try { + logger.info( "uc=" + uc ); + uc.setRequestMethod("POST"); + uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", postFeed.getOwner() ); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + int rc = -1; + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if (rc == 201 ) { + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + + } else { + err.setCode( rc ); + err.setMessage(responsemessage); + } + + } catch (ConnectException ce) { + logger.error("Connection refused " ); + err.setCode( 500 ); + err.setMessage("Backend connection refused"); + } catch (SocketException se) { + logger.error( "Socket exception: unexpected end of file from server" ); + err.setCode( 500 ); + err.setMessage( "Unable to read response from DR"); + } catch (Exception e) { + logger.warn("Unable to read response " ); + e.printStackTrace(); + try { + err.setCode( uc.getResponseCode()); + err.setMessage(uc.getResponseMessage()); + } catch (Exception e2) { + err.setCode( 500 ); + err.setMessage("Unable to determine response message"); + } + } + finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + return responseBody; + + } + + + // the POST for /internal/route/ingress doesn't return any data, so needs a different function + public int doIngressPost( ApiError err ) { + + String responsemessage = null; + int rc = -1; + + try { + uc.setRequestMethod("POST"); +// uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed"); +// uc.setRequestProperty( "charset", "utf-8"); +// uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", postFeed.getOwner() ); +// uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); +// uc.setUseCaches(false); +// uc.setDoOutput(true); + OutputStream os = null; + + + try { + uc.connect(); + os = uc.getOutputStream(); + + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + + if (rc < 200 || rc >= 300 ) { + err.setCode( rc ); + err.setMessage(responsemessage); + } + } catch (Exception e) { + System.err.println("Unable to read response " ); + e.printStackTrace(); + } finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + + return rc; + + } + + public String doPostDr_Sub( DR_Sub postSub ) { + logger.info( "entry: doPostDr_Sub() " ); + byte[] postData = postSub.getBytes(); + logger.info( "post fields=" + postData ); + String responsemessage = null; + String responseBody = null; + + try { + + uc.setRequestMethod("POST"); + + uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" ); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + int rc = -1; + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if (rc == 201 ) { + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + + } + + } catch (Exception e) { + System.err.println("Unable to read response " ); + e.printStackTrace(); + } finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + return responseBody; + + } + + public static void main( String[] args ) throws Exception { + PropertyConfigurator.configure("log4j.properties"); + logger.info("Started."); + + RandomInteger ri = new RandomInteger(10000); + //String postJSON = String.format("{\"name\": \"dgl feed %d\", \"version\": \"v1.0\", \"description\": \"dgl feed N for testing\", \"authorization\": { \"classification\": \"unclassified\", \"endpoint_addrs\": [],\"endpoint_ids\": [{\"password\": \"test\",\"id\": \"test\"}]}}", ri.next()) ; + int i = ri.next(); + Feed tst = new Feed( "dgl feed " + i, + "v1.0", + "dgl feed " + i + "for testing", + "TEST", + "unclassified" + ); + ArrayList pubs = new ArrayList(); + pubs.add( new DR_Pub( "centralLocation" ) ); + tst.setPubs(pubs); + + boolean rc; + DrProvConnection context = new DrProvConnection(); + rc = context.makeFeedConnection(); + logger.info( "makeFeedConnection returns " + rc); + ApiError err = new ApiError(); + if ( rc ) { + String tmp = context.doPostFeed( tst, err ); + logger.info( "doPostFeed returns " + tmp); + } + + + } + + public String doPutFeed(Feed putFeed, ApiError err) { + byte[] postData = putFeed.getBytes(); + logger.info( "post fields=" + postData.toString() ); + String responsemessage = null; + String responseBody = null; + + try { + logger.info( "uc=" + uc ); + uc.setRequestMethod("PUT"); + uc.setRequestProperty("Content-Type", "application/vnd.att-dr.feed"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", putFeed.getOwner() ); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + int rc = -1; + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if (rc >= 200 && rc < 300 ) { + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + + } else if ( rc == 404 ) { + err.setCode( rc ); + err.setFields( "feedid"); + String message = "FeedId " + putFeed.getFeedId() + " not found on DR to update. Out-of-sync condition?"; + err.setMessage( message ); + logger.warn(message); + + } else { + err.setCode( rc ); + err.setMessage(responsemessage); + } + + } catch (ConnectException ce) { + logger.error("Connection refused " ); + err.setCode( 500 ); + err.setMessage("Backend connection refused"); + } catch (SocketException se) { + logger.error( "Socket exception: unexpected end of file from server" ); + err.setCode( 500 ); + err.setMessage( "Unable to read response from DR"); + } catch (Exception e) { + logger.warn("Unable to read response " ); + e.printStackTrace(); + try { + err.setCode( uc.getResponseCode()); + err.setMessage(uc.getResponseMessage()); + } catch (Exception e2) { + err.setCode( 500 ); + err.setMessage("Unable to determine response message"); + } + } finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + return responseBody; + } + + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/client/MrProvConnection.java b/src/main/java/org/openecomp/dmaapbc/client/MrProvConnection.java new file mode 100644 index 0000000..420c315 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/client/MrProvConnection.java @@ -0,0 +1,187 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ConnectException; +import java.net.ProtocolException; +import java.net.URL; +import java.net.UnknownHostException; +import javax.net.ssl.HttpsURLConnection; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.util.DmaapConfig; + +public class MrProvConnection { + static final Logger logger = Logger.getLogger(MrProvConnection.class); + + + private String provURL; + + private HttpsURLConnection uc; + + + private String topicMgrCred; + + + + public MrProvConnection() { + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + topicMgrCred = p.getProperty("aaf.TopicMgrUser", "noIdSet") + ":" + p.getProperty("aaf.TopicMgrPassword", "noPwdSet" ); + + } + + public boolean makeTopicConnection( MR_Cluster cluster ) { + logger.info( "connect to cluster: " + cluster.getDcaeLocationName()); + + + provURL = cluster.getTopicProtocol() + "://" + cluster.getFqdn() + ":" + cluster.getTopicPort() + "/topics/create"; + + return makeConnection( provURL ); + } + + private boolean makeConnection( String pURL ) { + logger.info( "makeConnection to " + pURL ); + + try { + URL u = new URL( pURL ); + uc = (HttpsURLConnection) u.openConnection(); + uc.setInstanceFollowRedirects(false); + logger.info( "successful connect to " + pURL ); + return(true); + } catch( UnknownHostException uhe ){ + logger.error( "Caught UnknownHostException for " + pURL); + return(false); + } catch (Exception e) { + logger.error("Unexpected error during openConnection of " + pURL ); + e.printStackTrace(); + return(false); + } + + } + + static String bodyToString( InputStream is ) { + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader( new InputStreamReader(is)); + String line; + try { + while ((line = br.readLine()) != null ) { + sb.append( line ); + } + } catch (IOException ex ) { + logger.error( "IOexception:" + ex); + } + + return sb.toString(); + } + + public String doPostTopic( Topic postTopic ) { + String auth = "Basic " + Base64.encodeBase64String(topicMgrCred.getBytes()); + + + String responsemessage = null; + int rc = -1; + + + try { + byte[] postData = postTopic.getBytes(); + logger.info( "post fields=" + postData.toString() ); + uc.setRequestProperty("Authorization", auth); + logger.info( "Authenticating with " + auth ); + uc.setRequestMethod("POST"); + uc.setRequestProperty("Content-Type", "application/json"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } catch ( UnknownHostException uhe ) { + logger.error( "UnknownHostException: " + uhe.getMessage() ); + return new String( "500: " + uhe.getMessage()); + }catch ( ConnectException ce ) { + logger.error( "ConnectException: " + ce.getMessage() ); + return new String( "500: " + ce.getMessage()); + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if (rc >= 200 && rc < 300 ) { + String responseBody = null; + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + return responseBody; + + } + + } catch (Exception e) { + System.err.println("Unable to read response " ); + e.printStackTrace(); + } + finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + return new String( rc +": " + responsemessage ); + + } + + + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/client/MrTopicConnection.java b/src/main/java/org/openecomp/dmaapbc/client/MrTopicConnection.java new file mode 100644 index 0000000..1ab2431 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/client/MrTopicConnection.java @@ -0,0 +1,168 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ProtocolException; +import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.MR_Cluster; + +public class MrTopicConnection { + static final Logger logger = Logger.getLogger(MrTopicConnection.class); + private String topicURL; + + private HttpsURLConnection uc; + + + private String mmProvCred; + + + + public MrTopicConnection(String user, String pwd ) { + mmProvCred = new String( user + ":" + pwd ); + + } + + public boolean makeTopicConnection( MR_Cluster cluster, String topic ) { + logger.info( "connect to cluster: " + cluster.getFqdn() + " for topic: " + topic ); + + + topicURL = cluster.getTopicProtocol() + "://" + cluster.getFqdn() + ":" + cluster.getTopicPort() + "/events/" + topic ; + + return makeConnection( topicURL ); + } + + private boolean makeConnection( String pURL ) { + logger.info( "makeConnection to " + pURL ); + + try { + URL u = new URL( pURL ); + uc = (HttpsURLConnection) u.openConnection(); + uc.setInstanceFollowRedirects(false); + logger.info( "successful connect to " + pURL ); + return(true); + } catch (Exception e) { + logger.error("Unexpected error during openConnection of " + pURL ); + e.printStackTrace(); + return(false); + } + + } + + static String bodyToString( InputStream is ) { + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader( new InputStreamReader(is)); + String line; + try { + while ((line = br.readLine()) != null ) { + sb.append( line ); + } + } catch (IOException ex ) { + logger.error( "IOexception:" + ex); + } + + return sb.toString(); + } + + public ApiError doPostMessage( String postMessage ) { + ApiError response = new ApiError(); + String auth = "Basic " + Base64.encodeBase64String(mmProvCred.getBytes()); + + + + try { + byte[] postData = postMessage.getBytes(); + logger.info( "post fields=" + postMessage ); + uc.setRequestProperty("Authorization", auth); + logger.info( "Authenticating with " + auth ); + uc.setRequestMethod("POST"); + uc.setRequestProperty("Content-Type", "application/json"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + + + try { + uc.connect(); + os = uc.getOutputStream(); + os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + response.setCode( uc.getResponseCode()); + logger.info( "http response code:" + response.getCode()); + response.setMessage( uc.getResponseMessage() ); + logger.info( "response message=" + response.getMessage() ); + + + if ( response.getMessage() == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + response.setMessage( h0.substring(j + 1) ); + } + } + } + if ( response.is2xx() ) { + response.setFields( bodyToString( uc.getInputStream() ) ); + logger.info( "responseBody=" + response.getFields() ); + return response; + + } + + } catch (Exception e) { + response.setCode(500); + response.setMessage( "Unable to read response"); + logger.warn( response.getMessage() ); + e.printStackTrace(); + } + finally { + try { + uc.disconnect(); + } catch ( Exception e ) {} + } + return response; + + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/ConnWrapper.java b/src/main/java/org/openecomp/dmaapbc/database/ConnWrapper.java new file mode 100644 index 0000000..1cbba1d --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/ConnWrapper.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.sql.*; + + +public abstract class ConnWrapper { + protected Connection c; + protected PreparedStatement ps; + protected ResultSet rs; + protected abstract T run(U u) throws Exception; + public T protect(ConnectionFactory cf, U u) throws DBException { + try { + try { + return(attempt(cf, u, false)); + } catch (SQLException sqle) { + return(attempt(cf, u, true)); + } + } catch (RuntimeException rte) { + throw rte; + } catch (Exception e) { + throw new DBException(e); + } + } + private T attempt(ConnectionFactory cf, U u, boolean fresh) throws Exception { + c = null; + ps = null; + rs = null; + try { + c = cf.get(fresh); + T ret = run(u); + cf.release(c); + c = null; + return(ret); + } finally { + if (rs != null) { try { rs.close(); } catch (Exception e) {}} + rs = null; + if (ps != null) { try { ps.close(); } catch (Exception e) {}} + ps = null; + if (c != null) { try { c.close(); } catch (Exception e) {}} + c = null; + } + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/ConnectionFactory.java b/src/main/java/org/openecomp/dmaapbc/database/ConnectionFactory.java new file mode 100644 index 0000000..7dd54ae --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/ConnectionFactory.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.sql.*; +import java.util.*; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.util.DmaapConfig; + +public class ConnectionFactory { + static final Logger logger = Logger.getLogger(ConnectionFactory.class); + static { + try { + Class.forName("org.postgresql.Driver"); + } catch (Exception e) { + logger.error("Unable to load postgres driver " + e, e); + } + } + private static ConnectionFactory instance = new ConnectionFactory(); + private String host; + private String dbname; + private String dbuser; + private String dbcr; + public ConnectionFactory() { + Properties p = DmaapConfig.getConfig(); + host = p.getProperty("DB.host", "dcae-pstg-write-ftl.domain.notset.com"); + dbname = p.getProperty("DB.name", "dmaap"); + dbuser = p.getProperty("DB.user", "dmaap_admin"); + dbcr = p.getProperty("DB.cred", "test234-ftl"); + } + public static ConnectionFactory getDefaultInstance() { + return(instance); + } + private Connection[] pool = new Connection[5]; + private int cur; + public Connection get(boolean fresh) throws SQLException { + if (!fresh) { + synchronized(this) { + if (cur > 0) { + return(pool[--cur]); + } + } + } + Properties p = new Properties(); + p.put("user", dbuser); + p.put("password", dbcr); + return(DriverManager.getConnection("jdbc:postgresql://" + host + "/" + dbname, p)); + } + public void release(Connection c) { + synchronized(this) { + if (cur < pool.length) { + pool[cur++] = c; + return; + } + } + try { c.close(); } catch (Exception e) {} + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/DBException.java b/src/main/java/org/openecomp/dmaapbc/database/DBException.java new file mode 100644 index 0000000..91193d8 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/DBException.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import org.apache.log4j.Logger; + +public class DBException extends RuntimeException { + static final Logger logger = Logger.getLogger(DBException.class); + public DBException(Exception e) { + super(e); + logger.error("Database access problem " + e, e); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/DBFieldHandler.java b/src/main/java/org/openecomp/dmaapbc/database/DBFieldHandler.java new file mode 100644 index 0000000..46e0fb5 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/DBFieldHandler.java @@ -0,0 +1,194 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.lang.reflect.*; +import java.sql.*; +import java.util.*; +import org.apache.log4j.Logger; + +public class DBFieldHandler { + static final Logger logger = Logger.getLogger(DBFieldHandler.class); + public static interface SqlOp { + public Object get(ResultSet rs, int index) throws Exception; + public void set(PreparedStatement ps, int index, Object value) throws Exception; + } + private static class AofString implements SqlOp { + public Object get(ResultSet rs, int index) throws Exception { + String val = rs.getString(index); + if (val == null) { + return(null); + } + String[] ret = val.split(","); + for (int i = 0; i < ret.length; i++) { + ret[i] = funesc(ret[i]); + } + return(ret); + } + public void set(PreparedStatement ps, int index, Object x) throws Exception { + String[] val = (String[])x; + if (val == null) { + ps.setString(index, null); + return; + } + StringBuffer sb = new StringBuffer(); + String sep = ""; + for (String s: val) { + sb.append(sep).append(fesc(s)); + sep = ","; + } + ps.setString(index, sb.toString()); + } + } + private static class EnumSql implements SqlOp { + private Class enclass; + public EnumSql(Class enclass) { + this.enclass = enclass; + } + @SuppressWarnings("unchecked") + public Object get(ResultSet rs, int index) throws Exception { + String val = rs.getString(index); + if (val == null) { + return(null); + } else { + return(Enum.valueOf(enclass, val)); + } + } + public void set(PreparedStatement ps, int index, Object value) throws Exception { + if (value == null) { + ps.setString(index, null); + } else { + ps.setString(index, value.toString()); + } + } + } + private static class SqlDate implements SqlOp { + public Object get(ResultSet rs, int index) throws Exception { + return(rs.getTimestamp(index)); + } + public void set(PreparedStatement ps, int index, Object val) throws Exception { + if (val instanceof java.util.Date && !(val instanceof java.sql.Timestamp)) { + val = new java.sql.Timestamp(((java.util.Date)val).getTime()); + } + ps.setTimestamp(index, (java.sql.Timestamp)val); + } + } + private static class SqlType implements SqlOp { + private Method sqlget; + private Method sqlset; + private SqlType(String tag) throws Exception { + sqlget = ResultSet.class.getMethod("get" + tag, Integer.TYPE); + sqlset = PreparedStatement.class.getMethod("set" + tag, Integer.TYPE, sqlget.getReturnType()); + sqltypes.put(sqlget.getReturnType().getName(), this); + } + public Object get(ResultSet rs, int index) throws Exception { + return(sqlget.invoke(rs, index)); + } + public void set(PreparedStatement ps, int index, Object val) throws Exception { + try { + sqlset.invoke(ps, index, val); + } catch (Exception e) { + logger.error("Problem setting field " + index + " to " + val + " statement is " + ps); + throw e; + } + } + } + private static Map sqltypes; + static { + sqltypes = new HashMap(); + sqltypes.put("[Ljava.lang.String;", new AofString()); + sqltypes.put("java.util.Date", new SqlDate()); + try { + new SqlType("Boolean"); + new SqlType("Timestamp"); + new SqlType("Double"); + new SqlType("Float"); + new SqlType("Int"); + new SqlType("Long"); + new SqlType("Short"); + new SqlType("String"); + } catch (Exception e) { + logger.error("Problem initializing sql access methods " + e, e); + } + } + private Method objget; + private Method objset; + private SqlOp sqlop; + private int fieldnum; + public void copy(Object from, Object to) throws Exception { + objset.invoke(to, objget.invoke(from)); + } + public void setKey(Object o, String key) throws Exception { + objset.invoke(o, key); + } + public String getKey(Object o) throws Exception { + return((String)objget.invoke(o)); + } + public void toSQL(Object o, PreparedStatement ps) throws Exception { + sqlop.set(ps, fieldnum, objget.invoke(o)); + } + public void fromSQL(ResultSet r, Object o) throws Exception { + objset.invoke(o, sqlop.get(r, fieldnum)); + } + public DBFieldHandler(Class c, String fieldname, int fieldnum) throws Exception { + this(c, fieldname, fieldnum, null); + } + public DBFieldHandler(Class c, String fieldname, int fieldnum, SqlOp op) throws Exception { + this.fieldnum = fieldnum; + StringBuffer sb = new StringBuffer(); + for (String s: fieldname.split("_")) { + sb.append(s.substring(0, 1).toUpperCase()).append(s.substring(1)); + } + String camelcase = sb.toString(); + try { + objget = c.getMethod("is" + camelcase); + } catch (Exception e) { + objget = c.getMethod("get" + camelcase); + } + objset = c.getMethod("set" + camelcase, objget.getReturnType()); + sqlop = op; + if (sqlop != null) { + return; + } + Class x = objget.getReturnType(); + if (x.isEnum()) { + sqlop = new EnumSql(x); + return; + } + sqlop = sqltypes.get(x.getName()); + if (sqlop != null) { + return; + } + logger.error("No field handler for class " + c.getName() + " field " + fieldname + " index " + fieldnum + " type " + x.getName()); + } + public static String fesc(String s) { + if (s == null) { + return(s); + } + return(s.replaceAll("@", "@a").replaceAll(";", "@s").replaceAll(",", "@c")); + } + public static String funesc(String s) { + if (s == null) { + return(s); + } + return(s.replaceAll("@c", ",").replaceAll("@s", ";").replaceAll("@a", "@")); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/DBMap.java b/src/main/java/org/openecomp/dmaapbc/database/DBMap.java new file mode 100644 index 0000000..c195245 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/DBMap.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.sql.*; +import java.util.*; + +public class DBMap extends TableHandler implements Map { + public DBMap(Class cls, String tabname, String keyfield) throws Exception { + this(ConnectionFactory.getDefaultInstance(), cls, tabname, keyfield); + } + public DBMap(ConnectionFactory cf, Class cls, String tabname, String keyfield) throws Exception { + super(cf, cls, tabname, keyfield); + } + public void clear() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + public boolean containsKey(Object key) throws DBException { + return(get(key) != null); + } + public boolean containsValue(Object value) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + public boolean isEmpty() { + return(false); + } + public Set> entrySet() throws DBException { + return(list()); + } + public Set keySet() throws DBException { + Set ret = new HashSet(); + for (Map.Entry x: list()) { + ret.add(x.getKey()); + } + return(ret); + } + public void putAll(Map m) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + public int size() { + return(2); + } + public Collection values() throws DBException { + Collection ret = new Vector(); + for (Map.Entry x: list()) { + ret.add(x.getValue()); + } + return(ret); + } + public C get(Object key) throws DBException { + if (!(key instanceof String)) { + return(null); + } + return((new ConnWrapper() { + protected C run(String key) throws Exception { + ps = c.prepareStatement(getstmt); + ps.setString(1, (String)key); + rs = ps.executeQuery(); + if (!rs.next()) { + return(null); + } + C ret = cls.newInstance(); + for (DBFieldHandler f: fields) { + f.fromSQL(rs, ret); + } + return(ret); + } + }).protect(cf, (String)key)); + } + public Set> list() throws DBException { + return((new ConnWrapper>, Object>() { + protected Set> run(Object junk) throws Exception { + DBFieldHandler keyfield = fields[fields.length - 1]; + ps = c.prepareStatement(liststmt); + rs = ps.executeQuery(); + Set> ret = new HashSet>(); + while (rs.next()) { + C val = cls.newInstance(); + for (DBFieldHandler f: fields) { + f.fromSQL(rs, val); + } + String key = keyfield.getKey(val); + ret.add(new AbstractMap.SimpleEntry(key, val)); + } + return(ret); + } + }).protect(cf, null)); + } + public C put(String key, C val) throws DBException { + try { + fields[fields.length - 1].setKey(val, key); + } catch (Exception e) { + throw new DBException(e); + } + PreparedStatement ps = null; + return((new ConnWrapper() { + protected C run(C val) throws Exception { + ps = c.prepareStatement(insorreplstmt); + for (DBFieldHandler f: fields) { + f.toSQL(val, ps); + } + ps.executeUpdate(); + return(null); + } + }).protect(cf, val)); + } + public C remove(Object key) throws DBException { + if (!(key instanceof String)) { + return(null); + } + return((new ConnWrapper() { + protected C run(String key) throws Exception { + ps = c.prepareStatement(delstmt); + ps.setString(1, key); + ps.executeUpdate(); + return(null); + } + }).protect(cf, (String)key)); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/DBSingleton.java b/src/main/java/org/openecomp/dmaapbc/database/DBSingleton.java new file mode 100644 index 0000000..25ed793 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/DBSingleton.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.sql.*; +import java.util.*; + +import org.openecomp.dmaapbc.util.Singleton; + +public class DBSingleton extends TableHandler implements Singleton { + private C singleton; + public DBSingleton(Class cls, String tabname) throws Exception { + this(ConnectionFactory.getDefaultInstance(), cls, tabname); + } + public DBSingleton(ConnectionFactory cf, Class cls, String tabname) throws Exception { + super(cf, cls, tabname, null); + singleton = cls.newInstance(); + } + public C get() throws DBException { + return((new ConnWrapper() { + protected C run(Object junk) throws Exception { + ps = c.prepareStatement(getstmt); + rs = ps.executeQuery(); + if (!rs.next()) { + return(null); + } + for (DBFieldHandler f: fields) { + f.fromSQL(rs, singleton); + } + return(singleton); + } + }).protect(cf, null)); + } + public void init(C val) throws DBException { + if (get() != null) { + return; + } + (new ConnWrapper() { + protected Void run(C val) throws Exception { + ps = c.prepareStatement(initstmt); + for (DBFieldHandler f: fields) { + f.toSQL(val, ps); + } + ps.executeUpdate(); + if (val != singleton) { + for (DBFieldHandler f: fields) { + f.copy(val, singleton); + } + } + return(null); + } + }).protect(cf, val); + } + public void update(C val) throws DBException { + (new ConnWrapper() { + protected Void run(C val) throws Exception { + ps = c.prepareStatement(insorreplstmt); + for (DBFieldHandler f: fields) { + f.toSQL(val, ps); + } + ps.executeUpdate(); + if (val != singleton) { + for (DBFieldHandler f: fields) { + f.copy(val, singleton); + } + } + return(null); + } + }).protect(cf, val); + } + public void remove() throws DBException { + (new ConnWrapper() { + protected Void run(Object junk) throws Exception { + ps = c.prepareStatement(delstmt); + ps.executeUpdate(); + return(null); + } + }).protect(cf, null); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/DatabaseClass.java b/src/main/java/org/openecomp/dmaapbc/database/DatabaseClass.java new file mode 100644 index 0000000..973d592 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/DatabaseClass.java @@ -0,0 +1,268 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.util.*; +import java.sql.*; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.model.DR_Node; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.DR_Sub; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.model.Dmaap; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.model.MR_Client; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.MirrorMaker; +import org.openecomp.dmaapbc.model.ReplicationVector; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.service.DmaapService; +import org.openecomp.dmaapbc.util.DmaapConfig; +import org.openecomp.dmaapbc.util.Singleton; + +import org.openecomp.dmaapbc.model.*; + + + + +public class DatabaseClass { + + static final Logger logger = Logger.getLogger(DatabaseClass.class); + + private static Singleton dmaap; + private static Map dcaeLocations; + private static Map dr_nodes; + private static Map dr_pubs; + private static Map dr_subs; + private static Map mr_clients; + private static Map mr_clusters; + private static Map feeds; + private static Map topics; + private static Map mirrors; + + private static long lastTime = 0L; + + private static class MirrorVectorHandler implements DBFieldHandler.SqlOp { + public Object get(ResultSet rs, int index) throws Exception { + String val = rs.getString(index); + if (val == null) { + return(null); + } + Set rv = new HashSet(); + for (String s: val.split(",")) { + String[] f = s.split(";"); + if (f.length < 3) { + continue; + } + rv.add(new ReplicationVector(DBFieldHandler.funesc(f[0]), DBFieldHandler.funesc(f[1]), DBFieldHandler.funesc(f[2]))); + } + return(rv); + } + public void set(PreparedStatement ps, int index, Object val) throws Exception { + if (val == null) { + ps.setString(index, null); + return; + } + Set xv = (Set)val; + StringBuffer sb = new StringBuffer(); + String sep = ""; + for (Object o: xv) { + ReplicationVector rv = (ReplicationVector)o; + sb.append(sep).append(DBFieldHandler.fesc(rv.getFqtn())).append(';').append(DBFieldHandler.fesc(rv.getSourceCluster())).append(';').append(DBFieldHandler.fesc(rv.getTargetCluster())); + sep = ","; + } + ps.setString(index, sb.toString()); + } + } + + // modified version of MirrorVectorHandler for Topics + private static class MirrorTopicsHandler implements DBFieldHandler.SqlOp { + public Object get(ResultSet rs, int index) throws Exception { + String val = rs.getString(index); + if (val == null) { + return(null); + } + List rv = new ArrayList(); + for (String s: val.split(",")) { + //String[] f = s.split(";"); + //if (f.length < 3) { + // continue; + //} + rv.add(new String(s)); + } + return(rv); + } + public void set(PreparedStatement ps, int index, Object val) throws Exception { + if (val == null) { + ps.setString(index, null); + return; + } + @SuppressWarnings("unchecked") + List xv = (List)val; + StringBuffer sb = new StringBuffer(); + String sep = ""; + for (Object o: xv) { + String rv = (String)o; + sb.append(sep).append(DBFieldHandler.fesc(rv)); + sep = ","; + } + ps.setString(index, sb.toString()); + } + } + public static Singleton getDmaap() { + return dmaap; + } + + + + public static Map getDcaeLocations() { + return dcaeLocations; + } + + public static Map getDr_nodes() { + return dr_nodes; + } + + public static Map getDr_subs() { + return dr_subs; + } + public static Map getDr_pubs() { + return dr_pubs; + } + + public static Map getMr_clients() { + return mr_clients; + } + + + public static Map getMr_clusters() { + return mr_clusters; + } + + public static Map getFeeds() { + return feeds; + } + public static Map getTopics() { + return topics; + } + public static Map getMirrorMakers() { + return mirrors; + } + + static { + try { + logger.info( "begin static initialization"); + logger.info( "initializing dmaap" ); + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + if ("true".equalsIgnoreCase(p.getProperty("UsePGSQL", "false"))) { + logger.info("Data from database"); + try { + LoadSchema.upgrade(); + } catch (Exception e) { + logger.warn("Problem updating DB schema", e); + } + try { + dmaap = new DBSingleton(Dmaap.class, "dmaap"); + dcaeLocations = new DBMap(DcaeLocation.class, "dcae_location", "dcae_location_name"); + dr_nodes = new DBMap(DR_Node.class, "dr_node", "fqdn"); + dr_pubs = new DBMap(DR_Pub.class, "dr_pub", "pub_id"); + dr_subs = new DBMap(DR_Sub.class, "dr_sub", "sub_id"); + mr_clients = new DBMap(MR_Client.class, "mr_client", "mr_client_id"); + mr_clusters = new DBMap(MR_Cluster.class, "mr_cluster", "dcae_location_name"); + feeds = new DBMap(Feed.class, "feed", "feed_id"); + topics = new DBMap(Topic.class, "topic", "fqtn"); + //TableHandler.setSpecialCase("mirror_maker", "vectors", new MirrorVectorHandler()); + TableHandler.setSpecialCase("mirror_maker", "topics", new MirrorTopicsHandler()); + mirrors = new DBMap(MirrorMaker.class, "mirror_maker", "mm_name"); + } catch (Exception e) { + logger.fatal("Error initializing database access " + e, e); + System.exit(1); + } + } else { + logger.info("Data from memory"); + dmaap = new Singleton() { + private Dmaap dmaap; + public void remove() { + dmaap = null; + } + public void init(Dmaap val) { + if (dmaap == null) { + dmaap = val; + } + } + public Dmaap get() { + return(dmaap); + } + public void update(Dmaap nd) { + dmaap.setVersion(nd.getVersion()); + dmaap.setTopicNsRoot(nd.getTopicNsRoot()); + dmaap.setDmaapName(nd.getDmaapName()); + dmaap.setDrProvUrl(nd.getDrProvUrl()); + dmaap.setBridgeAdminTopic(nd.getBridgeAdminTopic()); + dmaap.setLoggingUrl(nd.getLoggingUrl()); + dmaap.setNodeKey(nd.getNodeKey()); + dmaap.setAccessKeyOwner(nd.getAccessKeyOwner()); + } + }; + dcaeLocations = new HashMap(); + dr_nodes = new HashMap(); + dr_pubs = new HashMap(); + dr_subs = new HashMap(); + mr_clients = new HashMap(); + mr_clusters = new HashMap(); + feeds = new HashMap(); + topics = new HashMap(); + mirrors = new HashMap(); + } + dmaap.init(new Dmaap("0", "", "", "", "", "", "", "")); + // check for, and set up initial data, if it isn't already there + Dmaap dmx = dmaap.get(); + if ("0".equals(dmx.getVersion())) { + + dmx = new Dmaap("0", "", "", "", "", "", "", ""); + dmx.setDmaapName(p.getProperty("DmaapName")); + dmx.setDrProvUrl("https://" + p.getProperty("DR.provhost")); + dmx.setVersion("1"); + dmx.setTopicNsRoot("org.openecomp.dcae.dmaap"); + dmx.setBridgeAdminTopic("DCAE_MM_AGENT"); + + (new DmaapService()).addDmaap(dmx); + } + } catch (Exception e) { + logger.error("Error loading database " + e, e); + } + } + + public synchronized static String getNextClientId() { + + long id = System.currentTimeMillis(); + if ( id <= lastTime ) { + id = lastTime + 1; + } + lastTime = id; + return Long.toString(id); + } + + + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/LoadSchema.java b/src/main/java/org/openecomp/dmaapbc/database/LoadSchema.java new file mode 100644 index 0000000..bcf838a --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/LoadSchema.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.io.*; +import java.sql.*; +import org.apache.log4j.Logger; + +public class LoadSchema { + static Logger logger = Logger.getLogger(LoadSchema.class); + static int getVer(Statement s) throws SQLException { + ResultSet rs = null; + try { + rs = s.executeQuery("SELECT version FROM dmaapbc_sch_ver"); + rs.next(); + return(rs.getInt(1)); + } finally { + if (rs != null) { + rs.close(); + } + } + } + static void upgrade() throws SQLException { + ConnectionFactory cf = ConnectionFactory.getDefaultInstance(); + Connection c = null; + Statement stmt = null; + InputStream is = null; + try { + c = cf.get(true); + stmt = c.createStatement(); + int newver = -1; + try { + newver = getVer(stmt); + } catch (Exception e) {} + logger.info("Database schema currently at version " + newver++); + while ((is = LoadSchema.class.getClassLoader().getResourceAsStream("schema_" + newver + ".sql")) != null) { + logger.info("Upgrading database schema to version " + newver); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String s; + String sofar = null; + while ((s = br.readLine()) != null) { + logger.info("SCHEMA: " + s); + s = s.trim(); + if (s.length() == 0 || s.startsWith("--")) { + continue; + } + if (sofar == null) { + sofar = s; + } else { + sofar = sofar + " " + s; + } + if (s.endsWith(";")) { + sofar = sofar.substring(0, sofar.length() - 1); + boolean ignore = false; + if (sofar.startsWith("@")) { + ignore = true; + sofar = sofar.substring(1).trim(); + } + try { + stmt.execute(sofar); + } catch (SQLException sqle) { + if (!ignore) { + throw sqle; + } + } + sofar = null; + } + } + is.close(); + is = null; + if (getVer(stmt) != newver) { + throw new SQLException("Schema version not properly updated to " + newver + " by upgrade script"); + } + logger.info("Upgrade to database schema version " + newver + " successful"); + newver++; + } + } catch (IOException ioe) { + throw new SQLException(ioe); + } finally { + if (stmt != null) { try { stmt.close(); } catch (Exception e) {}} + if (c != null) { try { c.close(); } catch (Exception e) {}} + } + } + public static void main(String[] args) throws Exception { + upgrade(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/database/TableHandler.java b/src/main/java/org/openecomp/dmaapbc/database/TableHandler.java new file mode 100644 index 0000000..2104123 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/database/TableHandler.java @@ -0,0 +1,115 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.database; + +import java.util.*; +import java.lang.reflect.*; +import java.sql.*; + +class TableHandler { + protected ConnectionFactory cf; + protected boolean haskey; + protected String delstmt; + protected String insorreplstmt; + protected String getstmt; + protected String liststmt; + protected String initstmt; + protected Class cls; + protected DBFieldHandler[] fields; + private static Map> exceptions = new HashMap>(); + public static void setSpecialCase(String dbtabname, String dbfldname, DBFieldHandler.SqlOp handler) { + Map m = exceptions.get(dbtabname); + if (m == null) { + m = new HashMap(); + exceptions.put(dbtabname, m); + } + m.put(dbfldname, handler); + } + public static DBFieldHandler.SqlOp getSpecialCase(String dbtabname, String dbfldname) { + Map m = exceptions.get(dbtabname); + if (m != null) { + return(m.get(dbfldname)); + } + return(null); + } + protected TableHandler(Class cls, String tabname, String keyname) throws Exception { + this(ConnectionFactory.getDefaultInstance(), cls, tabname, keyname); + } + protected TableHandler(ConnectionFactory cf, Class cls, String tabname, String keyname) throws Exception { + this.cf = cf; + Connection c = null; + try { + c = cf.get(false); + setup(c.getMetaData(), cls, tabname, keyname); + } finally { + if (c != null) { + cf.release(c); + } + } + } + private void setup(DatabaseMetaData dmd, Class cls, String tabname, String keyname) throws Exception { + this.cls = cls; + Vector h = new Vector(); + ResultSet rs = dmd.getColumns("", "public", tabname, null); + StringBuffer sb1 = new StringBuffer(); + StringBuffer sb2 = new StringBuffer(); + StringBuffer sb3 = new StringBuffer(); + int count = 0; + while (rs.next()) { + if (!rs.getString(3).equals(tabname)) { + continue; + } + String cname = rs.getString(4); + if (cname.equals(keyname)) { + haskey = true; + continue; + } + sb1.append(", ").append(cname); + sb2.append(", ?"); + sb3.append(", EXCLUDED.").append(cname); + count++; + h.add(new DBFieldHandler(cls, cname, count, getSpecialCase(tabname, cname))); + } + if (count == 0) { + throw new SQLException("Table " + tabname + " not found"); + } + String clist = sb1.substring(2); + String qlist = sb2.substring(2); + String elist = sb3.substring(2); + if (keyname != null && !haskey) { + throw new SQLException("Table " + tabname + " does not have key column " + keyname + " not found"); + } + if (haskey) { + count++; + h.add(new DBFieldHandler(cls, keyname, count, getSpecialCase(tabname, keyname))); + delstmt = "DELETE FROM " + tabname + " WHERE " + keyname + " = ?"; + insorreplstmt = "INSERT INTO " + tabname + " (" + clist + ", " + keyname + ") VALUES (" + qlist + ", ?) ON CONFLICT(" + keyname + ") DO UPDATE SET (" + clist + ") = (" + elist + ")"; + getstmt = "SELECT " + clist + ", " + keyname + " FROM " + tabname + " WHERE " + keyname + " = ?"; + liststmt = "SELECT " + clist + ", " + keyname + " FROM " + tabname; + } else { + delstmt = "DELETE FROM " + tabname; + initstmt = "INSERT INTO " + tabname + " (" + clist + ") VALUES (" + qlist + ")"; + insorreplstmt = "UPDATE " + tabname + " SET (" + clist + ") = (" + qlist + ")"; + getstmt = "SELECT " + clist + ", " + keyname + " FROM " + tabname; + } + fields = h.toArray(new DBFieldHandler[h.size()]); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/ApiError.java b/src/main/java/org/openecomp/dmaapbc/model/ApiError.java new file mode 100644 index 0000000..0659f65 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/ApiError.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ApiError { + private int code; + private String message; + private String fields; + + public int getCode() { + return code; + } + public void setCode(int rc) { + this.code = rc; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public String getFields() { + return fields; + } + public void setFields(String fields) { + this.fields = fields; + } + public String toString() { + return String.format( "code=%d msg=%s fields=%s", this.code, this.message, this.fields ); + } + public boolean is2xx() { + + return code >= 200 && code < 300; + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/BrTopic.java b/src/main/java/org/openecomp/dmaapbc/model/BrTopic.java new file mode 100644 index 0000000..e8a697e --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/BrTopic.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + +@XmlRootElement +public class BrTopic { + static final Logger logger = Logger.getLogger(BrTopic.class); + + private String brSource; + private String brTarget; + private int topicCount; + + // no-op constructor used by framework + public BrTopic() { + } + + public String getBrSource() { + return brSource; + } + + public void setBrSource(String brSource) { + this.brSource = brSource; + } + + public String getBrTarget() { + return brTarget; + } + + public void setBrTarget(String brTarget) { + this.brTarget = brTarget; + } + + public int getTopicCount() { + return topicCount; + } + + public void setTopicCount(int topicCount) { + this.topicCount = topicCount; + } + + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/DR_Node.java b/src/main/java/org/openecomp/dmaapbc/model/DR_Node.java new file mode 100644 index 0000000..f3ff1fe --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/DR_Node.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class DR_Node extends DmaapObject { + private String fqdn; + private String dcaeLocationName; + private String hostName; + private String version; + + public DR_Node() { + + } + + public DR_Node( String f, + String dLN, + String hN, + String v ) { + this.fqdn = f; + this.dcaeLocationName = dLN; + this.hostName = hN; + this.version = v; + } + + public String getFqdn() { + return fqdn; + } + + public void setFqdn(String fqdn) { + this.fqdn = fqdn; + } + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/DR_Pub.java b/src/main/java/org/openecomp/dmaapbc/model/DR_Pub.java new file mode 100644 index 0000000..2e3e894 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/DR_Pub.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.util.RandomString; + +@XmlRootElement +public class DR_Pub extends DmaapObject { + static final Logger logger = Logger.getLogger(DR_Pub.class); + private String dcaeLocationName; + private String username; + private String userpwd; + private String feedId; + private String pubId; + + + public DR_Pub() { + status = DmaapObject_Status.EMPTY; + + } + + public DR_Pub( String dLN ) { + this.dcaeLocationName = dLN; + this.status = DmaapObject_Status.STAGED; + } + + public DR_Pub( String dLN, + String uN, + String uP, + String fI, + String pI ) { + this.dcaeLocationName = dLN; + this.username = uN; + this.userpwd = uP; + this.feedId = fI; + this.pubId = pI; + this.status = DmaapObject_Status.VALID; + } + + + public DR_Pub( String dLN, + String uN, + String uP, + String fI ) { + this.dcaeLocationName = dLN; + this.username = uN; + this.userpwd = uP; + this.feedId = fI; + this.pubId = fI + "." + DR_Pub.nextKey(); + this.status = DmaapObject_Status.VALID; + } + + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserpwd() { + return userpwd; + } + + public void setUserpwd(String userpwd) { + this.userpwd = userpwd; + } + + public String getFeedId() { + return feedId; + } + + public void setFeedId(String feedId) { + this.feedId = feedId; + } + + public String getPubId() { + return pubId; + } + + public void setPubId(String pubId) { + this.pubId = pubId; + } + + public void setNextPubId() { + this.pubId = this.feedId + "." + DR_Pub.nextKey(); + } + + public DR_Pub setRandomUserName() { + RandomString r = new RandomString(15); + this.username = "tmp_" + r.nextString(); + return this; + } + public DR_Pub setRandomPassword() { + RandomString r = new RandomString(15); + this.userpwd = r.nextString(); + return this; + } + + public static String nextKey() { + RandomString ri = new RandomString(5); + return ri.nextString(); + + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/DR_Sub.java b/src/main/java/org/openecomp/dmaapbc/model/DR_Sub.java new file mode 100644 index 0000000..0184a14 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/DR_Sub.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.nio.charset.StandardCharsets; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +@XmlRootElement +public class DR_Sub extends DmaapObject { + static final Logger logger = Logger.getLogger(DR_Sub.class); + + private String dcaeLocationName; + private String username; + private String userpwd; + private String feedId; + private String deliveryURL; + private String logURL; + private String subId; + private boolean use100; + private boolean suspended; + private String owner; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public boolean isSuspended() { + return suspended; + } + + public void setSuspended(boolean suspended) { + this.suspended = suspended; + } + + + + public boolean isUse100() { + return use100; + } + + public void setUse100(boolean use100) { + this.use100 = use100; + } + + public DR_Sub() { + + } + + public DR_Sub( String dLN, + String uN, + String uP, + String fI, + String dU, + String lU, + boolean u100 ) { + this.dcaeLocationName = dLN; + this.username = uN; + this.userpwd = uP; + this.feedId = fI; + this.deliveryURL = dU; + this.logURL = lU; + this.use100 = u100; + this.setStatus( DmaapObject_Status.NEW ); + this.subId = "0"; + } + + public DR_Sub ( String json ) { + logger.info( "DR_Sub:" + json ); + JSONParser parser = new JSONParser(); + JSONObject jsonObj; + + try { + jsonObj = (JSONObject) parser.parse( json ); + } catch ( ParseException pe ) { + logger.error( "Error parsing provisioning data: " + json ); + this.setStatus( DmaapObject_Status.INVALID ); + return; + } + + this.setOwner( (String) jsonObj.get("subscriber")); + this.setSuspended( (boolean) jsonObj.get("suspend")); + + JSONObject links = (JSONObject) jsonObj.get("links"); + String url = (String) links.get("feed"); + this.setFeedId( url.substring( url.lastIndexOf('/')+1, url.length() )); + url = (String) links.get("self"); + this.setSubId( url.substring( url.lastIndexOf('/')+1, url.length() )); + logger.info( "feedid="+ this.getFeedId() ); + this.setLogURL( (String) links.get("log") ); + + JSONObject del = (JSONObject) jsonObj.get("delivery"); + this.setDeliveryURL( (String) del.get("url") ); + this.setUsername( (String) del.get("user")); + this.setUserpwd( (String) del.get( "password")); + this.setUse100((boolean) del.get( "use100")); + + this.setStatus( DmaapObject_Status.VALID ); + + logger.info( "new DR_Sub returning"); + } + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserpwd() { + return userpwd; + } + + public void setUserpwd(String userpwd) { + this.userpwd = userpwd; + } + + public String getFeedId() { + return feedId; + } + + public void setFeedId(String feedId) { + this.feedId = feedId; + } + + public String getDeliveryURL() { + return deliveryURL; + } + + public void setDeliveryURL(String deliveryURL) { + this.deliveryURL = deliveryURL; + } + + public String getLogURL() { + return logURL; + } + + public void setLogURL(String logURL) { + this.logURL = logURL; + } + + public String getSubId() { + return subId; + } + + public void setSubId(String subId) { + this.subId = subId; + } + + + + public byte[] getBytes() { + return toProvJSON().getBytes(StandardCharsets.UTF_8); + } + // returns the DR_Sub object in JSON that conforms to DR Prov Server expectations + public String toProvJSON() { + + // in DR 3.0, API v2.1 a new groupid field is added. We are not using this required field so just set it to 0. + // we send this regardless of DR Release because older versions of DR seem to safely ignore it + // and soon those versions won't be around anyway... + String postJSON = String.format("{\"delivery\": {\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": \"%s\"}, \"metadataOnly\": false, \"groupid\": \"0\"}", + this.getDeliveryURL(), + this.getUsername(), + this.getUserpwd(), + this.isUse100() ); + + logger.info( postJSON ); + return postJSON; + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/DcaeLocation.java b/src/main/java/org/openecomp/dmaapbc/model/DcaeLocation.java new file mode 100644 index 0000000..f0ef481 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/DcaeLocation.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + +@XmlRootElement +public class DcaeLocation extends DmaapObject { + static final Logger logger = Logger.getLogger(MR_Cluster.class); + private String clli; + private String dcaeLayer; + private String dcaeLocationName; + private String openStackAvailabilityZone; + private String subnet; + + + + public DcaeLocation() { + + } + + public DcaeLocation( String c, + String dL, + String dLN, + String oSAZ, + String s ) { + + this.clli = c; + this.dcaeLayer = dL; + this.dcaeLocationName = dLN; + this.openStackAvailabilityZone = oSAZ; + this.subnet = s; + } + + public String getClli() { + return clli; + } + + public void setClli(String clli) { + this.clli = clli; + } + + public String getDcaeLayer() { + return dcaeLayer; + } + + public void setDcaeLayer(String dcaeLayer) { + this.dcaeLayer = dcaeLayer; + } + public boolean isCentral() { + return dcaeLayer != null && dcaeLayer.contains("central"); + } + public boolean isLocal() { + return dcaeLayer != null && dcaeLayer.contains("local"); + } + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + + + public String getOpenStackAvailabilityZone() { + return openStackAvailabilityZone; + } + + public void setOpenStackAvailabilityZone(String openStackAvailabilityZone) { + this.openStackAvailabilityZone = openStackAvailabilityZone; + } + + public String getSubnet() { + return subnet; + } + + public void setSubnet(String subnet) { + this.subnet = subnet; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/Dmaap.java b/src/main/java/org/openecomp/dmaapbc/model/Dmaap.java new file mode 100644 index 0000000..362c184 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/Dmaap.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + +@XmlRootElement +public class Dmaap extends DmaapObject { + static final Logger logger = Logger.getLogger(Dmaap.class); + + private String version; + private String topicNsRoot; + private String dmaapName; + private String drProvUrl; + private String bridgeAdminTopic; + private String loggingUrl; + private String nodeKey; + private String accessKeyOwner; + + + + // no-op constructor used by framework + public Dmaap() { + + } + + public Dmaap( String ver, + String tnr, + String dn, + String dpu, + String lu, + String bat, + String nk, + String ako ) { + this.version = ver; + this.topicNsRoot = tnr; + this.dmaapName = dn; + this.drProvUrl = dpu; + this.bridgeAdminTopic = bat; + this.loggingUrl = lu; + this.nodeKey = nk; + this.accessKeyOwner = ako; + this.setStatus( DmaapObject_Status.NEW ); + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getTopicNsRoot() { + return topicNsRoot; + } + + public void setTopicNsRoot(String topicNsRoot) { + this.topicNsRoot = topicNsRoot; + } + + public String getDmaapName() { + return dmaapName; + } + + public void setDmaapName(String dmaapName) { + this.dmaapName = dmaapName; + } + + public String getDrProvUrl() { + return drProvUrl; + } + + public void setDrProvUrl(String drProvUrl) { + this.drProvUrl = drProvUrl; + } + + + public String getNodeKey() { + return nodeKey; + } + + public void setNodeKey(String nodeKey) { + this.nodeKey = nodeKey; + } + + public String getAccessKeyOwner() { + return accessKeyOwner; + } + + public void setAccessKeyOwner(String accessKeyOwner) { + this.accessKeyOwner = accessKeyOwner; + } + + + public String getBridgeAdminTopic() { + return bridgeAdminTopic; + } + + public void setBridgeAdminTopic(String bridgeAdminTopic) { + this.bridgeAdminTopic = bridgeAdminTopic; + } + + public String getLoggingUrl() { + return loggingUrl; + } + + public void setLoggingUrl(String loggingUrl) { + this.loggingUrl = loggingUrl; + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/DmaapObject.java b/src/main/java/org/openecomp/dmaapbc/model/DmaapObject.java new file mode 100644 index 0000000..39d4181 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/DmaapObject.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public abstract class DmaapObject { + protected Date lastMod; + protected DmaapObject_Status status; + + public Date getLastMod() { + return lastMod; + } + + public void setLastMod(Date lastMod) { + this.lastMod = lastMod; + } + + public void setLastMod() { + this.lastMod = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime(); + } + + public enum DmaapObject_Status { + EMPTY, + NEW, + STAGED, + VALID, + INVALID, + DELETED + } + public DmaapObject_Status getStatus() { + return status; + } + + public void setStatus(DmaapObject_Status status) { + this.status = status; + } + + public boolean isStatusValid() { + if ( this.status == DmaapObject_Status.VALID ) { + return true; + } + return false; + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/Feed.java b/src/main/java/org/openecomp/dmaapbc/model/Feed.java new file mode 100644 index 0000000..c445b65 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/Feed.java @@ -0,0 +1,279 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + + +import org.json.simple.*; +import org.json.simple.parser.*; +import org.openecomp.dmaapbc.service.DmaapService; +import org.openecomp.dmaapbc.util.RandomString; + +@XmlRootElement +public class Feed extends DmaapObject { + static final Logger logger = Logger.getLogger(Feed.class); + + + private String feedId; + + private String feedName; + private String feedVersion; + private String feedDescription; + private String owner; + private String asprClassification; + private String publishURL; + private String subscribeURL; + private boolean suspended; + private String logURL; + private String formatUuid; + + private ArrayList pubs; + private ArrayList subs; + + + + public boolean isSuspended() { + return suspended; + } + + public void setSuspended(boolean suspended) { + this.suspended = suspended; + } + + public String getSubscribeURL() { + return subscribeURL; + } + + public void setSubscribeURL(String subscribeURL) { + this.subscribeURL = subscribeURL; + } + + + + public Feed() { + this.pubs = new ArrayList(); + this.subs = new ArrayList(); + this.setStatus( DmaapObject_Status.EMPTY ); + + } + + public Feed( String name, + String version, + String description, + String owner, + String aspr + ) { + this.feedName = name; + this.feedVersion = version; + this.feedDescription = description; + this.owner = owner; + this.asprClassification = aspr; + this.pubs = new ArrayList(); + this.subs = new ArrayList(); + this.setStatus( DmaapObject_Status.NEW ); + + } + + // expects a String in JSON format, with known fields to populate Feed object + public Feed ( String json ) { + JSONParser parser = new JSONParser(); + JSONObject jsonObj; + + try { + jsonObj = (JSONObject) parser.parse( json ); + } catch ( ParseException pe ) { + logger.error( "Error parsing provisioning data: " + json ); + this.setStatus( DmaapObject_Status.INVALID ); + return; + } + this.setFeedName( (String) jsonObj.get("name")); + + + this.setFeedVersion( (String) jsonObj.get("version")); + this.setFeedDescription( (String) jsonObj.get("description")); + this.setOwner( (String) jsonObj.get("publisher")); + + this.setSuspended( (boolean) jsonObj.get("suspend")); + JSONObject links = (JSONObject) jsonObj.get("links"); + String url = (String) links.get("publish"); + this.setPublishURL( url ); + this.setFeedId( url.substring( url.lastIndexOf('/')+1, url.length() )); + logger.info( "feedid="+ this.getFeedId() ); + this.setSubscribeURL( (String) links.get("subscribe") ); + this.setLogURL( (String) links.get("log") ); + JSONObject auth = (JSONObject) jsonObj.get("authorization"); + this.setAsprClassification( (String) auth.get("classification")); + JSONArray pubs = (JSONArray) auth.get( "endpoint_ids"); + int i; + ArrayList dr_pub = new ArrayList(); + this.subs = new ArrayList(); + + for( i = 0; i < pubs.size(); i++ ) { + JSONObject entry = (JSONObject) pubs.get(i); + dr_pub.add( new DR_Pub( "someLocation", + (String) entry.get("id"), + (String) entry.get("password"), + this.getFeedId(), + this.getFeedId() + "." + DR_Pub.nextKey() )); + + } + this.setPubs( dr_pub ); + + this.setStatus( DmaapObject_Status.VALID ); + + } + + public String getFeedId() { + return feedId; + } + + public void setFeedId(String feedId) { + this.feedId = feedId; + } + + public String getFeedName() { + return feedName; + } + + public void setFeedName(String feedName) { + this.feedName = feedName; + } + + public String getFeedVersion() { + return feedVersion; + } + + public void setFeedVersion(String feedVersion) { + this.feedVersion = feedVersion; + } + + public String getFeedDescription() { + return feedDescription; + } + + public void setFeedDescription(String feedDescription) { + this.feedDescription = feedDescription; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getAsprClassification() { + return asprClassification; + } + + public void setAsprClassification(String asprClassification) { + this.asprClassification = asprClassification; + } + + public String getPublishURL() { + return publishURL; + } + + public void setPublishURL(String publishURL) { + this.publishURL = publishURL; + } + + public String getLogURL() { + return logURL; + } + + public void setLogURL(String logURL) { + this.logURL = logURL; + } + + + + public String getFormatUuid() { + return formatUuid; + } + + public void setFormatUuid(String formatUuid) { + this.formatUuid = formatUuid; + } + + // returns the Feed object in JSON that conforms to DR Prov Server expectations + public String toProvJSON() { + + ArrayList pubs = this.getPubs(); + String postJSON = String.format("{\"name\": \"%s\", \"version\": \"%s\", \"description\": \"%s\", \"suspend\": %s, \"authorization\": { \"classification\": \"%s\", ", + this.getFeedName(), + this.getFeedVersion(), + this.getFeedDescription(), + this.isSuspended() , + this.getAsprClassification() + ); + int i; + postJSON += "\"endpoint_addrs\": [],\"endpoint_ids\": ["; + String comma = ""; + for( i = 0 ; i < pubs.size(); i++) { + postJSON += String.format(" %s{\"id\": \"%s\",\"password\": \"%s\"}", + comma, + pubs.get(i).getUsername(), + pubs.get(i).getUserpwd() + ) ; + comma = ","; + } + postJSON += "]}}"; + + logger.info( "postJSON=" + postJSON); + return postJSON; + } + + public ArrayList getPubs() { + return pubs; + } + + public void setPubs( ArrayList pubs) { + this.pubs = pubs; + } + + public ArrayList getSubs() { + return subs; + } + + public void setSubs( ArrayList subs) { + this.subs = subs; + } + + public byte[] getBytes() { + return toProvJSON().getBytes(StandardCharsets.UTF_8); + } + + public static String getSubProvURL( String feedId ) { + String ret = new String(); + ret = new DmaapService().getDmaap().getDrProvUrl() + "/subscribe/" + feedId ; + return ret; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/MR_Client.java b/src/main/java/org/openecomp/dmaapbc/model/MR_Client.java new file mode 100644 index 0000000..684424a --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/MR_Client.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.database.DatabaseClass; + +@XmlRootElement +public class MR_Client extends DmaapObject { + static final Logger logger = Logger.getLogger(MR_Client.class); + + private String dcaeLocationName; + private String topicURL; + private String fqtn; + private String clientRole; + private String[] action; + private String mrClientId; + + + public MR_Client() { + this.mrClientId = DatabaseClass.getNextClientId(); + this.lastMod = new Date(); + this.setLastMod(); + logger.debug( "MR_Client constructor " + this.lastMod ); + + } + + public MR_Client( String dLN, + String f, + String cR, + String[] a ) { + this.dcaeLocationName = dLN; + this.fqtn = f; + this.clientRole = cR; + int i = 0; + + if ( this.action == null ) { + this.action = new String[a.length]; + } + for( String aa : a ) { + this.action[i++] = new String( aa ); + } + this.setStatus( DmaapObject_Status.NEW ); + this.mrClientId = DatabaseClass.getNextClientId(); + this.setLastMod(); + logger.debug( "MR_Client constructor w initialization " + this.lastMod ); + } + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + public String getFqtn() { + return fqtn; + } + + public void setFqtn(String fqtn) { + this.fqtn = fqtn; + } + + public String getClientRole() { + return clientRole; + } + + public void setClientRole(String clientRole) { + this.clientRole = clientRole; + } + + public String[] getAction() { + return action; + } + + public void setAction(String[] action) { + this.action = action; + } + + public String getMrClientId() { + return mrClientId; + } + + public void setMrClientId(String mrClientId) { + this.mrClientId = mrClientId; + } + + + + public String getTopicURL() { + return topicURL; + } + + public void setTopicURL(String topicURL) { + this.topicURL = topicURL; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/MR_Cluster.java b/src/main/java/org/openecomp/dmaapbc/model/MR_Cluster.java new file mode 100644 index 0000000..fcaf007 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/MR_Cluster.java @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.util.Date; +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + + +@XmlRootElement +public class MR_Cluster extends DmaapObject { + static final Logger logger = Logger.getLogger(MR_Cluster.class); + private String dcaeLocationName; + private String fqdn; + private String[] hosts; + //private DmaapTimestamp lastMod; + private String topicProtocol; + private String topicPort; + + + // TODO: make this a system property + private static String defaultTopicProtocol = "https"; + private static String defaultTopicPort = "3905"; + + + + + public MR_Cluster() { + this.topicProtocol = defaultTopicProtocol; + this.topicPort = defaultTopicPort; + this.lastMod = new Date(); + + logger.info( "MR_Cluster constructor " + this.lastMod ); + + } + + public MR_Cluster( String dLN, + String f, + String a, + String[] h ) { + this.dcaeLocationName = dLN; + this.fqdn = f; + this.hosts[0] = h[0]; + this.hosts[1] = h[1]; + this.hosts[2] = h[2]; + this.topicProtocol = defaultTopicProtocol; + this.topicPort = defaultTopicPort; + + logger.info( "MR_Cluster constructor w initialization complete" + this.lastMod ); + } + + public String getDcaeLocationName() { + return dcaeLocationName; + } + + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + + public String getFqdn() { + return fqdn; + } + + public void setFqdn(String fqdn) { + this.fqdn = fqdn; + } + + public String[] getHosts() { + return hosts; + } + + public void setHosts(String[] hosts) { + this.hosts = hosts; + } + + public String getTopicProtocol() { + return topicProtocol; + } + + public void setTopicProtocol(String topicProtocol) { + this.topicProtocol = topicProtocol; + } + + public String getTopicPort() { + return topicPort; + } + + public void setTopicPort(String topicPort) { + this.topicPort = topicPort; + } + + public String genTopicURL( String topic ) { + StringBuilder str = new StringBuilder( topicProtocol ); + str.append("://") + .append(fqdn) + .append(":") + .append(topicPort) + .append("/events/") + .append(topic); + + return str.toString(); + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/MirrorMaker.java b/src/main/java/org/openecomp/dmaapbc/model/MirrorMaker.java new file mode 100644 index 0000000..828e9e0 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/MirrorMaker.java @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.service.MirrorMakerService; + +public class MirrorMaker extends DmaapObject { + static final Logger logger = Logger.getLogger(MirrorMaker.class); + + private String sourceCluster; + private String targetCluster; + private String mmName; + private ArrayList topics; //re-using this var name for backwards DB compatibility + + private Set vectors; + + + public MirrorMaker(){ + + } + + public MirrorMaker(String source, String target) { + sourceCluster = source; + targetCluster = target; + mmName = genKey(source, target); + vectors = new HashSet(); + topics = new ArrayList(); + + } + + public String getMmName() { + return mmName; + } + + public void setMmName(String mmName) { + this.mmName = mmName; + } + + + public void addVector( String fqtn, String source, String target ) { + logger.info( "addVector: fqtn=" + fqtn + " source=" + source + " target=" + target ); + if ( ! sourceCluster.equals( source ) ){ + logger.error( "trying to add edge from source " + source + " into Map belonging to " + sourceCluster ); + } + vectors.add(new ReplicationVector( fqtn, source, target )); + } + + public void delVector( String fqtn, String source, String target ) { + vectors.remove(new ReplicationVector( fqtn, source, target)); + } + + + + public String toJSON() { + StringBuilder str = new StringBuilder( "{ \"source\": " + sourceCluster + ",\"topics\": [" ); + int numTargets = 0; + for (ReplicationVector rv: vectors) { + if ( numTargets > 0 ) { + str.append( ","); + } + str.append( " \"target\": " + rv.getTargetCluster() + ", \"topic\": " + rv.getFqtn()); + numTargets++; + } + str.append( "] }" ); + + return str.toString(); + } + + + // returns the JSON for MM message containing which Topics to replicate + /* + * example: + * + { + "messageID":"12349", + "updateWhiteList": + { + "name":"Global1ToGlobal3", + "whitelist":"org.openecomp.dcae.topic1,org.openecomp.dcae.topic2" + } + } + */ + public String updateWhiteList() { + StringBuilder str = new StringBuilder( "{ \"messageID\": \"" + MirrorMakerService.genTransactionId() + "\", \"updateWhiteList\": {" ); + str.append( " \"name\": \"" + this.getMmName() + "\", \"whitelist\": \"" ); + int numTargets = 0; + + //for (ReplicationVector rv: vectors) { + for (String rv: topics) { + if ( numTargets > 0 ) { + str.append( ","); + } + //str.append( rv.getFqtn() ); + str.append( rv ); + numTargets++; + } + str.append( "\" } }" ); + + return str.toString(); + } + + // returns the JSON for MM message indicating that a MM agent is needed between two clusters + // example: + /* + * + { + "messageID":"12345" + "createMirrorMaker": + { + "name":"Global1ToGlobal2", + "consumer":"192.168.0.1:2181", + "producer":"192.168.0.2:9092" + } + } + */ + public String createMirrorMaker() { + StringBuilder str = new StringBuilder( "{ \"messageID\": \"" + MirrorMakerService.genTransactionId() + "\", \"createMirrorMaker\": {" ); + str.append( " \"name\": \"" + this.getMmName() + "\", " ); + str.append( " \"consumer\": \"" + this.sourceCluster + ":2181\", " ); + str.append( " \"producer\": \"" + this.targetCluster + ":9092\" "); + + str.append( " } }" ); + + return str.toString(); + } + + + public String getSourceCluster() { + return sourceCluster; + } + + public void setSourceCluster(String sourceCluster) { + this.sourceCluster = sourceCluster; + } + + public String getTargetCluster() { + return targetCluster; + } + + public void setTargetCluster(String targetCluster) { + this.targetCluster = targetCluster; + } + + + public Set getVectors() { + return vectors; + } + + public void setVectors(Set vectors) { + this.vectors = vectors; + } + public ArrayList getTopics() { + return topics; + } + + //public void setVectors(Set vectors) { + public void setTopics(ArrayList topics) { + this.topics = topics; + } + + + public static String genKey( String s, String t) { + StringBuilder str = new StringBuilder(); + str.append(s); + str.append("-To-"); + str.append(t); + return str.toString(); + } + + + + public void addTopic( String topic ) { + topics.add(topic); + } + + public int getTopicCount() { + return topics.size(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/ReplicationVector.java b/src/main/java/org/openecomp/dmaapbc/model/ReplicationVector.java new file mode 100644 index 0000000..60f25e5 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/ReplicationVector.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; +import org.apache.log4j.Logger; + +public class ReplicationVector { + + + + static final Logger logger = Logger.getLogger(ReplicationVector.class); + public enum ReplicationVector_Status { + EMPTY, + NEW, + STAGED, + VALID, + INVALID, + INVALID_DUP, + DELETED + } + + String fqtn; + String sourceCluster; + String targetCluster; + ReplicationVector_Status status; + + public ReplicationVector(){ + + } + + public ReplicationVector(String fqtn, String sourceCluster, + String targetCluster) { + super(); + this.fqtn = fqtn; + this.sourceCluster = sourceCluster; + this.targetCluster = targetCluster; + } + + public String getFqtn() { + return fqtn; + } + + public void setFqtn(String fqtn) { + this.fqtn = fqtn; + } + + public String getSourceCluster() { + return sourceCluster; + } + + public void setSourceCluster(String sourceCluster) { + this.sourceCluster = sourceCluster; + } + + public String getTargetCluster() { + return targetCluster; + } + + public void setTargetCluster(String targetCluster) { + this.targetCluster = targetCluster; + } + + public int hashCode() { + StringBuilder tmp = new StringBuilder( this.fqtn ); + tmp.append(this.sourceCluster); + tmp.append(this.targetCluster); + + return tmp.toString().hashCode(); + } + private static boolean xeq(String s1, String s2) { + if (s1 == null) { + return(s2 == null); + } else { + return(s1.equals(s2)); + } + } + public boolean equals(Object o) { + if (o == this) { + return(true); + } + if (!(o instanceof ReplicationVector)) { + return(false); + } + ReplicationVector x = (ReplicationVector)o; + return(xeq(fqtn, x.fqtn) && xeq(sourceCluster, x.sourceCluster) && xeq(targetCluster, x.targetCluster)); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/model/Topic.java b/src/main/java/org/openecomp/dmaapbc/model/Topic.java new file mode 100644 index 0000000..3d9ea6f --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/model/Topic.java @@ -0,0 +1,165 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.model; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.service.DmaapService; + + +@XmlRootElement +public class Topic extends DmaapObject { + static final Logger logger = Logger.getLogger(Topic.class); + + private String fqtn; + private String topicName; + private String topicDescription; + // I don't think this field is needed for this object. Rather, it applies to each MR_Client + //private String dcaeLocationName; + private String tnxEnabled; + private String owner; + private String formatUuid; + + private ArrayList clients; + + + + private static Dmaap dmaap = new DmaapService().getDmaap(); + + // + // utility function to generate the FQTN of a topic + public static String genFqtn( String name ) { + String ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + name; + return ret; + } + + + + public Topic() { + super(); + this.clients = new ArrayList(); + this.lastMod = new Date(); + this.setLastMod(); + logger.info( "Topic constructor " + this.lastMod ); + } + public Topic(String fqtn, String topicName, String topicDescription, + String tnxEnabled, String owner) { + super(); + this.fqtn = fqtn; + this.topicName = topicName; + this.topicDescription = topicDescription; + //this.dcaeLocationName = dcaeLocationName; + this.tnxEnabled = tnxEnabled; + this.owner = owner; + this.setLastMod(); + this.setStatus( DmaapObject_Status.NEW ); + logger.info( "Topic constructor " + this.getLastMod() ); + } + public String getFqtn() { + return fqtn; + } + public void setFqtn(String fqtn) { + this.fqtn = fqtn; + } + public String getTopicName() { + return topicName; + } + public void setTopicName(String topicName) { + this.topicName = topicName; + } + public String getTopicDescription() { + return topicDescription; + } + public void setTopicDescription(String topicDescription) { + this.topicDescription = topicDescription; + } + /* + public String getDcaeLocationName() { + return dcaeLocationName; + } + public void setDcaeLocationName(String dcaeLocationName) { + this.dcaeLocationName = dcaeLocationName; + } + */ + public String getTnxEnabled() { + return tnxEnabled; + } + public void setTnxEnabled(String tnxEnabled) { + this.tnxEnabled = tnxEnabled; + } + public String getOwner() { + return owner; + } + public void setOwner(String owner) { + this.owner = owner; + } + + + public void setClients(ArrayList clients) { + this.clients = clients; + } + + public ArrayList getClients() { + return clients; + } + + public int getNumClients() { + if ( this.clients == null ) { + return 0; + } + return this.clients.size(); + } + + + + + public String getFormatUuid() { + return formatUuid; + } + + + + public void setFormatUuid(String formatUuid) { + this.formatUuid = formatUuid; + } + + + + public String toProvJSON() { + StringBuilder str = new StringBuilder(); + str.append("{ \"topicName\": \""); + str.append( this.getFqtn() ); + str.append( "\", \"topicDescription\": \""); + str.append( this.getTopicDescription()); + str.append( "\", \"partitionCount\": \"2\", \"replicationCount\": \"1\" } "); + logger.info( str.toString() ); + return str.toString(); + } + + public byte[] getBytes() { + return toProvJSON().getBytes(StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/ApiResource.java b/src/main/java/org/openecomp/dmaapbc/resources/ApiResource.java new file mode 100644 index 0000000..a2a9e71 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/ApiResource.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.core.Response.Status; + +import org.openecomp.dmaapbc.model.ApiError; + +//TODO: Retire this class +public class ApiResource { + + static void checkRequired( String name, Object val, String expr, ApiError err ) throws RequiredFieldException { + if ( val == null ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("missing required field"); + err.setFields( name ); + throw new RequiredFieldException(); + } + + + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/BridgeResource.java b/src/main/java/org/openecomp/dmaapbc/resources/BridgeResource.java new file mode 100644 index 0000000..0c5782a --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/BridgeResource.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +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 javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.BrTopic; +import org.openecomp.dmaapbc.model.MirrorMaker; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.MirrorMakerService; + +@Path("/bridge") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class BridgeResource { + + static final Logger logger = Logger.getLogger(BridgeResource.class); + + private MirrorMakerService mmService = new MirrorMakerService(); + + @GET + public Response getBridgedTopics(@QueryParam("source") String source, + @QueryParam("target") String target, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + ApiService check = new ApiService(); + BrTopic brTopic = new BrTopic(); + + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + + logger.info( "getBridgeTopics():" + " source=" + source + ", target=" + target); +// System.out.println("getBridgedTopics() " + "source=" + source + ", target=" + target ); + if (source != null && target != null) { // get topics between 2 bridged locations + brTopic.setBrSource(source); + brTopic.setBrTarget(target); + MirrorMaker mm = mmService.getMirrorMaker(source, target); + if ( mm != null ) { + brTopic.setTopicCount( mm.getTopicCount() ); + } + + logger.info( "topicCount [2 locations]: " + brTopic.getTopicCount() ); + } + else if (source == null && target == null ) { + List mmList = mmService.getAllMirrorMakers(); + brTopic.setBrSource("all"); + brTopic.setBrTarget("all"); + int totCnt = 0; + for( String key: mmList ) { + int mCnt = 0; + MirrorMaker mm = mmService.getMirrorMaker(key); + if ( mm != null ) { + mCnt = mm.getTopicCount(); + } + logger.info( "Count for "+ key + ": " + mCnt); + totCnt += mCnt; + } + + logger.info( "topicCount [all locations]: " + totCnt ); + brTopic.setTopicCount(totCnt); +// System.out.println("BridgeResource() d.getBrSource()=" + d.getBrSource()); + } + else { +// System.out.println("A source or target Parameter is missing"); +// return Response.serverError().build(); + logger.error( "source or target is missing"); + return Response.status(Status.BAD_REQUEST) + .entity( "Either 2 locations or no location must be provided") + .build(); + } + return Response.ok(brTopic). + build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/DR_NodeResource.java b/src/main/java/org/openecomp/dmaapbc/resources/DR_NodeResource.java new file mode 100644 index 0000000..73506f6 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/DR_NodeResource.java @@ -0,0 +1,183 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.DR_Node; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.DR_NodeService; + +@Path("/dr_nodes") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class DR_NodeResource extends ApiResource { + static final Logger logger = Logger.getLogger(DR_NodeResource.class); + DR_NodeService dr_nodeService = new DR_NodeService(); + + @GET + public List getDr_Nodes(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + return dr_nodeService.getAllDr_Nodes(); + } + + @POST + public Response addDr_Node( DR_Node node, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "dcaeLocation", node.getDcaeLocationName(), ""); + resp.required( "fqdn", node.getFqdn(), ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST).entity( resp ).build(); + } + DR_Node nNode = dr_nodeService.addDr_Node(node, resp.getErr()); + if ( resp.getErr().is2xx()) { + return Response.status(Status.OK.getStatusCode()) + .entity(nNode) + .build(); + } + return Response.status( resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @PUT + @Path("/{fqdn}") + public Response updateDr_Node( @PathParam("fqdn") String name, DR_Node node, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "dcaeLocation", name, ""); + resp.required( "fqdn", node.getFqdn(), ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST).entity( resp ).build(); + } + node.setFqdn(name); + DR_Node nNode = dr_nodeService.updateDr_Node(node, resp.getErr()); + if ( resp.getErr().is2xx()) { + return Response.status(Status.OK.getStatusCode()) + .entity(nNode) + .build(); + } + return Response.status( resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @DELETE + @Path("/{fqdn}") + public Response deleteDr_Node( @PathParam("fqdn") String name, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + + ApiService resp = new ApiService(); + + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "fqdn", name, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST).entity( resp ).build(); + } + dr_nodeService.removeDr_Node(name, resp.getErr()); + if ( resp.getErr().is2xx() ) { + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + return Response.status( resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @GET + @Path("/{fqdn}") + public Response get( @PathParam("fqdn") String name, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + DR_Node nNode = dr_nodeService.getDr_Node( name, resp.getErr() ); + if ( resp.getErr().is2xx() ) { + return Response.status(Status.OK.getStatusCode()) + .entity(nNode) + .build(); + } + return Response.status( resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/DR_PubResource.java b/src/main/java/org/openecomp/dmaapbc/resources/DR_PubResource.java new file mode 100644 index 0000000..108a18b --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/DR_PubResource.java @@ -0,0 +1,270 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.DR_PubService; +import org.openecomp.dmaapbc.service.FeedService; + + +@Path("/dr_pubs") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class DR_PubResource extends ApiResource { + static final Logger logger = Logger.getLogger(DR_PubResource.class); + DR_PubService dr_pubService = new DR_PubService(); + + @GET + public List getDr_Pubs(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + logger.info( "Entry: GET /dr_pubs"); + return dr_pubService.getAllDr_Pubs(); + } + + @POST + public Response addDr_Pub( DR_Pub pub, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + logger.info( "Entry: POST /dr_pubs"); + ApiError err = new ApiError(); + try { + checkRequired( "feedId", pub.getFeedId(), "", err); + checkRequired( "dcaeLocationName", pub.getDcaeLocationName(), "", err); + } catch ( RequiredFieldException rfe ) { + logger.debug( err.toString() ); + return Response.status(Status.BAD_REQUEST).entity( err ).build(); + } + + FeedService feeds = new FeedService(); + Feed fnew = feeds.getFeed( pub.getFeedId(), err); + if ( fnew == null ) { + logger.info( "Specified feed " + pub.getFeedId() + " not known to Bus Controller"); + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + + ArrayList pubs = fnew.getPubs(); + logger.info( "num existing pubs before = " + pubs.size() ); +/* + DR_Pub pnew = new DR_Pub( pub.getDcaeLocationName()); + pnew.setFeedId(pub.getFeedId()); + pnew.setPubId(pub.getPubId()); + String tmp = pub.getUsername(); + if ( tmp != null ) { + pub.setUsername(tmp); + } + tmp = pub.getUserpwd(); + if ( tmp != null ) { + pub.setUserpwd(tmp); + } + pnew.setNextPubId(); +*/ + + + logger.info( "update feed"); + pub.setNextPubId(); + if ( pub.getUsername() == null ) { + pub.setRandomUserName(); + } + if ( pub.getUserpwd() == null ) { + pub.setRandomPassword(); + } + pubs.add( pub ); + fnew.setPubs(pubs); + fnew = feeds.updateFeed( fnew, err ); + + if ( ! err.is2xx()) { + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + pubs = fnew.getPubs(); + logger.info( "num existing pubs after = " + pubs.size() ); + + DR_Pub pnew = dr_pubService.getDr_Pub(pub.getPubId(), err); + return Response.status(Status.CREATED.getStatusCode()) + .entity(pnew) + .build(); + } + + @PUT + @Path("/{pubId}") + public Response updateDr_Pub( @PathParam("pubId") String name, DR_Pub pub, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + logger.info( "Entry: PUT /dr_pubs"); + pub.setPubId(name); + DR_Pub res = dr_pubService.updateDr_Pub(pub); + return Response.ok() + .entity(res) + .build(); + } + + @DELETE + @Path("/{pubId}") + public Response deleteDr_Pub( @PathParam("pubId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + logger.info( "Entry: DELETE /dr_pubs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + ApiError err = new ApiError(); + try { + checkRequired( "feedId", id, "", err); + } catch ( RequiredFieldException rfe ) { + logger.debug( err.toString() ); + return Response.status(Status.BAD_REQUEST).entity( err ).build(); + } + + DR_Pub pub = dr_pubService.getDr_Pub( id, err ); + if ( ! err.is2xx()) { + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + FeedService feeds = new FeedService(); + Feed fnew = feeds.getFeed( pub.getFeedId(), err); + if ( fnew == null ) { + logger.info( "Specified feed " + pub.getFeedId() + " not known to Bus Controller"); + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + ArrayList pubs = fnew.getPubs(); + if ( pubs.size() == 1 ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage( "Can't delete the last publisher of a feed"); + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + Iterator i = pubs.iterator(); + while( i.hasNext() ) { + DR_Pub listItem = i.next(); + if ( listItem.getPubId().equals(id)) { + pubs.remove( listItem ); + } + } + fnew.setPubs(pubs); + fnew = feeds.updateFeed( fnew, err ); + if ( ! err.is2xx()) { + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + + dr_pubService.removeDr_Pub(id, err); + if ( ! err.is2xx()) { + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + + @GET + @Path("/{pubId}") + public Response get( @PathParam("pubId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + ApiError err = new ApiError(); + try { + checkRequired( "feedId", id, "", err); + } catch ( RequiredFieldException rfe ) { + logger.debug( err.toString() ); + return Response.status(Status.BAD_REQUEST).entity( err ).build(); + } + logger.info( "Entry: GET /dr_pubs"); + DR_Pub pub = dr_pubService.getDr_Pub( id, err ); + if ( ! err.is2xx()) { + return Response.status(err.getCode()) + .entity( err ) + .build(); + } + return Response.status(Status.OK.getStatusCode()) + .entity(pub) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/DR_SubResource.java b/src/main/java/org/openecomp/dmaapbc/resources/DR_SubResource.java new file mode 100644 index 0000000..e0b42ce --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/DR_SubResource.java @@ -0,0 +1,253 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + + + + + + + + + + + + + + + + + + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.DR_Sub; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.DR_SubService; +import org.openecomp.dmaapbc.service.FeedService; + + +@Path("/dr_subs") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class DR_SubResource extends ApiResource { + static final Logger logger = Logger.getLogger(DR_SubResource.class); + + + @GET + public List getDr_Subs(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info( "Entry: GET /dr_subs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + DR_SubService dr_subService = new DR_SubService(); + return dr_subService.getAllDr_Subs(); + } + + @POST + public Response addDr_Sub( DR_Sub sub, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info( "Entry: POST /dr_subs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + + try { + resp.required( "feedId", sub.getFeedId(), ""); + resp.required( "dcaeLocationName", sub.getDcaeLocationName(), ""); + + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST) + .entity( resp.getErr() ) + .build(); + } + + FeedService feeds = new FeedService(); + Feed fnew = feeds.getFeed( sub.getFeedId(), resp.getErr() ); + if ( fnew == null ) { + logger.warn( "Specified feed " + sub.getFeedId() + " not known to Bus Controller"); + return Response.status( resp.getErr().getCode() ) + .entity( resp.getErr() ) + .build(); + } + + DR_SubService dr_subService = new DR_SubService( fnew.getSubscribeURL()); + ArrayList subs = fnew.getSubs(); + logger.info( "num existing subs before = " + subs.size() ); + DR_Sub snew = dr_subService.addDr_Sub(sub, resp.getErr() ); + if ( ! resp.getErr().is2xx() ) { + return Response.status( resp.getErr().getCode() ) + .entity( resp.getErr() ) + .build(); + } + subs.add( snew ); + logger.info( "num existing subs after = " + subs.size() ); + + fnew.setSubs(subs); + logger.info( "update feed"); + //feeds.updateFeed( fnew, err ); + + return Response.status(Status.CREATED) + .entity(snew) + .build(); + + } + + @PUT + @Path("/{subId}") + public Response updateDr_Sub( @PathParam("subId") String name, DR_Sub sub, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info( "Entry: PUT /dr_subs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + + try { + resp.required( "subId", name, ""); + resp.required( "feedId", sub.getFeedId(), ""); + resp.required( "dcaeLocationName", sub.getDcaeLocationName(), ""); + + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST) + .entity( resp.getErr() ) + .build(); + } + DR_SubService dr_subService = new DR_SubService(); + sub.setSubId(name); + DR_Sub nsub = dr_subService.updateDr_Sub(sub, resp.getErr() ); + if ( nsub != null && nsub.isStatusValid() ) { + return Response.status(Status.OK) + .entity(nsub) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity(resp.getErr()) + .build(); + } + + @DELETE + @Path("/{subId}") + public Response deleteDr_Sub( @PathParam("subId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + logger.info( "Entry: DELETE /dr_subs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + + try { + resp.required( "subId", id, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST.getStatusCode()) + .entity( resp.getErr() ) + .build(); + } + DR_SubService dr_subService = new DR_SubService(); + dr_subService.removeDr_Sub(id, resp.getErr() ); + if ( ! resp.getErr().is2xx() ) { + return Response.status( resp.getErr().getCode() ) + .entity( resp.getErr() ) + .build(); + } + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + + @GET + @Path("/{subId}") + public Response get( @PathParam("subId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info( "Entry: GET /dr_subs"); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + + try { + resp.required( "subId", id, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST.getStatusCode()) + .entity( resp.getErr() ) + .build(); + } + DR_SubService dr_subService = new DR_SubService(); + DR_Sub sub = dr_subService.getDr_Sub( id, resp.getErr() ); + if ( sub != null && sub.isStatusValid() ) { + return Response.status(Status.OK.getStatusCode()) + .entity(sub) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity(resp.getErr()) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/DcaeLocationResource.java b/src/main/java/org/openecomp/dmaapbc/resources/DcaeLocationResource.java new file mode 100644 index 0000000..9d158fa --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/DcaeLocationResource.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.PathSegment; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; + + + +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.DcaeLocationService; + + +@Path("/dcaeLocations") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class DcaeLocationResource { + static final Logger logger = Logger.getLogger(DcaeLocationResource.class); + DcaeLocationService locationService = new DcaeLocationService(); + + @GET + public List getDcaeLocations( @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //check.unavailable(); + } + return locationService.getAllDcaeLocations(); + } + + @POST + public Response addDcaeLocation( DcaeLocation location, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + if ( locationService.getDcaeLocation(location.getDcaeLocationName()) != null ) { + ApiError err = new ApiError(); + + err.setCode(Status.CONFLICT.getStatusCode()); + err.setMessage("dcaeLocation already exists"); + err.setFields("dcaeLocation"); + + logger.warn( err ); + return Response.status(Status.CONFLICT).entity( err ).build(); + + + } + DcaeLocation loc = locationService.addDcaeLocation(location); + return Response.status(Status.CREATED) + .entity(loc) + .build(); + } + + @PUT + @Path("/{locationName}") + public Response updateDcaeLocation( @PathParam("locationName") String name, DcaeLocation location, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + location.setDcaeLocationName(name); + if ( locationService.getDcaeLocation(location.getDcaeLocationName()) == null ) { + ApiError err = new ApiError(); + + err.setCode(Status.NOT_FOUND.getStatusCode()); + err.setMessage("dcaeLocation does not exist"); + err.setFields("dcaeLocation"); + + logger.warn( err ); + return Response.status(Status.NOT_FOUND).entity( err ).build(); + + + } + DcaeLocation loc = locationService.updateDcaeLocation(location); + return Response.status(Status.CREATED) + .entity(loc) + .build(); + } + + @DELETE + @Path("/{locationName}") + public Response deleteDcaeLocation( @PathParam("locationName") String name, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + locationService.removeDcaeLocation(name); + return Response.status(Status.NO_CONTENT).build(); + } + + @GET + @Path("/{locationName}") + public Response getDcaeLocation( @PathParam("locationName") String name, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService check = new ApiService(); + try { + //List segments = uriInfo.getPathSegments(); + check.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + DcaeLocation loc = locationService.getDcaeLocation( name ); + if ( loc == null ) { + ApiError err = new ApiError(); + + err.setCode(Status.NOT_FOUND.getStatusCode()); + err.setMessage("dcaeLocation does not exist"); + err.setFields("dcaeLocation"); + + logger.warn( err ); + return Response.status(Status.NOT_FOUND).entity( err ).build(); + + + } + + return Response.status(Status.OK) + .entity(loc) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/DmaapResource.java b/src/main/java/org/openecomp/dmaapbc/resources/DmaapResource.java new file mode 100644 index 0000000..03c731f --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/DmaapResource.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +// +// $Id$ + +package org.openecomp.dmaapbc.resources; + + + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +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 javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.Dmaap; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.DmaapService; + + + +@Path("/dmaap") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class DmaapResource { + static final Logger logger = Logger.getLogger(DmaapResource.class); + + DmaapService dmaapService = new DmaapService(); + + @GET + public Response getDmaap(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + logger.debug( "Entry: GET " + uriInfo.getPath() ); + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + Dmaap d = dmaapService.getDmaap(); + return Response.ok(d) + .build(); + } + + @POST + public Response addDmaap( Dmaap obj,@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + try { //check for required fields + check.required( "dmaapName", obj.getDmaapName(), "^\\S+$" ); //no white space allowed in dmaapName + check.required( "dmaapProvUrl", obj.getDrProvUrl(), "" ); + check.required( "topicNsRoot", obj.getTopicNsRoot(), "" ); + check.required( "bridgeAdminTopic", obj.getBridgeAdminTopic(), "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + + Dmaap d = dmaapService.addDmaap(obj); + if ( d == null ) { + return Response.status(Status.NOT_FOUND) + .build(); + + } + + return Response.ok(d) + .build(); + } + + @PUT + public Response updateDmaap( Dmaap obj, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + try { //check for required fields + check.required( "dmaapName", obj.getDmaapName(), "^\\S+$" ); //no white space allowed in dmaapName + check.required( "dmaapProvUrl", obj.getDrProvUrl(), "" ); + check.required( "topicNsRoot", obj.getTopicNsRoot(), "" ); + check.required( "bridgeAdminTopic", obj.getBridgeAdminTopic(), "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + Dmaap d = dmaapService.updateDmaap(obj); + if ( d != null ) { + return Response.ok(d) + .build(); + } else { + return Response.status(Status.NOT_FOUND) + .build(); + } + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/FeedResource.java b/src/main/java/org/openecomp/dmaapbc/resources/FeedResource.java new file mode 100644 index 0000000..b1dcd57 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/FeedResource.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.List; + +import javax.jws.WebParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; + +import org.apache.log4j.Logger; + + + + + + + + + + + + + + + + + + + +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.FeedService; + + +@Path("/feeds") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class FeedResource extends ApiResource { + static final Logger logger = Logger.getLogger(FeedResource.class); + + + @GET + public List getFeeds(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.debug( "Entry: GET " + uriInfo.getPath() ); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + FeedService feedService = new FeedService(); + List nfeeds = feedService.getAllFeeds(); +// tried this: http://www.adam-bien.com/roller/abien/entry/jax_rs_returning_a_list +// but still didn't seem to work... +// GenericEntity> list = new GenericEntity>(nfeeds){}; +// return Response.status(Status.OK) +// .entity( list ) +// .build(); + return nfeeds; + } + + + + @POST + public Response addFeed( @WebParam(name = "feed") Feed feed , @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + logger.debug( "Entry: POST " + uriInfo.getPath()); + + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "feedName", feed.getFeedName(), ""); + resp.required( "feedVersion", feed.getFeedVersion(), ""); + resp.required( "owner", feed.getOwner(), "" ); + resp.required( "asprClassification", feed.getAsprClassification(), "" ); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST).entity( resp ).build(); + } + + FeedService feedService = new FeedService(); + Feed nfeed = feedService.addFeed( feed, resp.getErr() ); + if ( nfeed != null ) { + return Response.status(Status.OK) + .entity(nfeed) + .build(); + } else { + logger.error( "Unable to create: " + feed.getFeedName() + ":" + feed.getFeedVersion()); + + return Response.status(resp.getErr().getCode()) + .entity( resp ) + .build(); + } + } + + @PUT + @Path("/{id}") + public Response updateFeed( @PathParam("id") String id, Feed feed, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.debug( "Entry: PUT " + uriInfo.getPath()); + + FeedService feedService = new FeedService(); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "feedId", id, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(Status.BAD_REQUEST.getStatusCode()).entity( resp ).build(); + } + + Feed nfeed = feedService.getFeed( id, resp.getErr() ); + if ( nfeed == null ) { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + // we assume there is no updates allowed for pubs and subs objects via this api... + // need to update any fields supported by PUT but preserve original field values. + nfeed.setSuspended(feed.isSuspended()); + nfeed.setFeedDescription(feed.getFeedDescription()); + nfeed.setFormatUuid(feed.getFormatUuid()); + + nfeed = feedService.updateFeed(nfeed, resp.getErr()); + if ( nfeed != null ) { + return Response.status(Status.OK) + .entity(nfeed) + .build(); + } else { + logger.info( "Unable to update: " + feed.getFeedName() + ":" + feed.getFeedVersion()); + + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + } + + @DELETE + @Path("/{id}") + public Response deleteFeed( @PathParam("id") String id, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ){ + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + logger.debug( "Entry: DELETE " + uriInfo.getPath()); + FeedService feedService = new FeedService(); + feedService.removeFeed(id); + return Response.status(Status.NO_CONTENT) + .build(); + } + + @GET + @Path("/{id}") + public Response getFeed( @PathParam("id") String id, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + logger.debug( "Entry: GET " + uriInfo.getPath()); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + FeedService feedService = new FeedService(); + Feed nfeed = feedService.getFeed( id, resp.getErr() ); + if ( nfeed == null ) { + return Response.status(Status.NOT_FOUND).entity( resp.getErr() ).build(); + } + return Response.status(Status.OK) + .entity(nfeed) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/MR_ClientResource.java b/src/main/java/org/openecomp/dmaapbc/resources/MR_ClientResource.java new file mode 100644 index 0000000..7acc0a4 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/MR_ClientResource.java @@ -0,0 +1,267 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.MR_Client; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.MR_ClientService; +import org.openecomp.dmaapbc.service.MR_ClusterService; +import org.openecomp.dmaapbc.service.TopicService; + + +@Path("/mr_clients") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class MR_ClientResource extends ApiResource { + static final Logger logger = Logger.getLogger(MR_ClientResource.class); + private MR_ClientService mr_clientService = new MR_ClientService(); + + @GET + public List getMr_Clients(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + return mr_clientService.getAllMr_Clients(); + } + + @POST + public Response addMr_Client( MR_Client client, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "fqtn", client.getFqtn(), ""); + resp.required( "dcaeLocationName", client.getDcaeLocationName(), ""); + resp.required( "clientRole", client.getClientRole(), "" ); + resp.required( "action", client.getAction(), ""); + + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + MR_ClusterService clusters = new MR_ClusterService(); + + MR_Cluster cluster = clusters.getMr_Cluster(client.getDcaeLocationName(), resp.getErr()); + if ( cluster == null ) { + ApiError err = resp.getErr(); + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage( "MR_Cluster alias not found for dcaeLocation: " + client.getDcaeLocationName()); + err.setFields("dcaeLocationName"); + logger.warn( err.getMessage() ); + return Response.status(err.getCode()).entity( err ).build(); + } + String url = cluster.getFqdn(); + if ( url == null || url.isEmpty() ) { + ApiError err = resp.getErr(); + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("FQDN not set for dcaeLocation " + client.getDcaeLocationName() ); + err.setFields("fqdn"); + logger.warn( err.getMessage() ); + return Response.status(err.getCode()).entity( err ).build(); + } + TopicService topics = new TopicService(); + ApiError err = resp.getErr(); + Topic t = topics.getTopic(client.getFqtn(), err); + if ( t == null ) { + return Response.status(err.getCode()).entity( err ).build(); + } + MR_Client nClient = mr_clientService.addMr_Client(client, t, err); + if ( err.is2xx()) { + int n; + ArrayList tc = t.getClients(); + if ( tc == null ) { + n = 0; + tc = new ArrayList(); + } else { + n = tc.size(); + } + logger.info( "number of existing clients for topic is " + n ); + + + logger.info( "n=" + n + " tc=" + tc + " client=" + client ); + tc.add( client ); + t.setClients(tc); + topics.updateTopic( t ); + return Response.ok(nClient) + .build(); + } + else { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + } + + @PUT + @Path("/{clientId}") + public Response updateMr_Client( @PathParam("clientId") String clientId, MR_Client client, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "fqtn", client.getFqtn(), ""); + resp.required( "dcaeLocationName", client.getDcaeLocationName(), ""); + resp.required( "clientRole", client.getClientRole(), "" ); + resp.required( "action", client.getAction(), ""); + + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + client.setMrClientId(clientId); + MR_Client nClient = mr_clientService.updateMr_Client(client, resp.getErr() ); + if ( resp.getErr().is2xx()) { + return Response.ok(nClient) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @DELETE + @Path("/{subId}") + public Response deleteMr_Client( @PathParam("subId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "clientId", id, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + MR_Client client = mr_clientService.removeMr_Client(id, resp.getErr() ); + if ( resp.getErr().is2xx()) { + TopicService topics = new TopicService(); + ApiError err = resp.getErr(); + Topic t = topics.getTopic(client.getFqtn(), err); + if ( t == null ) { + logger.info( err.getMessage() ); + return Response.status(err.getCode()).entity( err ).build(); + } + + ArrayList tc = t.getClients(); + for( MR_Client c: tc) { + if ( c.getMrClientId().equals(id)) { + tc.remove(c); + break; + } + } + t.setClients(tc); + topics.updateTopic( t ); + + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @GET + @Path("/{subId}") + public Response test( @PathParam("subId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "clientId", id, ""); + } catch ( RequiredFieldException rfe ) { + logger.debug( resp.toString() ); + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + MR_Client nClient = mr_clientService.getMr_Client( id, resp.getErr() ); + if ( resp.getErr().is2xx()) { + return Response.ok(nClient) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/MR_ClusterResource.java b/src/main/java/org/openecomp/dmaapbc/resources/MR_ClusterResource.java new file mode 100644 index 0000000..a7b8f37 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/MR_ClusterResource.java @@ -0,0 +1,195 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.MR_ClusterService; + + +@Path("/mr_clusters") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class MR_ClusterResource { + static final Logger logger = Logger.getLogger(MR_ClusterResource.class); + + MR_ClusterService mr_clusterService = new MR_ClusterService(); + + @GET + public List getMr_Clusters(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; //resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //resp.unavailable(); + } + return mr_clusterService.getAllMr_Clusters(); + } + + @POST + public Response addMr_Cluster( MR_Cluster cluster, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info("Entry: /POST" ); + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "dcaeLocationName", cluster.getDcaeLocationName(), "" ); + resp.required( "fqdn", cluster.getFqdn(), "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + MR_Cluster mrc = mr_clusterService.addMr_Cluster(cluster, resp.getErr() ); + if ( mrc != null && mrc.isStatusValid() ) { + return Response.status(Status.CREATED) + .entity(mrc) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity(resp.getErr()) + .build(); + + } + + @PUT + @Path("/{clusterId}") + public Response updateMr_Cluster( @PathParam("clusterId") String clusterId, MR_Cluster cluster, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "PUT"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "fqdn", clusterId, "" ); + resp.required( "dcaeLocationName", cluster.getDcaeLocationName(), "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + cluster.setDcaeLocationName(clusterId); + MR_Cluster mrc = mr_clusterService.updateMr_Cluster(cluster, resp.getErr() ); + if ( mrc != null && mrc.isStatusValid() ) { + return Response.status(Status.CREATED) + .entity(mrc) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity(resp.getErr()) + .build(); + } + + @DELETE + @Path("/{clusterId}") + public Response deleteMr_Cluster( @PathParam("clusterId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth){ + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "fqdn", id, "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + mr_clusterService.removeMr_Cluster(id, resp.getErr() ); + if ( resp.getErr().is2xx()) { + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + + @GET + @Path("/{clusterId}") + public Response getMR_Cluster( @PathParam("clusterId") String id, + @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + ApiService resp = new ApiService(); + try { + resp.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return resp.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return resp.unavailable(); + } + try { + resp.required( "dcaeLocationName", id, "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(resp.getErr().getCode()) + .entity( resp.getErr() ) + .build(); + } + MR_Cluster mrc = mr_clusterService.getMr_Cluster( id, resp.getErr() ); + if ( mrc != null && mrc.isStatusValid() ) { + return Response.status(Status.CREATED) + .entity(mrc) + .build(); + } + return Response.status(resp.getErr().getCode()) + .entity(resp.getErr()) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/RequiredFieldException.java b/src/main/java/org/openecomp/dmaapbc/resources/RequiredFieldException.java new file mode 100644 index 0000000..081e086 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/RequiredFieldException.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +public class RequiredFieldException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/org/openecomp/dmaapbc/resources/TopicResource.java b/src/main/java/org/openecomp/dmaapbc/resources/TopicResource.java new file mode 100644 index 0000000..5d4b9a7 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/resources/TopicResource.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.resources; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.service.ApiService; +import org.openecomp.dmaapbc.service.TopicService; + +@Path("/topics") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class TopicResource { + + static final Logger logger = Logger.getLogger(TopicResource.class); + + TopicService mr_topicService = new TopicService(); + + @GET + public List getTopics(@Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info("Entry: /GET" ); + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return null; // check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return null; //check.unavailable(); + } + return mr_topicService.getAllTopics(); + } + + @POST + public Response addTopic( Topic topic, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + logger.info("Entry: /POST" ); + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPath(), "POST"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + try { + check.required( "topicName", topic.getTopicName(), "^\\S+$" ); //no white space allowed in topicName + check.required( "topicDescription", topic.getTopicDescription(), "" ); + check.required( "owner", topic.getOwner(), "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + //String fqtn = Topic.genFqtn(topic.getTopicName()); + ApiError err = check.getErr(); + + topic.setLastMod(); + + Topic mrc = mr_topicService.addTopic(topic, err); + if ( mrc != null && mrc.isStatusValid() ) { + return Response.status(Status.CREATED) + .entity(mrc) + .build(); + } + return Response.status(err.getCode()) + .entity(err) + .build(); + + } + + @PUT + @Path("/{topicId}") + public Response updateTopic( @PathParam("topicId") String topicId, Topic topic, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ) { + logger.info("Entry: /PUT " + topic ); + ApiError err = new ApiError(); + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage( "Method /PUT not supported for /topics"); + + return Response.status(err.getCode()) + .entity( err ) + .build(); + //return mr_topicService.updateTopic(topic); + } + + @DELETE + @Path("/{topicId}") + public Response deleteTopic( @PathParam("topicId") String id, @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth ){ + logger.info("Entry: /DELETE " + id ); + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "DELETE"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + try { + check.required( "fqtn", id, "" ); + } catch( RequiredFieldException rfe ) { + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + + Topic topic = mr_topicService.removeTopic(id, check.getErr()); + if ( check.getErr().is2xx()) { + return Response.status(Status.NO_CONTENT.getStatusCode()) + .build(); + } + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + + + @GET + @Path("/{topicId}") + public Response getTopic( @PathParam("topicId") String id , @Context UriInfo uriInfo, @HeaderParam("Authorization") String basicAuth) { + logger.info("Entry: /GET " + id); + ApiService check = new ApiService(); + try { + check.checkAuthorization( basicAuth, uriInfo.getPathSegments().get(0).getPath(), "GET"); + } catch ( AuthenticationErrorException ae ) { + return check.unauthorized(); + } catch ( Exception e ) { + logger.error( "Unexpected exception " + e ); + return check.unavailable(); + } + try { + check.required( "topicName", id, "^\\S+$" ); //no white space allowed in topicName + } catch( RequiredFieldException rfe ) { + return Response.status(check.getErr().getCode()) + .entity( check.getErr() ) + .build(); + } + Topic mrc = mr_topicService.getTopic( id, check.getErr() ); + if ( mrc == null ) { + return Response.status(check.getErr().getCode()) + .entity(check.getErr()) + .build(); + } + return Response.ok(mrc) + .build(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/server/JettyServer.java b/src/main/java/org/openecomp/dmaapbc/server/JettyServer.java new file mode 100644 index 0000000..cef19a8 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/server/JettyServer.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.server; + + +import java.util.Properties; + +import javax.net.ssl.SSLContext; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +/** + * A Jetty server which supports: + * - http and https (simultaneously for dev env) + * - REST API context + * - static html pages (for documentation). + */ +public class JettyServer { + + static final Logger logger = Logger.getLogger(JettyServer.class); + + public JettyServer( Properties params ) throws Exception { + + Server server = new Server(); + int httpPort = Integer.valueOf(params.getProperty("IntHttpPort", "80" )); + int sslPort = Integer.valueOf(params.getProperty("IntHttpsPort", "443" )); + boolean allowHttp = Boolean.valueOf(params.getProperty("HttpAllowed", "false")); + logger.info( "port params: http=" + httpPort + " https=" + sslPort ); + logger.info( "allowHttp=" + allowHttp ); + + // HTTP Server + + HttpConfiguration http_config = new HttpConfiguration(); + http_config.setSecureScheme("https"); + http_config.setSecurePort(sslPort); + http_config.setOutputBufferSize(32768); + + + + ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(http_config)); + httpConnector.setPort(httpPort); + httpConnector.setIdleTimeout(30000); + + + // HTTPS Server + + HttpConfiguration https_config = new HttpConfiguration(http_config); + https_config.addCustomizer(new SecureRequestCustomizer()); + SslContextFactory sslContextFactory = new SslContextFactory(); + String keystore = params.getProperty("KeyStoreFile", "etc/keystore"); + logger.info( "https Server using keystore at " + keystore ); + String keystorePwd = params.getProperty( "KeyStorePassword", "changeit"); + String keyPwd = params.getProperty("KeyPassword", "changeit"); + + + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword(keystorePwd); + sslContextFactory.setKeyManagerPassword(keyPwd); + + + ServerConnector sslConnector = null; + if ( sslPort != 0 ) { + sslConnector = new ServerConnector(server, + new SslConnectionFactory(sslContextFactory, "http/1.1"), + new HttpConnectionFactory(https_config)); + sslConnector.setPort(sslPort); + if ( allowHttp ) { + logger.info("Starting httpConnector on port " + httpPort ); + logger.info("Starting sslConnector on port " + sslPort + " for https"); + server.setConnectors( new Connector[] { httpConnector, sslConnector }); + } else { + logger.info("NOT starting httpConnector because HttpAllowed param is " + allowHttp ); + logger.info("Starting sslConnector on port " + sslPort + " for https"); + server.setConnectors( new Connector[] { sslConnector }); + } + } + else { + logger.info("NOT starting sslConnector on port " + sslPort + " for https"); + if ( allowHttp ) { + logger.info("Starting httpConnector on port " + httpPort ); + server.setConnectors( new Connector[] { httpConnector }); + } + } + + // Set context for servlet. This is shared for http and https + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + server.setHandler( context ); + + ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, "/webapi/*"); + jerseyServlet.setInitOrder(1); + jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "org.openecomp.dmaapbc.resources" ); + + // also serve up some static pages... + ServletHolder staticServlet = context.addServlet(DefaultServlet.class,"/*"); + staticServlet.setInitParameter("resourceBase","www"); + staticServlet.setInitParameter("pathInfoOnly","true"); + + try { + + logger.info("Starting jetty server"); + server.start(); + server.dumpStdErr(); + server.join(); + } catch ( Exception e ) { + logger.error( "Exception " + e ); + logger.error( "possibly unable to use keystore " + keystore + " with passwords " + keystorePwd + " and " + keyPwd ); + //System.exit(1); + } finally { + server.destroy(); + } + + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/server/Main.java b/src/main/java/org/openecomp/dmaapbc/server/Main.java new file mode 100644 index 0000000..2143670 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/server/Main.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.server; + +import java.io.FileInputStream; +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.openecomp.dmaapbc.util.DmaapConfig; + +public class Main { + + private Properties parameters; + private static String provFQDN; + + public static String getProvFQDN() { + return provFQDN; + } + public void setProvFQDN(String provFQDN) { + Main.provFQDN = provFQDN; + } + private Main() { + } + public static void main(String[] args) throws Exception { + (new Main()).main(); + } + + static final Logger logger = Logger.getLogger(Main.class); + private void main() { + String log = System.getProperty( "log4j.configuration"); + if ( log.isEmpty() ) { + log = "log4j.properties"; + } + PropertyConfigurator.configure( log ); + logger.info("Started."); + parameters = DmaapConfig.getConfig(); + setProvFQDN( parameters.getProperty("ProvFQDN", "ProvFQDN.notset.com")); + + + try { + //new JettyServer( Integer.valueOf(parameters.getProperty("IntHttpPort", "80" )), + // Integer.valueOf(parameters.getProperty("IntHttpsPort","443"))); + new JettyServer( parameters ); + } catch (Exception e) { + logger.fatal("Unable to start Jetty " + DmaapConfig.getConfigFileName(), e); + System.exit(1); + } + + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/ApiService.java b/src/main/java/org/openecomp/dmaapbc/service/ApiService.java new file mode 100644 index 0000000..8690bb0 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/ApiService.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.bind.DatatypeConverter; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.aaf.DmaapPerm; +import org.openecomp.dmaapbc.authentication.AuthenticationErrorException; +import org.openecomp.dmaapbc.authentication.DecisionPolicy; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.Dmaap; +import org.openecomp.dmaapbc.resources.RequiredFieldException; +import org.openecomp.dmaapbc.util.DmaapConfig; + +public class ApiService { + static final Logger logger = Logger.getLogger(ApiService.class); + static private String apiNamespace; + static private boolean usePE; + + private ApiError err; + + public ApiService() { + err = new ApiError(); + + if (apiNamespace == null) { + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + usePE = "true".equalsIgnoreCase(p.getProperty("UsePE", "false")); + apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api"); + } + + } + + + public ApiError getErr() { + return err; + } + + + public void setErr(ApiError err) { + this.err = err; + } + + + // test for presence of a required field + public void required( String name, Object val, String expr ) throws RequiredFieldException { + if ( val == null ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("missing required field"); + err.setFields( name ); + throw new RequiredFieldException(); + } + if ( expr != null && ! expr.isEmpty() ) { + Pattern pattern = Pattern.compile(expr); + Matcher matcher = pattern.matcher((CharSequence) val); + if ( ! matcher.find() ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage( "value '" + val + "' violates regexp check '" + expr + "'"); + err.setFields( name ); + throw new RequiredFieldException(); + } + } + } + + // utility to serialize ApiErr object + public String toString() { + return String.format( "code=%d msg=%s fields=%s", err.getCode(), err.getMessage(), err.getFields() ); + } + + + public void setCode(int statusCode) { + err.setCode(statusCode); + } + + + public void setMessage(String string) { + err.setMessage(string); + } + + + public void setFields(String string) { + err.setFields(string); + } + + private Response buildResponse() { + return Response.status( err.getCode()) + .entity(getErr()) + .build(); + } + public Response response(int statusCode) { + err.setCode(statusCode); + return buildResponse(); + } + public Response unauthorized() { + err.setCode(Status.UNAUTHORIZED.getStatusCode()); + err.setFields( "Authorization"); + err.setMessage( "User credentials in HTTP Header field Authorization are not authorized for the requested action"); + return buildResponse(); + } + public Response unavailable() { + err.setCode(Status.SERVICE_UNAVAILABLE.getStatusCode()); + err.setMessage( "Request is unavailable due to unexpected condition"); + return buildResponse(); + } + + public void checkAuthorization( String authorization, String uriPath, String method ) throws AuthenticationErrorException, Exception { + if ( ! usePE ) return; // skip authorization if not enabled + if ( authorization == null || authorization.isEmpty()) { + String errmsg = "No basic authorization value provided "; + logger.info( errmsg ); + throw new AuthenticationErrorException( ); + } + if ( uriPath == null || uriPath.isEmpty()) { + String errmsg = "No URI value provided "; + logger.info( errmsg ); + throw new AuthenticationErrorException( ); + } + if ( method == null || method.isEmpty()) { + String errmsg = "No method value provided "; + logger.info( errmsg ); + throw new AuthenticationErrorException( ); + } + DmaapService dmaapService = new DmaapService(); + Dmaap dmaap = dmaapService.getDmaap(); + String env = dmaap.getDmaapName(); + + // special case during bootstrap of app when DMaaP environment may not be set. + // this allows us to authorize certain APIs used for initialization during this window. + if ( env.isEmpty() ) { + env = "boot"; + } + + String credentials = authorization.substring("Basic".length()).trim(); + byte[] decoded = DatatypeConverter.parseBase64Binary(credentials); + String decodedString = new String(decoded); + String[] actualCredentials = decodedString.split(":"); + String ID = actualCredentials[0]; + String Password = actualCredentials[1]; + +logger.info( "User " + ID + " allowed - DecisionPolicy() not compiled in yet!" ); +/* disable until PolicyEngine avail... + try { + DecisionPolicy d = new DecisionPolicy(); + DmaapPerm p = new DmaapPerm( apiNamespace + "." + uriPath, env, method ); + d.check( ID, Password, p); + } catch ( AuthenticationErrorException ae ) { + logger.info( "User " + ID + " failed authentication/authorization"); + throw ae; + + } +*/ + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/DR_NodeService.java b/src/main/java/org/openecomp/dmaapbc/service/DR_NodeService.java new file mode 100644 index 0000000..c1e36aa --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/DR_NodeService.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Node; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class DR_NodeService { + static final Logger logger = Logger.getLogger(DR_NodeService.class); + private Map dr_nodes = DatabaseClass.getDr_nodes(); + + public Map getDr_Nodes() { + return dr_nodes; + } + + public List getAllDr_Nodes() { + return new ArrayList(dr_nodes.values()); + } + + public DR_Node getDr_Node( String fqdn, ApiError apiError ) { + DR_Node old = dr_nodes.get( fqdn ); + if ( old == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "fqdn"); + apiError.setMessage( "Node " + fqdn + " does not exist"); + return null; + } + apiError.setCode(200); + return old; + } + + public DR_Node addDr_Node( DR_Node node, ApiError apiError ) { + String fqdn = node.getFqdn(); + DR_Node old = dr_nodes.get( fqdn ); + if ( old != null ) { + apiError.setCode(Status.CONFLICT.getStatusCode()); + apiError.setFields( "fqdn"); + apiError.setMessage( "Node " + fqdn + " already exists"); + return null; + } + node.setLastMod(); + node.setStatus(DmaapObject_Status.VALID); + dr_nodes.put( node.getFqdn(), node ); + apiError.setCode(200); + return node; + } + + public DR_Node updateDr_Node( DR_Node node, ApiError apiError ) { + DR_Node old = dr_nodes.get( node ); + if ( old == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "fqdn"); + apiError.setMessage( "Node " + node + " does not exist"); + return null; + } + node.setLastMod(); + dr_nodes.put( node.getFqdn(), node ); + apiError.setCode(200); + return node; + } + + public DR_Node removeDr_Node( String nodeName, ApiError apiError ) { + DR_Node old = dr_nodes.get( nodeName ); + if ( old == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "fqdn"); + apiError.setMessage( "Node " + nodeName + " does not exist"); + return null; + } + apiError.setCode(200); + return dr_nodes.remove(nodeName); + } + + public String getNodePatternAtLocation( String loc ) { + logger.info( "loc=" + loc ); + if ( loc == null ) { + return null; + } + StringBuilder str = new StringBuilder(); + for( DR_Node node : dr_nodes.values() ) { + if ( loc.equals( node.getDcaeLocationName()) ) { + if ( str.length() > 0 ) { + str.append( ","); + } + str.append( node.getFqdn()); + } + } + logger.info( "returning " + str.toString() ); + return str.toString(); + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/DR_PubService.java b/src/main/java/org/openecomp/dmaapbc/service/DR_PubService.java new file mode 100644 index 0000000..8479e55 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/DR_PubService.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.client.DrProvConnection; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class DR_PubService { + static final Logger logger = Logger.getLogger(DR_PubService.class); + private Map dr_pubs = DatabaseClass.getDr_pubs(); + private DR_NodeService nodeService = new DR_NodeService(); + private static DrProvConnection prov; + + public DR_PubService() { + super(); + prov = new DrProvConnection(); + } + + public Map getDr_Pubs() { + return dr_pubs; + } + + public List getAllDr_Pubs() { + return new ArrayList(dr_pubs.values()); + } + + public ArrayList getDr_PubsByFeedId( String feedId ) { + ArrayList somePubs = new ArrayList(); + for( DR_Pub pub : dr_pubs.values() ) { + if ( feedId.equals( pub.getFeedId() )) { + somePubs.add( pub ); + } + } + + return somePubs; + } + + public DR_Pub getDr_Pub( String key, ApiError err ) { + DR_Pub pub = dr_pubs.get( key ); + if ( pub == null ) { + err.setCode(Status.NOT_FOUND.getStatusCode()); + err.setFields( "pubId"); + err.setMessage("DR_Pub with pubId = " + key + " not found"); + } else { + err.setCode(Status.OK.getStatusCode()); + } + return pub; + } + + private void addIngressRoute( DR_Pub pub, ApiError err ) { + + String nodePattern = nodeService.getNodePatternAtLocation( pub.getDcaeLocationName()); + if ( nodePattern != null && nodePattern.length() > 0 ) { + logger.info( "creating ingress rule: pub " + pub.getPubId() + " on feed " + pub.getFeedId() + " to " + nodePattern); + prov.makeIngressConnection( pub.getFeedId(), pub.getUsername(), "-", nodePattern); + int rc = prov.doIngressPost(err); + logger.info( "rc=" + rc + " error code=" + err.getCode() ); + + if ( rc != 200 ) { + switch( rc ) { + case 403: + logger.error( "Not authorized for DR ingress API"); + err.setCode(500); + err.setMessage("API deployment/configuration error - contact support"); + err.setFields( "PROV_AUTH_ADDRESSES"); + break; + + default: + logger.warn( "unable to create ingress rule for " + pub.getPubId() + " on feed " + pub.getFeedId() + " to " + nodePattern); + } + } + + } + } + + public DR_Pub addDr_Pub( DR_Pub pub ) { + ApiError err = new ApiError(); + if ( pub.getPubId() != null && ! pub.getPubId().isEmpty() ) { + addIngressRoute( pub, err); + if ( err.getCode() > 0 ) { + pub.setStatus(DmaapObject_Status.INVALID); + } + pub.setLastMod(); + dr_pubs.put( pub.getPubId(), pub ); + return pub; + } + else { + return null; + } + } + + public DR_Pub updateDr_Pub( DR_Pub pub ) { + if ( pub.getPubId().isEmpty()) { + return null; + } + pub.setLastMod(); + dr_pubs.put( pub.getPubId(), pub ); + return pub; + } + + public DR_Pub removeDr_Pub( String pubId, ApiError err ) { + + DR_Pub pub = dr_pubs.get( pubId ); + if ( pub == null ) { + err.setCode(Status.NOT_FOUND.getStatusCode()); + err.setFields( "pubId"); + err.setMessage( "pubId " + pubId + " not found"); + } else { + dr_pubs.remove(pubId); + err.setCode(Status.OK.getStatusCode()); + } + return pub; + + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/DR_SubService.java b/src/main/java/org/openecomp/dmaapbc/service/DR_SubService.java new file mode 100644 index 0000000..a360cff --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/DR_SubService.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.client.DrProvConnection; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.DR_Sub; +import org.openecomp.dmaapbc.model.Feed; + +public class DR_SubService { + static final Logger logger = Logger.getLogger(DR_SubService.class); + private Map dr_subs = DatabaseClass.getDr_subs(); + private String provURL; + //private DrProvConnection prov; + + public DR_SubService( ) { + logger.info( "Entry: DR_SubService (with no args)" ); +// prov = new DrProvConnection(); + + } + public DR_SubService( String subURL ) { + logger.info( "Entry: DR_SubService " + subURL ); + provURL = subURL; +// prov = new DrProvConnection(); +// prov.makeSubConnection( subURL ); + } + public Map getDR_Subs() { + logger.info( "enter getDR_Subs()"); + return dr_subs; + } + + public List getAllDr_Subs() { + logger.info( "enter getAllDR_Subs()"); + return new ArrayList(dr_subs.values()); + } + + public ArrayList getDr_SubsByFeedId( String pubId ) { + ArrayList someSubs = new ArrayList(); + for( DR_Sub sub : dr_subs.values() ) { + if ( pubId.equals( sub.getFeedId() )) { + someSubs.add( sub ); + } + } + + return someSubs; + } + public DR_Sub getDr_Sub( String key, ApiError apiError ) { + logger.info( "enter getDR_Sub()"); + DR_Sub sub = dr_subs.get( key ); + if ( sub == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "subId"); + apiError.setMessage("subId " + key + " not found"); + } else { + apiError.setCode(200); + } + return sub; + } + + public DR_Sub addDr_Sub( DR_Sub sub, ApiError apiError ) { + logger.info( "enter addDR_Subs()"); + DrProvConnection prov = new DrProvConnection(); + prov.makeSubConnection( provURL ); + String resp = prov.doPostDr_Sub( sub ); + logger.info( "resp=" + resp ); + + DR_Sub snew = null; + + if ( resp != null ) { + snew = new DR_Sub( resp ); + snew.setDcaeLocationName(sub.getDcaeLocationName()); + snew.setLastMod(); + dr_subs.put( snew.getSubId(), snew ); + apiError.setCode(200); + } else { + apiError.setCode(400); + } + + return snew; + } + + + public DR_Sub updateDr_Sub( DR_Sub obj, ApiError apiError ) { + logger.info( "enter updateDR_Subs()"); + + DR_Sub sub = dr_subs.get( obj.getSubId() ); + if ( sub == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "subId"); + apiError.setMessage("subId " + obj.getSubId() + " not found"); + return null; + } + sub.setLastMod(); + dr_subs.put( sub.getSubId(), sub ); + apiError.setCode(200); + return sub; + } + + public void removeDr_Sub( String key, ApiError apiError ) { + logger.info( "enter removeDR_Subs()"); + DR_Sub sub = dr_subs.get( key ); + if ( sub == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "subId"); + apiError.setMessage("subId " + key + " not found"); + } else { + dr_subs.remove(key); + apiError.setCode(200); + } + + return; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/DcaeLocationService.java b/src/main/java/org/openecomp/dmaapbc/service/DcaeLocationService.java new file mode 100644 index 0000000..f88852a --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/DcaeLocationService.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + + + + + + + +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class DcaeLocationService { + + private Map dcaeLocations = DatabaseClass.getDcaeLocations(); + + public Map getDcaeLocations() { + return dcaeLocations; + } + + public List getAllDcaeLocations() { + return new ArrayList(dcaeLocations.values()); + } + + public DcaeLocation getDcaeLocation( String name ) { + return dcaeLocations.get(name); + } + + public DcaeLocation addDcaeLocation( DcaeLocation location ) { + location.setLastMod(); + location.setStatus(DmaapObject_Status.VALID); + dcaeLocations.put( location.getDcaeLocationName(), location ); + return location; + } + + public DcaeLocation updateDcaeLocation( DcaeLocation location ) { + if ( location.getDcaeLocationName().isEmpty()) { + return null; + } + location.setLastMod(); + dcaeLocations.put( location.getDcaeLocationName(), location ); + return location; + } + + public DcaeLocation removeDcaeLocation( String locationName ) { + return dcaeLocations.remove(locationName); + } + + public String getCentralLocation() { + for( Map.Entry entry: dcaeLocations.entrySet() ) { + DcaeLocation loc = entry.getValue(); + if ( loc.isCentral() ) { + // use the name of the first central location we hit + return loc.getDcaeLocationName(); + } + + } + return "aCentralLocation"; // default value that is obvious to see is wrong + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/DmaapService.java b/src/main/java/org/openecomp/dmaapbc/service/DmaapService.java new file mode 100644 index 0000000..47cc271 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/DmaapService.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.aaf.AafService; +import org.openecomp.dmaapbc.aaf.DmaapGrant; +import org.openecomp.dmaapbc.aaf.DmaapPerm; +import org.openecomp.dmaapbc.aaf.AafService.ServiceType; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.model.Dmaap; +import org.openecomp.dmaapbc.model.MR_Client; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; +import org.openecomp.dmaapbc.util.DmaapConfig; +import org.openecomp.dmaapbc.util.Singleton; + +public class DmaapService { + static final Logger logger = Logger.getLogger(DmaapService.class); + + private Singleton dmaapholder = DatabaseClass.getDmaap(); + + // TODO put these in properties file + String topicFactory = "org.openecomp.dcae.dmaap.topicFactory"; + String topicMgrRole = "org.openecomp.dmaapBC.TopicMgr"; + + // TODO confirm this is equivalent to dmaap.getTopicNsRoot() so we can retire it + String dcaeTopicNs = "org.openecomp.dcae.dmaap"; + + + public DmaapService() { + + } + + public Dmaap getDmaap() { + logger.info( "entering getDmaap()" ); + return(dmaapholder.get()); + } + + public Dmaap addDmaap( Dmaap nd ) { + + logger.info( "entering addDmaap()" ); + Dmaap dmaap = dmaapholder.get(); + if ( dmaap.getVersion().equals( "0")) { + + nd.setLastMod(); + dmaapholder.update(nd); + + AafService aaf = new AafService( ServiceType.AAF_Admin); + + boolean anythingWrong = setTopicMgtPerms( nd, aaf ) || createMmaTopic(); + + if ( anythingWrong ) { + dmaap.setStatus(DmaapObject_Status.INVALID); + } + else { + dmaap.setStatus(DmaapObject_Status.VALID); + } + + + return dmaap; + + } + else { + return dmaap; + } + } + + public Dmaap updateDmaap( Dmaap nd ) { + logger.info( "entering updateDmaap()" ); + + boolean anythingWrong = false; + AafService aaf = new AafService( ServiceType.AAF_Admin); + Dmaap dmaap = dmaapholder.get(); + + // some triggers for when we attempt to reprovision perms and MMA topic: + // - if the DMaaP Name changes + // - if the version is 0 (this is a handy test to force this processing by updating the DB) + // - if the object is invalid, reprocessing might fix it. + if ( ! dmaap.isStatusValid() || ! nd.getDmaapName().equals(dmaap.getDmaapName()) || dmaap.getVersion().equals( "0") ) { + nd.setLastMod(); + dmaapholder.update(nd); //need to set this so the following perms will pick up any new vals. + anythingWrong = setTopicMgtPerms( nd, aaf ) || createMmaTopic(); + } + + if ( anythingWrong ) { + nd.setStatus(DmaapObject_Status.INVALID); + } + else { + nd.setStatus(DmaapObject_Status.VALID); + } + nd.setLastMod(); + dmaapholder.update(nd); // may need to update status... + return(dmaapholder.get()); + + } + + public String getTopicPerm(){ + Dmaap dmaap = dmaapholder.get(); + return getTopicPerm( dmaap.getDmaapName() ); + } + public String getTopicPerm( String val ) { + Dmaap dmaap = dmaapholder.get(); + return dmaap.getTopicNsRoot() + "." + val + ".mr.topic"; + } + + public String getBridgeAdminFqtn(){ + Dmaap dmaap = dmaapholder.get(); + return(dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + dmaap.getBridgeAdminTopic()); + } + + private boolean setTopicMgtPerms( Dmaap nd, AafService aaf ){ + String[] actions = { "create", "destroy" }; + String instance = ":" + dcaeTopicNs + "." + nd.getDmaapName() + ".mr.topic:" + dcaeTopicNs + "." + nd.getDmaapName(); + + for( String action : actions ) { + + DmaapPerm perm = new DmaapPerm( topicFactory, instance, action ); + + int rc = aaf.addPerm( perm ); + if ( rc != 201 && rc != 409 ) { + logger.error( "unable to add perm for "+ topicFactory + "|" + instance + "|" + action ); + return true; + } + + DmaapGrant grant = new DmaapGrant( perm, topicMgrRole ); + rc = aaf.addGrant( grant ); + if ( rc != 201 && rc != 409 ) { + logger.error( "unable to grant to " + topicMgrRole + " perm for "+ topicFactory + "|" + instance + "|" + action ); + return true; + } + } + + String t = dcaeTopicNs +"." + nd.getDmaapName() + ".mr.topic"; + String[] s = { "view", "pub", "sub" }; + actions = s; + instance = "*"; + + for( String action : actions ) { + + DmaapPerm perm = new DmaapPerm( t, instance, action ); + + int rc = aaf.addPerm( perm ); + if ( rc != 201 && rc != 409 ) { + logger.error( "unable to add perm for "+ t + "|" + instance + "|" + action ); + return true; + } + + DmaapGrant grant = new DmaapGrant( perm, topicMgrRole ); + rc = aaf.addGrant( grant ); + if ( rc != 201 && rc != 409 ) { + logger.error( "unable to grant to " + topicMgrRole + " perm for "+ topicFactory + "|" + instance + "|" + action ); + return true; + } + + } + return false; + } + + // create the special topic for MMA provisioning. + // return true indicating a problem in topic creation, + // else false means it was ok (created or previously existed) + private boolean createMmaTopic() { + boolean rc = true; + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + Dmaap dmaap = dmaapholder.get(); + + ArrayList clients = new ArrayList(); + String[] actions = { "pub", "sub", "view" }; + String centralMR = new DcaeLocationService().getCentralLocation(); + if ( centralMR == null ) { + return rc; + } + logger.info( "Location for " + dmaap.getBridgeAdminTopic() + " is " + centralMR ); + + // first client is the Role used by Bus Controller to send messages to MMA + String provRole = p.getProperty("MM.ProvRole"); + MR_Client nClient = new MR_Client(); + nClient.setAction(actions); + nClient.setClientRole(provRole); + nClient.setDcaeLocationName(centralMR); + clients.add( nClient ); + + // second client is the Role used by MMA to listen to messages from Bus Controller + String agentRole = p.getProperty("MM.AgentRole"); + nClient = new MR_Client(); + nClient.setAction(actions); + nClient.setClientRole(agentRole); + nClient.setDcaeLocationName(centralMR); + clients.add( nClient ); + + // initialize Topic + Topic mmaTopic = new Topic(); + mmaTopic.setTopicName(dmaap.getBridgeAdminTopic()); + mmaTopic.setClients(clients); + mmaTopic.setOwner("BusController"); + mmaTopic.setTopicDescription("topic reserved for MirrorMaker Administration"); + mmaTopic.setTnxEnabled("false"); + + ApiError err = new ApiError(); + TopicService svc = new TopicService(); + Topic nTopic = svc.addTopic(mmaTopic, err); + if ( err.is2xx() || err.getCode() == 409 ) { + return false; + } + logger.error( "Unable to create topic for " + dmaap.getBridgeAdminTopic() + " err=" + err.getFields() + " fields=" + err.getFields() + " msg=" + err.getMessage()); + + return rc; + + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/FeedService.java b/src/main/java/org/openecomp/dmaapbc/service/FeedService.java new file mode 100644 index 0000000..a9af116 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/FeedService.java @@ -0,0 +1,314 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.client.DrProvConnection; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DR_Pub; +import org.openecomp.dmaapbc.model.DR_Sub; +import org.openecomp.dmaapbc.model.Feed; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class FeedService { + static final Logger logger = Logger.getLogger(FeedService.class); + private Map feeds = DatabaseClass.getFeeds(); + private DR_PubService pubService = new DR_PubService(); + private DR_SubService subService = new DR_SubService(); + private DcaeLocationService dcaeLocations = new DcaeLocationService(); + public FeedService() { + logger.info( "new FeedService"); + + } + + public Map getFeeds() { + return feeds; + } + + private void getSubObjects( Feed f ) { + ArrayList pubs = pubService.getDr_PubsByFeedId( f.getFeedId() ); + f.setPubs(pubs); + ArrayList subs = subService.getDr_SubsByFeedId( f.getFeedId() ); + f.setSubs(subs); + } + + public List getAllFeeds() { + ArrayList fatFeeds = new ArrayList(); + for( Feed f: feeds.values() ) { + getSubObjects(f); + fatFeeds.add(f); + } + return fatFeeds; + } + + public Feed getFeed( String key, ApiError err ) { + Feed f = feeds.get( key ); + if ( f != null ) { + getSubObjects( f ); + } else { + err.setCode(Status.NOT_FOUND.getStatusCode()); + err.setMessage("feed not found"); + err.setFields("feedId=" + key ); + } + err.setCode(200); + return f; + } + //TODO: clean this up after testing proves it is no longer needed + /* + private void saveChildren( Feed fnew, Feed req ) { + // save any pubs + DR_PubService pubSvc = new DR_PubService(); + ArrayList reqPubs = req.getPubs(); + ArrayList newPubs = fnew.getPubs(); + logger.info( "reqPubs size=" + reqPubs.size() + " newPubs size=" + newPubs.size() ); + + // NOTE: when i > 1 newPubs are in reverse order from reqPubs + int nSize = newPubs.size(); + int rSize = reqPubs.size(); + if ( nSize != rSize ) { + logger.error( "Resulting set of publishers do not match requested set of publishers " + nSize + " vs " + rSize ); + fnew.setStatus( DmaapObject_Status.INVALID); + return; + } + for( int i = 0; i < reqPubs.size(); i++ ) { + DR_Pub reqPub = reqPubs.get(i); + DR_Pub newPub = newPubs.get(nSize - i - 1); + + + // make sure to re-use original pubId if it exists + String origPubId = reqPub.getPubId(); + if ( origPubId != null && ! origPubId.isEmpty()) { + newPub.setPubId( origPubId ); + } + newPub.setDcaeLocationName(reqPub.getDcaeLocationName()); + + + newPubs.set( nSize - i - 1 , pubSvc.addDr_Pub( newPub )); + } + + // save any subs + ArrayList subs = req.getSubs(); + if ( subs.size() == 0 ) { + logger.info( "No subs specified"); + } else { + DR_SubService subSvc = new DR_SubService( fnew.getSubscribeURL() ); + ApiError err = new ApiError(); + for( int i = 0; i < subs.size(); i++ ) { + subs.set( i, subSvc.addDr_Sub(subs.get(i), err)); + } + fnew.setSubs(subs); + } + + + fnew.setStatus(DmaapObject_Status.VALID); + + } + */ + + private boolean savePubs( Feed f ) { + return savePubs( f, f ); + } + // need to save the Pub objects independently and copy pubId from original request + private boolean savePubs( Feed fnew, Feed req ) { + // save any pubs + DR_PubService pubSvc = new DR_PubService(); + ArrayList reqPubs = req.getPubs(); + ArrayList newPubs = fnew.getPubs(); + + + + int nSize = newPubs.size(); + int rSize = reqPubs.size(); + logger.info( "reqPubs size=" + rSize + " newPubs size=" + nSize ); + if ( nSize != rSize ) { + logger.error( "Resulting set of publishers do not match requested set of publishers " + nSize + " vs " + rSize ); + fnew.setStatus( DmaapObject_Status.INVALID); + return false; + } + // NOTE: when i > 1 newPubs are in reverse order from reqPubs + for( int i = 0; i < reqPubs.size(); i++ ) { + DR_Pub reqPub = reqPubs.get(i); + ApiError err = new ApiError(); + if ( pubSvc.getDr_Pub( reqPub.getPubId(), err ) == null ) { + DR_Pub newPub = newPubs.get(nSize - i - 1); + reqPub.setPubId(newPub.getPubId()); + reqPub.setFeedId(newPub.getFeedId()); + reqPub.setStatus(DmaapObject_Status.VALID); + if ( reqPub.getDcaeLocationName() == null ) { + reqPub.setDcaeLocationName("dcaeLocationNotSpecified"); + } + pubSvc.addDr_Pub( reqPub ); + } + + } + + fnew.setPubs(reqPubs); + fnew.setStatus(DmaapObject_Status.VALID); + return true; + + } + + private boolean saveSubs( Feed f ) { + return saveSubs( f, f ); + } + // need to save the Sub objects independently + private boolean saveSubs( Feed fnew, Feed req ) { + ArrayList subs = req.getSubs(); + if ( subs.size() == 0 ) { + logger.info( "No subs specified"); + } else { + DR_SubService subSvc = new DR_SubService( fnew.getSubscribeURL() ); + ApiError err = new ApiError(); + for( int i = 0; i < subs.size(); i++ ) { + DR_Sub sub = subs.get(i); + if ( subSvc.getDr_Sub( sub.getSubId(), err) == null ) { + subs.set( i, subSvc.addDr_Sub(sub, err)); + if ( ! err.is2xx()) { + logger.error( "i=" + i + " url=" + sub.getDeliveryURL() + " err=" + err.getCode() ); + return false; + } + } + + } + fnew.setSubs(subs); + } + + + fnew.setStatus(DmaapObject_Status.VALID); + return true; + + } + + public Feed addFeed( Feed req, ApiError err ) { + + // at least 1 pub is required by DR, so create a default pub if none is specified + if ( req.getPubs().size() == 0 ) { + logger.info( "No pubs specified - creating tmp pub"); + ArrayList pubs = new ArrayList(); + pubs.add( new DR_Pub( dcaeLocations.getCentralLocation()) + .setRandomUserName() + .setRandomPassword()); + req.setPubs(pubs); + } + + DrProvConnection prov = new DrProvConnection(); + prov.makeFeedConnection(); + String resp = prov.doPostFeed( req, err ); + logger.info( "resp=" + resp ); + if ( resp == null ) { + switch( err.getCode() ) { + case 400: + err.setFields( "feedName=" + req.getFeedName() + " + feedVersion=" + req.getFeedVersion() ); + break; + case 403: + err.setCode(500); + err.setMessage("API deployment/configuration error - contact support"); + err.setFields( "PROV_AUTH_ADDRESSES"); + logger.error( "Prov response: 403. " + err.getMessage() + " regarding " + err.getFields() ); + break; + default: + err.setCode(500); + err.setMessage( "Unexpected response from DR backend" ); + err.setFields("response"); + } + return null; + } + + + Feed fnew = new Feed( resp ); + logger.info( "fnew status is:" + fnew.getStatus() ); + if ( ! fnew.isStatusValid()) { + err.setCode(500); + err.setMessage( "Unexpected response from DR backend" ); + err.setFields("response"); + return null; + } + + //saveChildren( fnew, req ); + if ( ! savePubs( fnew, req ) || ! saveSubs( fnew, req ) ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("Unable to save Pub or Sub objects"); + return null; + } + fnew.setFormatUuid(req.getFormatUuid()); + fnew.setLastMod(); + feeds.put( fnew.getFeedId(), fnew ); + return fnew; + } + + public Feed updateFeed( Feed req, ApiError err ) { + + + DrProvConnection prov = new DrProvConnection(); + prov.makeFeedConnection( req.getFeedId() ); + String resp = prov.doPutFeed( req, err ); + logger.info( "resp=" + resp ); + if ( resp == null ) { + switch( err.getCode() ) { + case 400: + err.setFields( "feedName=" + req.getFeedName() + " + feedVersion=" + req.getFeedVersion() ); + break; + case 403: + err.setCode(500); + err.setMessage("API deployment/configuration error - contact support"); + err.setFields( "PROV_AUTH_ADDRESSES"); + break; + default: + err.setCode(500); + err.setMessage( "Unexpected response from DR backend" ); + err.setFields("response"); + } + return null; + } + + + Feed fnew = new Feed( resp ); + logger.info( "fnew status is:" + fnew.getStatus() ); + if ( ! fnew.isStatusValid()) { + err.setCode(500); + err.setMessage( "Unexpected response from DR backend" ); + err.setFields("response"); + return null; + } + + if ( ! savePubs( fnew, req ) || ! saveSubs( fnew, req ) ) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("Unable to save Pub or Sub objects"); + return null; + } + fnew.setFormatUuid(req.getFormatUuid()); + fnew.setLastMod(); + feeds.put( fnew.getFeedId(), fnew ); + return fnew; + } + + public Feed removeFeed( String pubId ) { + return feeds.remove(pubId); + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/MR_ClientService.java b/src/main/java/org/openecomp/dmaapbc/service/MR_ClientService.java new file mode 100644 index 0000000..ac4b5c8 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/MR_ClientService.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.aaf.AafService; +import org.openecomp.dmaapbc.aaf.DmaapGrant; +import org.openecomp.dmaapbc.aaf.DmaapPerm; +import org.openecomp.dmaapbc.aaf.AafService.ServiceType; +import org.openecomp.dmaapbc.client.MrProvConnection; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.MR_Client; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class MR_ClientService { + static final Logger logger = Logger.getLogger(MR_ClientService.class); + + private Map mr_clients = DatabaseClass.getMr_clients(); + private Map clusters = DatabaseClass.getMr_clusters(); + private Map topics = DatabaseClass.getTopics(); + private DmaapService dmaap = new DmaapService(); + + public Map getMR_Clients() { + return mr_clients; + } + + public List getAllMr_Clients() { + return new ArrayList(mr_clients.values()); + } + + public ArrayList getAllMrClients(String fqtn) { + ArrayList results = new ArrayList(); + for (Map.Entry entry : mr_clients.entrySet()) + { + MR_Client client = entry.getValue(); + if ( fqtn.equals(client.getFqtn() ) ) { + results.add( client ); + } + } + return results; + } + + + public MR_Client getMr_Client( String key, ApiError apiError ) { + MR_Client c = mr_clients.get( key ); + if ( c == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "mrClientId"); + apiError.setMessage("mrClientId " + key + " not found" ); + } else { + apiError.setCode(200); + } + return c; + } + + public MR_Client addMr_Client( MR_Client client, Topic topic, ApiError err ) { + if ( client.getDcaeLocationName().isEmpty()) { + logger.error( "Client dcaeLocation that doesn't exist or not specified" ); + return null; + } + MR_Cluster cluster = clusters.get( client.getDcaeLocationName()); + if ( cluster != null ) { + client.setTopicURL(cluster.genTopicURL(client.getFqtn())); + AafService aaf = new AafService(ServiceType.AAF_TopicMgr); + + String instance = ":topic." + client.getFqtn(); + client.setStatus( DmaapObject_Status.VALID); + for( String want : client.getAction() ) { + int rc; + DmaapPerm perm = new DmaapPerm( dmaap.getTopicPerm(), instance, want ); + DmaapGrant g = new DmaapGrant( perm, client.getClientRole() ); + rc = aaf.addGrant( g ); + if ( rc != 201 && rc != 409 ) { + client.setStatus( DmaapObject_Status.INVALID); + err.setCode(rc); + err.setMessage( "Grant of " + dmaap.getTopicPerm() + "|" + instance + "|" + want + " failed for " + client.getClientRole() ); + logger.warn( err.getMessage()); + return null; + } + } + + + logger.info( "cluster=" + cluster ); + MrProvConnection prov = new MrProvConnection(); + logger.info( "POST topic " + topic.getFqtn() + " to cluster " + cluster.getFqdn() + " in loc " + cluster.getDcaeLocationName()); + if ( prov.makeTopicConnection(cluster)) { + String resp = prov.doPostTopic(topic); + logger.info( "response: " + resp ); + if ( resp == null ) { + client.setStatus( DmaapObject_Status.INVALID); + } + } + + } else { + logger.info( "Client references a dcaeLocation that doesn't exist:" + client.getDcaeLocationName()); + client.setStatus( DmaapObject_Status.STAGED); + //return null; + } + + mr_clients.put( client.getMrClientId(), client ); + + + //TODO: this section on updating an existing topic with a new client needs to belong someplace else + //Topic t = topics.get(topic.getFqtn()); + /* + int n; + ArrayList tc = topic.getClients(); + if ( tc == null ) { + n = 0; + tc = new ArrayList(); + } else { + n = tc.size(); + } + logger.info( "number of existing clients for topic is " + n ); + + + logger.info( "n=" + n + " tc=" + tc + " client=" + client ); + tc.add( client ); + topic.setClients(tc); + */ + topics.put(topic.getFqtn(), topic); + err.setCode(200); + + return client; + } + + public MR_Client updateMr_Client( MR_Client client, ApiError apiError ) { + MR_Client c = mr_clients.get( client.getMrClientId()); + if ( c == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "mrClientId"); + apiError.setMessage("mrClientId " + client.getMrClientId() + " not found" ); + } else { + apiError.setCode(200); + } + mr_clients.put( client.getMrClientId(), client ); + return client; + } + + public MR_Client removeMr_Client( String key, ApiError apiError ) { + MR_Client c = mr_clients.get( key ); + if ( c == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "mrClientId"); + apiError.setMessage("mrClientId " + key + " not found" ); + } else { + apiError.setCode(200); + } + + return mr_clients.remove(key); + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/MR_ClusterService.java b/src/main/java/org/openecomp/dmaapbc/service/MR_ClusterService.java new file mode 100644 index 0000000..d5cb402 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/MR_ClusterService.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; + +public class MR_ClusterService { + static final Logger logger = Logger.getLogger(MR_ClusterService.class); + + private Map mr_clusters = DatabaseClass.getMr_clusters(); + + public Map getMR_Clusters() { + return mr_clusters; + } + + public List getAllMr_Clusters() { + return new ArrayList(mr_clusters.values()); + } + + public MR_Cluster getMr_Cluster( String key, ApiError apiError ) { + MR_Cluster mrc = mr_clusters.get( key ); + if ( mrc == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "dcaeLocationName"); + apiError.setMessage( "Cluster with dcaeLocationName " + key + " not found"); + } + apiError.setCode(200); + return mrc; + } + public MR_Cluster getMr_ClusterByFQDN( String key ) { + for( MR_Cluster cluster: mr_clusters.values() ) { + if ( key.equals( cluster.getFqdn() ) ) { + return cluster; + } + } + return null; + } + + public MR_Cluster addMr_Cluster( MR_Cluster cluster, ApiError apiError ) { + logger.info( "Entry: addMr_Cluster"); + MR_Cluster mrc = mr_clusters.get( cluster.getDcaeLocationName() ); + if ( mrc != null ) { + apiError.setCode(Status.CONFLICT.getStatusCode()); + apiError.setFields( "dcaeLocationName"); + apiError.setMessage( "Cluster with dcaeLocationName " + cluster.getDcaeLocationName() + " already exists"); + return null; + } + cluster.setLastMod(); + cluster.setStatus(DmaapObject_Status.VALID); + mr_clusters.put( cluster.getDcaeLocationName(), cluster ); + DcaeLocationService svc = new DcaeLocationService(); + DcaeLocation loc = svc.getDcaeLocation( cluster.getDcaeLocationName() ); + if ( loc != null && loc.isCentral() ) { + ApiError resp = TopicService.setBridgeClientPerms( cluster ); + if ( ! resp.is2xx() ) { + logger.error( "Unable to provision Bridge to " + cluster.getDcaeLocationName() ); + cluster.setLastMod(); + cluster.setStatus(DmaapObject_Status.INVALID); + mr_clusters.put( cluster.getDcaeLocationName(), cluster ); + } + } + apiError.setCode(200); + return cluster; + } + + public MR_Cluster updateMr_Cluster( MR_Cluster cluster, ApiError apiError ) { + MR_Cluster mrc = mr_clusters.get( cluster.getDcaeLocationName() ); + if ( mrc == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "dcaeLocationName"); + apiError.setMessage( "Cluster with dcaeLocationName " + cluster.getDcaeLocationName() + " not found"); + return null; + } + cluster.setLastMod(); + mr_clusters.put( cluster.getDcaeLocationName(), cluster ); + DcaeLocationService svc = new DcaeLocationService(); + DcaeLocation loc = svc.getDcaeLocation( cluster.getDcaeLocationName() ); + if ( loc.isCentral() ) { + ApiError resp = TopicService.setBridgeClientPerms( cluster ); + if ( ! resp.is2xx() ) { + logger.error( "Unable to provision Bridge to " + cluster.getDcaeLocationName() ); + cluster.setLastMod(); + cluster.setStatus(DmaapObject_Status.INVALID); + mr_clusters.put( cluster.getDcaeLocationName(), cluster ); + } + } + apiError.setCode(200); + return cluster; + } + + public MR_Cluster removeMr_Cluster( String key, ApiError apiError ) { + MR_Cluster mrc = mr_clusters.get( key ); + if ( mrc == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "dcaeLocationName"); + apiError.setMessage( "Cluster with dcaeLocationName " + key + " not found"); + return null; + } + apiError.setCode(200); + return mr_clusters.remove(key); + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/MirrorMakerService.java b/src/main/java/org/openecomp/dmaapbc/service/MirrorMakerService.java new file mode 100644 index 0000000..5d633b0 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/MirrorMakerService.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + + + + + + + + + + + + + +import org.openecomp.dmaapbc.aaf.AndrewDecryptor; +import org.openecomp.dmaapbc.client.MrTopicConnection; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.MirrorMaker; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; +import org.openecomp.dmaapbc.util.DmaapConfig; +import org.openecomp.dmaapbc.util.RandomInteger; + +public class MirrorMakerService { + static final Logger logger = Logger.getLogger(MirrorMakerService.class); + + private Map mirrors = DatabaseClass.getMirrorMakers(); + private static MrTopicConnection prov; + + public MirrorMakerService() { + super(); + // TODO Auto-generated constructor stub + } + + // will create a MM on MMagent if needed + // will update the MMagent whitelist with all topics for this MM + public MirrorMaker updateMirrorMaker( MirrorMaker mm ) { + logger.info( "updateMirrorMaker"); + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + String provUser = p.getProperty("MM.ProvUserMechId"); + String provUserPwd = AndrewDecryptor.valueOf(p.getProperty( "MM.ProvUserPwd", "notSet" )); + prov = new MrTopicConnection( provUser, provUserPwd ); + MR_ClusterService clusters = new MR_ClusterService(); + DmaapService dmaap = new DmaapService(); + //TODO: this should find the cluster!!!! + + MR_Cluster central = clusters.getMr_ClusterByFQDN(mm.getTargetCluster()); + if ( central != null ) { + prov.makeTopicConnection(central, dmaap.getBridgeAdminFqtn() ); + ApiError resp = prov.doPostMessage(mm.createMirrorMaker()); + if ( ! resp.is2xx() ) { + //logger.error( "Unable to publish MR Bridge provisioning message. rc=" + resp.getCode() + " msg=" + resp.getMessage()); + logger.error( "Unable to publish create MM provisioning message. rc=" + resp.getCode() + " msg=" + resp.getMessage()); + mm.setStatus(DmaapObject_Status.INVALID); + } else { + prov.makeTopicConnection(central, dmaap.getBridgeAdminFqtn() ); + resp = prov.doPostMessage(mm.updateWhiteList()); + if ( ! resp.is2xx()) { + logger.error( "Unable to publish MR Bridge provisioning message. rc=" + resp.getCode() + " msg=" + resp.getMessage()); + mm.setStatus(DmaapObject_Status.INVALID); + } else { + mm.setStatus(DmaapObject_Status.VALID); + } + } + + } else { + logger.warn( "target cluster " + mm.getTargetCluster() + " not found!"); + } + + mm.setLastMod(); + return mirrors.put( mm.getMmName(), mm); + } + public MirrorMaker getMirrorMaker( String part1, String part2 ) { + logger.info( "getMirrorMaker using " + part1 + " and " + part2 ); + return mirrors.get(MirrorMaker.genKey(part1, part2)); + } + public MirrorMaker getMirrorMaker( String key ) { + logger.info( "getMirrorMaker using " + key); + return mirrors.get(key); + } + + /*public MirrorMaker updateMirrorMaker( MirrorMaker mm ) { + logger.info( "updateMirrorMaker"); + return mirrors.put( mm.getMmName(), mm); + } + */ + + public void delMirrorMaker( MirrorMaker mm ) { + logger.info( "delMirrorMaker"); + mirrors.remove(mm.getMmName()); + } + + // TODO: this should probably return sequential values or get replaced by the MM client API + // but it should be sufficient for initial 1610 development + public static String genTransactionId() { + RandomInteger ri = new RandomInteger(100000); + int randomInt = ri.next(); + return Integer.toString(randomInt); + } + public List getAllMirrorMakers() { + List ret = new ArrayList(); + for( String key: mirrors.keySet()) { + ret.add( key ); + } + + return ret; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/service/TopicService.java b/src/main/java/org/openecomp/dmaapbc/service/TopicService.java new file mode 100644 index 0000000..0240fab --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/service/TopicService.java @@ -0,0 +1,240 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.log4j.Logger; +import org.openecomp.dmaapbc.aaf.AafService; +import org.openecomp.dmaapbc.aaf.DmaapPerm; +import org.openecomp.dmaapbc.aaf.AafService.ServiceType; +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.ApiError; +import org.openecomp.dmaapbc.model.Dmaap; +import org.openecomp.dmaapbc.model.MR_Client; +import org.openecomp.dmaapbc.model.MR_Cluster; +import org.openecomp.dmaapbc.model.MirrorMaker; +import org.openecomp.dmaapbc.model.Topic; +import org.openecomp.dmaapbc.model.DmaapObject.DmaapObject_Status; +import org.openecomp.dmaapbc.util.DmaapConfig; +import org.openecomp.dmaapbc.util.Graph; + +public class TopicService { + static final Logger logger = Logger.getLogger(TopicService.class); + + // TODO put these in properties file + String topicFactory = "org.openecomp.dcae.dmaap.topicFactory"; + + private Map mr_topics = DatabaseClass.getTopics(); + private Map clusters = DatabaseClass.getMr_clusters(); + + private Dmaap dmaap = new DmaapService().getDmaap(); + private MR_ClientService clientService = new MR_ClientService(); + private MirrorMakerService bridge = new MirrorMakerService(); + + + public Map getTopics() { + return mr_topics; + } + + public List getAllTopics() { + ArrayList topics = new ArrayList(mr_topics.values()); + for( Topic topic: topics ) { + topic.setClients( clientService.getAllMrClients(topic.getFqtn())); + } + return topics; + } + + + public Topic getTopic( String key, ApiError apiError ) { + logger.info( "getTopic: key=" + key); + Topic t = mr_topics.get( key ); + if ( t == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setFields( "fqtn"); + apiError.setMessage("topic with fqtn " + key + " not found"); + return null; + } + t.setClients( clientService.getAllMrClients( key )); + apiError.setCode(Status.OK.getStatusCode()); + return t; + } + + public Topic addTopic( Topic topic, ApiError err ) { + logger.info( "Entry: addTopic"); + String nFqtn = Topic.genFqtn( topic.getTopicName() ); + if ( getTopic( nFqtn, err ) != null ) { + String t = "topic already exists: " + nFqtn; + logger.info( t ); + err.setMessage( t ); + err.setFields( "fqtn"); + err.setCode(Status.CONFLICT.getStatusCode()); + return null; + } + logger.info( "fqtn: " + nFqtn ); + topic.setFqtn( nFqtn ); + + boolean anythingWrong = false; + AafService aaf = new AafService(ServiceType.AAF_TopicMgr); + String t = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + ".mr.topic"; + String instance = ":topic." + topic.getFqtn(); + + String[] actions = { "pub", "sub", "view" }; + for ( String action : actions ){ + DmaapPerm perm = new DmaapPerm( t, instance, action ); + int rc = aaf.addPerm( perm ); + if ( rc != 201 && rc != 409 ) { + err.setCode(500); + err.setMessage("Unexpected response from AAF:" + rc ); + err.setFields("t="+t + " instance="+ instance + " action="+ action); + return null; + } + } + + + if ( topic.getNumClients() > 0 ) { + ArrayList clients = new ArrayList(topic.getClients()); + + + ArrayList clients2 = new ArrayList(); + for ( Iterator it = clients.iterator(); it.hasNext(); ) { + MR_Client c = it.next(); + + logger.info( "c fqtn=" + c.getFqtn() + " ID=" + c.getMrClientId() + " url=" + c.getTopicURL()); + MR_Client nc = new MR_Client( c.getDcaeLocationName(), topic.getFqtn(), c.getClientRole(), c.getAction()); + nc.setFqtn(topic.getFqtn()); + logger.info( "nc fqtn=" + nc.getFqtn() + " ID=" + nc.getMrClientId() + " url=" + nc.getTopicURL()); + clients2.add( clientService.addMr_Client(nc, topic, err)); + if ( ! err.is2xx()) { + return null; + } + } + + topic.setClients(clients2); + Graph graph = new Graph( clients2 ); + + String centralFqdn = new String(); + if ( graph.isHasCentral() ) { + centralFqdn = clusters.get( graph.getCentralLoc() ).getFqdn(); + + } + + Collection locations = graph.getKeys(); + for( String loc : locations ) { + logger.info( "loc=" + loc ); + MR_Cluster cluster = clusters.get(loc); + logger.info( "cluster=" + cluster ); + + if ( graph.isHasCentral() && ! centralFqdn.equals(cluster.getFqdn())) { + logger.info( "Create a MM from " + cluster.getFqdn() + " to " + centralFqdn ); + try { + MirrorMaker mm = bridge.getMirrorMaker(cluster.getFqdn(), centralFqdn); + if ( mm == null ) { + mm = new MirrorMaker(cluster.getFqdn(), centralFqdn); + } + mm.addTopic(topic.getFqtn()); + bridge.updateMirrorMaker(mm); + } catch ( Exception ex ) { + err.setCode(500); + err.setFields( "mirror_maker.topic"); + err.setMessage("Unexpected condition: " + ex ); + anythingWrong = true; + break; + } + + } + + } + } + + if ( anythingWrong ) { + topic.setStatus( DmaapObject_Status.INVALID); + return null; + } + + topic.setStatus( DmaapObject_Status.VALID); + + mr_topics.put( nFqtn, topic ); + //String prov = bridge.commit(); + //logger.info( "prov=" + prov); + err.setCode(Status.OK.getStatusCode()); + return topic; + } + + + public Topic updateTopic( Topic topic ) { + if ( topic.getFqtn().isEmpty()) { + return null; + } + mr_topics.put( topic.getFqtn(), topic ); + return topic; + } + + public Topic removeTopic( String pubId, ApiError apiError ) { + if ( mr_topics.get(pubId) == null ) { + apiError.setCode(Status.NOT_FOUND.getStatusCode()); + apiError.setMessage("Topic " + pubId + " does not exist"); + apiError.setFields("fqtn"); + return null; + } + apiError.setCode(Status.OK.getStatusCode()); + return mr_topics.remove(pubId); + } + public static ApiError setBridgeClientPerms( MR_Cluster node ) { + DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); + String mmProvRole = p.getProperty("MM.ProvRole"); + String mmAgentRole = p.getProperty("MM.AgentRole"); + String[] Roles = { mmProvRole, mmAgentRole }; + String[] actions = { "view", "pub", "sub" }; + Topic bridgeAdminTopic = new Topic(); + bridgeAdminTopic.setTopicName( DatabaseClass.getDmaap().get().getBridgeAdminTopic()); + bridgeAdminTopic.setTopicDescription( "RESERVED topic for MirroMaker Provisioning"); + bridgeAdminTopic.setOwner( "DBC" ); + ArrayList clients = new ArrayList(); + for( String role: Roles ) { + MR_Client client = new MR_Client(); + client.setAction(actions); + client.setClientRole(role); + client.setDcaeLocationName( node.getDcaeLocationName()); + clients.add( client ); + } + bridgeAdminTopic.setClients(clients); + + TopicService ts = new TopicService(); + ApiError err = new ApiError(); + ts.addTopic(bridgeAdminTopic, err); + + if ( err.is2xx() || err.getCode() == 409 ){ + err.setCode(200); + return err; + } + + logger.error( "Unable to create MM provisioning topic " + bridgeAdminTopic.getFqtn()); + return err; + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/util/DmaapConfig.java b/src/main/java/org/openecomp/dmaapbc/util/DmaapConfig.java new file mode 100644 index 0000000..31c01b0 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/DmaapConfig.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +import java.io.*; +import java.util.*; + +public class DmaapConfig extends Properties { + /** + * + */ + private static final long serialVersionUID = 1L; + private static String configfname = System.getProperty("ConfigFile", "etc/dmaapbc.properties"); + private static Properties config = new DmaapConfig(); + public static Properties getConfig() { + return(config); + } + public static String getConfigFileName() { + return(configfname); + } + private DmaapConfig() { + try { + InputStream is = new FileInputStream(configfname); + load(is); + is.close(); + } catch (Exception e) { + System.err.println("Unable to load configuration file " + configfname); + org.apache.log4j.Logger.getLogger(getClass()).fatal("Unable to load configuration file " + configfname, e); + System.exit(1); + } + } +} diff --git a/src/main/java/org/openecomp/dmaapbc/util/DmaapTimestamp.java b/src/main/java/org/openecomp/dmaapbc/util/DmaapTimestamp.java new file mode 100644 index 0000000..080773f --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/DmaapTimestamp.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +import java.util.Calendar; +import java.util.Date; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.log4j.Logger; + +@XmlRootElement +public class DmaapTimestamp { + static final Logger logger = Logger.getLogger(DmaapTimestamp.class); + private static Calendar cal = Calendar.getInstance(); + private Date stamp; + + public DmaapTimestamp() { + + stamp = cal.getTime(); + logger.info("constructor: set val to " + stamp); + } + + public void mark() { + stamp = cal.getTime(); + logger.info("mark: set val to " + stamp); + } + + public Date getVal() { + return stamp; + } + +} diff --git a/src/main/java/org/openecomp/dmaapbc/util/Graph.java b/src/main/java/org/openecomp/dmaapbc/util/Graph.java new file mode 100644 index 0000000..bdb1f6e --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/Graph.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.dmaapbc.database.DatabaseClass; +import org.openecomp.dmaapbc.model.DcaeLocation; +import org.openecomp.dmaapbc.model.MR_Client; + + +public class Graph { + private HashMap graph; + private boolean hasCentral; + + private Map locations = DatabaseClass.getDcaeLocations(); + + //TODO add to properties file + private static String centralDcaeLayerName = "central"; + + public Graph() { + } + public Graph(HashMap graph) { + super(); + this.graph = graph; + } + + public Graph( List clients ) { + if ( clients == null ) + return; + this.graph = new HashMap(); + this.hasCentral = false; + for( MR_Client client: clients ) { + if ( client.isStatusValid()) { + String loc = client.getDcaeLocationName(); + for( String action : client.getAction() ){ + DcaeLocation dcaeLoc = locations.get(loc); + if ( ! action.equals("view") && dcaeLoc != null ) { + graph.put(loc, dcaeLoc.getDcaeLayer()); + } + } + String layer = graph.get(loc); + if ( layer != null && layer.contains(centralDcaeLayerName) ) { + this.hasCentral = true; + } + + } + } + } + + public HashMap getGraph() { + return graph; + } + + public void setGraph(HashMap graph) { + this.graph = graph; + } + + public String put( String key, String val ) { + return graph.put(key, val); + } + + public String get( String key ) { + return graph.get(key); + } + + public Collection getKeys() { + return graph.keySet(); + } + public boolean isHasCentral() { + return hasCentral; + } + public void setHasCentral(boolean hasCentral) { + this.hasCentral = hasCentral; + } + + public String getCentralLoc() { + if ( ! hasCentral ) { + return null; + } + for( String loc : graph.keySet()) { + if ( graph.get(loc).contains(centralDcaeLayerName)) { + return loc; + } + } + return null; + } + + +} diff --git a/src/main/java/org/openecomp/dmaapbc/util/RandomInteger.java b/src/main/java/org/openecomp/dmaapbc/util/RandomInteger.java new file mode 100644 index 0000000..e8086ce --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/RandomInteger.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +import java.util.Date; +// source: http://www.javapractices.com/topic/TopicAction.do?Id=62 +// with some modifications +import java.util.Random; + + +public final class RandomInteger { + private static Random randomGenerator; + private int range; + + public RandomInteger( int r ) { + randomGenerator = new Random(); + randomGenerator.setSeed((new Date()).getTime()); + range = r; + } + + public int next(){ + return randomGenerator.nextInt(range); + } + + /** Generate 10 random integers in the range 0..99. */ + public static final void main(String... aArgs){ + log("Generating 10 random integers in range 0..99."); + RandomInteger ri = new RandomInteger(100); + //note a single Random object is reused here + + for (int idx = 1; idx <= 10; ++idx){ + int randomInt = ri.next(); + log("Generated : " + randomInt); + } + + log("Done."); + } + + private static void log(String aMessage){ + System.out.println(aMessage); + } +} + diff --git a/src/main/java/org/openecomp/dmaapbc/util/RandomString.java b/src/main/java/org/openecomp/dmaapbc/util/RandomString.java new file mode 100644 index 0000000..259ed32 --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/RandomString.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +import java.util.Random; + +// source: http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string + +public class RandomString { + + private static final char[] symbols; + + static { + StringBuilder tmp = new StringBuilder(); + for (char ch = '0'; ch <= '9'; ++ch) + tmp.append(ch); + for (char ch = 'a'; ch <= 'z'; ++ch) + tmp.append(ch); + symbols = tmp.toString().toCharArray(); + } + + private final Random random = new Random(); + + private final char[] buf; + + public RandomString(int length) { + if (length < 1) + throw new IllegalArgumentException("length < 1: " + length); + buf = new char[length]; + } + + public String nextString() { + for (int idx = 0; idx < buf.length; ++idx) + buf[idx] = symbols[random.nextInt(symbols.length)]; + return new String(buf); + } + } diff --git a/src/main/java/org/openecomp/dmaapbc/util/Singleton.java b/src/main/java/org/openecomp/dmaapbc/util/Singleton.java new file mode 100644 index 0000000..b60509f --- /dev/null +++ b/src/main/java/org/openecomp/dmaapbc/util/Singleton.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * OpenECOMP - org.openecomp.dmaapbc + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.dmaapbc.util; + +public interface Singleton { + public T get(); + public void init(T val); + public void update(T val); + public void remove(); +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..bfaeaf2 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,29 @@ +### +# ============LICENSE_START======================================================= +# OpenECOMP - org.openecomp.dmaapbc +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. 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. +# ============LICENSE_END========================================================= +### + +log4j.debug=FALSE +log4j.rootLogger=INFO,Root + +log4j.appender.Root=org.apache.log4j.DailyRollingFileAppender +log4j.appender.Root.file=logs/dmaapBC-api.log +log4j.appender.Root.datePattern='.'yyyyMMdd +log4j.appender.Root.append=true +log4j.appender.Root.layout=org.apache.log4j.PatternLayout +log4j.appender.Root.layout.ConversionPattern=%d %p %F %L %t %m%n diff --git a/src/main/resources/schema_0.sql b/src/main/resources/schema_0.sql new file mode 100644 index 0000000..3b59800 --- /dev/null +++ b/src/main/resources/schema_0.sql @@ -0,0 +1,35 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + +@drop table dcae_location; +@drop table dmaap; +@drop table dr_node; +@drop table dr_pub; +@drop table dr_sub; +@drop table mr_client; +@drop table mr_cluster; +@drop table feed; +@drop table topic; +@drop table mirror_maker; +@drop table dmaapbc_sch_ver; +CREATE TABLE dmaapbc_sch_ver ( + version INTEGER +); +INSERT INTO dmaapbc_sch_ver (version) VALUES (0); diff --git a/src/main/resources/schema_1.sql b/src/main/resources/schema_1.sql new file mode 100644 index 0000000..27ae13f --- /dev/null +++ b/src/main/resources/schema_1.sql @@ -0,0 +1,136 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + +@drop table dcae_location; +create table dcae_location ( + dcae_location_name VARCHAR(100), + clli VARCHAR(100), + dcae_layer VARCHAR(100), + open_stack_availability_zone VARCHAR(100), + last_mod TIMESTAMP, + PRIMARY KEY(dcae_location_name) +); +@drop table dmaap; +create table dmaap ( + version VARCHAR(100), + topic_ns_root VARCHAR(100), + dmaap_name VARCHAR(100), + dr_prov_url VARCHAR(200), + node_key VARCHAR(100), + access_key_owner VARCHAR(100), + last_mod TIMESTAMP, + status VARCHAR(100), + bridge_admin_topic VARCHAR(100), + logging_url VARCHAR(200) +); +@drop table dr_node; +create table dr_node ( + fqdn VARCHAR(100), + dcae_location_name VARCHAR(100), + host_name VARCHAR(100), + version VARCHAR(100), + PRIMARY KEY(fqdn) +); +@drop table dr_pub; +create table dr_pub ( + dcae_location_name VARCHAR(100), + username VARCHAR(100), + userpwd VARCHAR(100), + feed_id VARCHAR(100), + pub_id VARCHAR(100), + status VARCHAR(100), + PRIMARY KEY(pub_id) +); +@drop table dr_sub; +create table dr_sub ( + owner VARCHAR(100), + suspended BOOLEAN, + status VARCHAR(100), + use100 BOOLEAN, + dcae_location_name VARCHAR(100), + username VARCHAR(100), + userpwd VARCHAR(100), + feed_id VARCHAR(100), + delivery_u_r_l VARCHAR(200), + log_u_r_l VARCHAR(200), + sub_id VARCHAR(100), + PRIMARY KEY(sub_id) +); +@drop table mr_client; +create table mr_client ( + dcae_location_name VARCHAR(100), + fqtn VARCHAR(100), + client_role VARCHAR(100), + action VARCHAR(300), + mr_client_id VARCHAR(100), + status VARCHAR(100), + topic_u_r_l VARCHAR(200), + last_mod TIMESTAMP, + PRIMARY KEY(mr_client_id) +); +@drop table mr_cluster; +create table mr_cluster ( + last_mod TIMESTAMP, + dcae_location_name VARCHAR(100), + fqdn VARCHAR(100), + hosts VARCHAR(300), + topic_protocol VARCHAR(100), + topic_port VARCHAR(100), + PRIMARY KEY(dcae_location_name) +); +@drop table feed; +create table feed ( + suspended BOOLEAN, + subscribe_u_r_l VARCHAR(200), + feed_id VARCHAR(100), + feed_name VARCHAR(100), + feed_version VARCHAR(100), + feed_description VARCHAR(1000), + owner VARCHAR(100), + aspr_classification VARCHAR(100), + publish_u_r_l VARCHAR(200), + log_u_r_l VARCHAR(200), + status VARCHAR(100), + -- pubs not stored here + -- subs not stored here + PRIMARY KEY(feed_id) +); +@drop table topic; +create table topic ( + last_mod TIMESTAMP, + fqtn VARCHAR(100), + topic_name VARCHAR(100), + topic_description VARCHAR(1000), + tnx_enabled VARCHAR(100), + owner VARCHAR(100), + status VARCHAR(100), + -- clients not stored here + PRIMARY KEY(fqtn) +); +@drop table mirror_maker; +create table mirror_maker ( + mm_name VARCHAR(100), + source_cluster VARCHAR(100), + target_cluster VARCHAR(100), + last_mod TIMESTAMP, + vectors TEXT, + PRIMARY KEY(source_cluster) +); +update dmaapbc_sch_ver set version = 1 where version = 0; diff --git a/src/main/resources/schema_2.sql b/src/main/resources/schema_2.sql new file mode 100644 index 0000000..c9e5c02 --- /dev/null +++ b/src/main/resources/schema_2.sql @@ -0,0 +1,51 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + +@alter table dcae_location + add column subnet VARCHAR(100), + add column status VARCHAR(100) +; + +@alter table dr_node + add column last_mod TIMESTAMP, + add column status VARCHAR(100) +; +@alter table dr_pub + add column last_mod TIMESTAMP +; +@alter table dr_sub + add column last_mod TIMESTAMP +; + +@alter table mr_cluster + add column status VARCHAR(100) +; +@alter table feed + add column last_mod TIMESTAMP, + add column format_uuid VARCHAR(100) +; +@alter table topic + add column format_uuid VARCHAR(100) +; + +@alter table mirror_maker + add column status VARCHAR(100) +; +update dmaapbc_sch_ver set version = 2 where version = 1; diff --git a/src/main/resources/schema_3.sql b/src/main/resources/schema_3.sql new file mode 100644 index 0000000..0f28988 --- /dev/null +++ b/src/main/resources/schema_3.sql @@ -0,0 +1,29 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + + +@alter table mirror_maker + add column topics TEXT +; +@alter table mirror_maker + drop column vectors +; +@delete from mirror_maker; +update dmaapbc_sch_ver set version = 3 where version = 2; diff --git a/src/main/resources/schema_4.sql b/src/main/resources/schema_4.sql new file mode 100644 index 0000000..727c4bd --- /dev/null +++ b/src/main/resources/schema_4.sql @@ -0,0 +1,33 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + + +@drop table mirror_maker; +create table mirror_maker ( + mm_name VARCHAR(512), + source_cluster VARCHAR(256), + target_cluster VARCHAR(256), + last_mod TIMESTAMP, + topics TEXT, + PRIMARY KEY(source_cluster) +); + + +update dmaapbc_sch_ver set version = 4 where version = 3; diff --git a/src/main/resources/schema_5.sql b/src/main/resources/schema_5.sql new file mode 100644 index 0000000..cd7130b --- /dev/null +++ b/src/main/resources/schema_5.sql @@ -0,0 +1,25 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + + +@delete from mirror_maker; + + +update dmaapbc_sch_ver set version = 5 where version = 4; diff --git a/src/main/resources/schema_6.sql b/src/main/resources/schema_6.sql new file mode 100644 index 0000000..7c2bbd7 --- /dev/null +++ b/src/main/resources/schema_6.sql @@ -0,0 +1,33 @@ +--- +-- ============LICENSE_START======================================================= +-- OpenECOMP - org.openecomp.dmaapbc +-- ================================================================================ +-- Copyright (C) 2017 AT&T Intellectual Property. 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. +-- ============LICENSE_END========================================================= +--- + + +@drop table mirror_maker; +create table mirror_maker ( + mm_name VARCHAR(512), + source_cluster VARCHAR(256), + target_cluster VARCHAR(256), + last_mod TIMESTAMP, + topics TEXT, + PRIMARY KEY(mm_name) +); + + +update dmaapbc_sch_ver set version = 6 where version = 5; diff --git a/src/main/webapp/HelloJetty.html b/src/main/webapp/HelloJetty.html new file mode 100644 index 0000000..4d61636 --- /dev/null +++ b/src/main/webapp/HelloJetty.html @@ -0,0 +1,30 @@ + + + + + + +Index + + +Hello Jetty! + + diff --git a/src/main/webapp/WEB-INF/log4j.xml b/src/main/webapp/WEB-INF/log4j.xml new file mode 100644 index 0000000..4e4d5e9 --- /dev/null +++ b/src/main/webapp/WEB-INF/log4j.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..055fbf0 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,38 @@ + + + + + + + Jersey Web Application + org.glassfish.jersey.servlet.ServletContainer + + jersey.config.server.provider.packages + org.openecomp.dmaapBC + + 1 + + + Jersey Web Application + /webapi/* + + diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp new file mode 100644 index 0000000..45aa9e8 --- /dev/null +++ b/src/main/webapp/index.jsp @@ -0,0 +1,28 @@ +<%-- + ============LICENSE_START======================================================= + OpenECOMP - org.openecomp.dmaapbc + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. 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. + ============LICENSE_END========================================================= + --%> + + + +

Jersey RESTful Web Application!

+

Jersey resource +

Visit Project Jersey website + for more information on Jersey! + + diff --git a/www/curversion b/www/curversion new file mode 100644 index 0000000..ca4f70f --- /dev/null +++ b/www/curversion @@ -0,0 +1,2 @@ +PFX=DMAAPBC1_1_ +VER=0 diff --git a/www/dmaapBC_1_1_4.pdf b/www/dmaapBC_1_1_4.pdf new file mode 100644 index 0000000..da7aeca Binary files /dev/null and b/www/dmaapBC_1_1_4.pdf differ diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..3055001 --- /dev/null +++ b/www/index.html @@ -0,0 +1,29 @@ + + + + +DMaaP Bus Controller + + +

DCAE DMaaP Bus Controller

+The full artifact implements an HTTP Server that supports the Bus Controller API. +The complete implementation is documented in Javadocs. + +

DCAE DMaaP Bus Controller API

+This server provides the following representations of the Bus Controller API: +
    +
  • description of the API:
  • + +
      +
    • presented in the swagger UI. +This provides a more dynamic presentation of the API, with ability to "Try it out!" interface. +Like a game, you may need to experiment with where to click...
    • +
    • presented in a hardcopy pdf. This is a Print-to-File output from swagger editor preview pane.
    • +
    +
  • implementation - this server also is the root URL for a "working" implementation.
  • +
  • test suite - TBD
  • +
  • GUI - TBD
  • +
+This feature is delivered to GitLab Repo under project org.openecomp.dmaapbc + + diff --git a/www/policyLogger.properties b/www/policyLogger.properties new file mode 100644 index 0000000..e98515c --- /dev/null +++ b/www/policyLogger.properties @@ -0,0 +1,24 @@ +################################### Set concurrentHashMap and timer info ####################### +#Timer initial delay and the delay between in milliseconds before task is to be execute. +timer.delay.time=1000 +#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions. +check.interval= 30000 +#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds. +event.expired.time=86400 +#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed +#to remove all expired records from this concurrentHashMap. +concurrentHashMap.limit=5000 +#Size of the concurrentHashMap - when its size drops to this point, stop the Timer +stop.check.point=2500 +################################### Set logging format ############################################# +# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println +logger.type=EELF +#################################### Set level for EELF or SYSTEMOUT logging ################################## +# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all +debugLogger.level=INFO +# Set level for metrics file. Set OFF to disable; set ON to enable +metricsLogger.level=ON +# Set level for error file. Set OFF to disable; set ON to enable +error.level=ON +# Set level for audit file. Set OFF to disable; set ON to enable +audit.level=ON diff --git a/www/swagger/404.html b/www/swagger/404.html new file mode 100644 index 0000000..eef68bc --- /dev/null +++ b/www/swagger/404.html @@ -0,0 +1,133 @@ +Page Not Found :(

Not found :(

Sorry, but the page you were trying to view does not exist.

It looks like this was the result of either:

  • a mistyped address
  • an out-of-date link
\ No newline at end of file diff --git a/www/swagger/CNAME b/www/swagger/CNAME new file mode 100644 index 0000000..be94bf0 --- /dev/null +++ b/www/swagger/CNAME @@ -0,0 +1 @@ +editor.swagger.io diff --git a/www/swagger/css/print.css b/www/swagger/css/print.css new file mode 100644 index 0000000..32bf0c8 --- /dev/null +++ b/www/swagger/css/print.css @@ -0,0 +1,1361 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #88F; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section .hljs, +.swagger-section .hljs-subst { + color: #444; +} +.swagger-section .hljs-keyword, +.swagger-section .hljs-attribute, +.swagger-section .hljs-selector-tag, +.swagger-section .hljs-meta-keyword, +.swagger-section .hljs-doctag, +.swagger-section .hljs-name { + font-weight: bold; +} +.swagger-section .hljs-built_in, +.swagger-section .hljs-literal, +.swagger-section .hljs-bullet, +.swagger-section .hljs-code, +.swagger-section .hljs-addition { + color: #1F811F; +} +.swagger-section .hljs-regexp, +.swagger-section .hljs-symbol, +.swagger-section .hljs-variable, +.swagger-section .hljs-template-variable, +.swagger-section .hljs-link, +.swagger-section .hljs-selector-attr, +.swagger-section .hljs-selector-pseudo { + color: #BC6060; +} +.swagger-section .hljs-type, +.swagger-section .hljs-string, +.swagger-section .hljs-number, +.swagger-section .hljs-selector-id, +.swagger-section .hljs-selector-class, +.swagger-section .hljs-quote, +.swagger-section .hljs-template-tag, +.swagger-section .hljs-deletion { + color: #880000; +} +.swagger-section .hljs-title, +.swagger-section .hljs-section { + color: #880000; + font-weight: bold; +} +.swagger-section .hljs-comment { + color: #888888; +} +.swagger-section .hljs-meta { + color: #2B6EA1; +} +.swagger-section .hljs-emphasis { + font-style: italic; +} +.swagger-section .hljs-strong { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + min-width: 760px; + max-width: 960px; + margin-left: auto; + margin-right: auto; + /* JSONEditor specific styling */ +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + min-width: 230px; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated { + text-decoration: line-through; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; + display: inline-block; +} +.swagger-section .authorize-wrapper { + margin: 15px 0 10px; +} +.swagger-section .authorize-wrapper_operation { + float: right; +} +.swagger-section .authorize__btn:hover { + text-decoration: underline; + cursor: pointer; +} +.swagger-section .authorize__btn_operation:hover .authorize-scopes { + display: block; +} +.swagger-section .authorize-scopes { + position: absolute; + margin-top: 20px; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section .authorize-scopes .authorize__scope { + text-decoration: none; +} +.swagger-section .authorize__btn_operation { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .authorize__btn_operation_login { + background-position: 0 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .authorize__btn_operation_logout { + background-position: -30px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section #auth_container { + color: #fff; + display: inline-block; + border: none; + padding: 5px; + width: 87px; + height: 13px; +} +.swagger-section #auth_container .authorize__btn { + color: #fff; +} +.swagger-section .auth_container { + padding: 0 0 10px; + margin-bottom: 5px; + border-bottom: solid 1px #CCC; + font-size: 0.9em; +} +.swagger-section .auth_container .auth__title { + color: #547f00; + font-size: 1.2em; +} +.swagger-section .auth_container .basic_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .auth_container .auth__description { + color: #999999; + margin-bottom: 5px; +} +.swagger-section .auth_container .auth__button { + margin-top: 10px; + height: 30px; +} +.swagger-section .auth_container .key_auth__field { + margin: 5px 0; +} +.swagger-section .auth_container .key_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .api-popup-dialog { + position: absolute; + display: none; +} +.swagger-section .api-popup-dialog-wrapper { + z-index: 1000; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + font-size: 13px; + color: #777; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.swagger-section .api-popup-dialog-shadow { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.2; + background-color: gray; + z-index: 900; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog .api-popup-content { + max-height: 500px; + overflow-y: auto; +} +.swagger-section .api-popup-dialog .api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog .api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +#header { + display: none; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + max-height: none; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 100px; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 100px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + display: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints { + display: block !important; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + display: block !important; +} diff --git a/www/swagger/css/reset.css b/www/swagger/css/reset.css new file mode 100644 index 0000000..b2b0789 --- /dev/null +++ b/www/swagger/css/reset.css @@ -0,0 +1,125 @@ +/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/www/swagger/css/screen.css b/www/swagger/css/screen.css new file mode 100644 index 0000000..90a93a2 --- /dev/null +++ b/www/swagger/css/screen.css @@ -0,0 +1,1488 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #88F; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section .hljs, +.swagger-section .hljs-subst { + color: #444; +} +.swagger-section .hljs-keyword, +.swagger-section .hljs-attribute, +.swagger-section .hljs-selector-tag, +.swagger-section .hljs-meta-keyword, +.swagger-section .hljs-doctag, +.swagger-section .hljs-name { + font-weight: bold; +} +.swagger-section .hljs-built_in, +.swagger-section .hljs-literal, +.swagger-section .hljs-bullet, +.swagger-section .hljs-code, +.swagger-section .hljs-addition { + color: #1F811F; +} +.swagger-section .hljs-regexp, +.swagger-section .hljs-symbol, +.swagger-section .hljs-variable, +.swagger-section .hljs-template-variable, +.swagger-section .hljs-link, +.swagger-section .hljs-selector-attr, +.swagger-section .hljs-selector-pseudo { + color: #BC6060; +} +.swagger-section .hljs-type, +.swagger-section .hljs-string, +.swagger-section .hljs-number, +.swagger-section .hljs-selector-id, +.swagger-section .hljs-selector-class, +.swagger-section .hljs-quote, +.swagger-section .hljs-template-tag, +.swagger-section .hljs-deletion { + color: #880000; +} +.swagger-section .hljs-title, +.swagger-section .hljs-section { + color: #880000; + font-weight: bold; +} +.swagger-section .hljs-comment { + color: #888888; +} +.swagger-section .hljs-meta { + color: #2B6EA1; +} +.swagger-section .hljs-emphasis { + font-style: italic; +} +.swagger-section .hljs-strong { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + min-width: 760px; + max-width: 960px; + margin-left: auto; + margin-right: auto; + /* JSONEditor specific styling */ +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + min-width: 230px; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated { + text-decoration: line-through; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; + display: inline-block; +} +.swagger-section .authorize-wrapper { + margin: 15px 0 10px; +} +.swagger-section .authorize-wrapper_operation { + float: right; +} +.swagger-section .authorize__btn:hover { + text-decoration: underline; + cursor: pointer; +} +.swagger-section .authorize__btn_operation:hover .authorize-scopes { + display: block; +} +.swagger-section .authorize-scopes { + position: absolute; + margin-top: 20px; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section .authorize-scopes .authorize__scope { + text-decoration: none; +} +.swagger-section .authorize__btn_operation { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .authorize__btn_operation_login { + background-position: 0 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .authorize__btn_operation_logout { + background-position: -30px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section #auth_container { + color: #fff; + display: inline-block; + border: none; + padding: 5px; + width: 87px; + height: 13px; +} +.swagger-section #auth_container .authorize__btn { + color: #fff; +} +.swagger-section .auth_container { + padding: 0 0 10px; + margin-bottom: 5px; + border-bottom: solid 1px #CCC; + font-size: 0.9em; +} +.swagger-section .auth_container .auth__title { + color: #547f00; + font-size: 1.2em; +} +.swagger-section .auth_container .basic_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .auth_container .auth__description { + color: #999999; + margin-bottom: 5px; +} +.swagger-section .auth_container .auth__button { + margin-top: 10px; + height: 30px; +} +.swagger-section .auth_container .key_auth__field { + margin: 5px 0; +} +.swagger-section .auth_container .key_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .api-popup-dialog { + position: absolute; + display: none; +} +.swagger-section .api-popup-dialog-wrapper { + z-index: 1000; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + font-size: 13px; + color: #777; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.swagger-section .api-popup-dialog-shadow { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.2; + background-color: gray; + z-index: 900; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog .api-popup-content { + max-height: 500px; + overflow-y: auto; +} +.swagger-section .api-popup-dialog .api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog .api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +.swagger-section .access { + float: right; +} +.swagger-section .auth { + float: right; +} +.swagger-section .api-ic { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .api-ic .api_information_panel { + position: relative; + margin-top: 20px; + margin-left: -5px; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section .api-ic .api_information_panel p .api-msg-enabled { + color: green; +} +.swagger-section .api-ic .api_information_panel p .api-msg-disabled { + color: red; +} +.swagger-section .api-ic:hover .api_information_panel { + position: absolute; + display: block; +} +.swagger-section .ic-info { + background-position: 0 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .ic-warning { + background-position: -60px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .ic-error { + background-position: -30px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .ic-off { + background-position: -90px 0; + width: 58px; + margin-top: -4px; + cursor: pointer; +} +.swagger-section .ic-on { + background-position: -160px 0; + width: 58px; + margin-top: -4px; + cursor: pointer; +} +.swagger-section #header { + background-color: #89bf04; + padding: 9px 14px 19px 14px; + height: 23px; + min-width: 775px; +} +.swagger-section #input_baseUrl { + width: 400px; +} +.swagger-section #api_selector { + display: block; + clear: none; + float: right; +} +.swagger-section #api_selector .input { + display: inline-block; + clear: none; + margin: 0 10px 0 0; +} +.swagger-section #api_selector input { + font-size: 0.9em; + padding: 3px; + margin: 0; +} +.swagger-section #input_apiKey { + width: 200px; +} +.swagger-section #explore, +.swagger-section #auth_container .authorize__btn { + display: block; + text-decoration: none; + font-weight: bold; + padding: 6px 8px; + font-size: 0.9em; + color: white; + background-color: #547f00; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -o-border-radius: 4px; + -ms-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} +.swagger-section #explore:hover, +.swagger-section #auth_container .authorize__btn:hover { + background-color: #547f00; +} +.swagger-section #header #logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + color: white; +} +.swagger-section #header #logo .logo__img { + display: block; + float: left; + margin-top: 2px; +} +.swagger-section #header #logo .logo__title { + display: inline-block; + padding: 5px 0 0 10px; +} +.swagger-section #content_message { + margin: 10px 15px; + font-style: italic; + color: #999999; +} +.swagger-section #message-bar { + min-height: 30px; + text-align: center; + padding-top: 10px; +} +.swagger-section .swagger-collapse:before { + content: "-"; +} +.swagger-section .swagger-expand:before { + content: "+"; +} +.swagger-section .error { + outline-color: #cc0000; + background-color: #f2dede; +} diff --git a/www/swagger/css/style.css b/www/swagger/css/style.css new file mode 100644 index 0000000..fc21a31 --- /dev/null +++ b/www/swagger/css/style.css @@ -0,0 +1,250 @@ +.swagger-section #header a#logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo.png) no-repeat left center; + padding: 20px 0 20px 40px; +} +#text-head { + font-size: 80px; + font-family: 'Roboto', sans-serif; + color: #ffffff; + float: right; + margin-right: 20%; +} +.navbar-fixed-top .navbar-nav { + height: auto; +} +.navbar-fixed-top .navbar-brand { + height: auto; +} +.navbar-header { + height: auto; +} +.navbar-inverse { + background-color: #000; + border-color: #000; +} +#navbar-brand { + margin-left: 20%; +} +.navtext { + font-size: 10px; +} +.h1, +h1 { + font-size: 60px; +} +.navbar-default .navbar-header .navbar-brand { + color: #a2dfee; +} +/* tag titles */ +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #393939; + font-family: 'Arvo', serif; + font-size: 1.5em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #525252; + padding-left: 0px; + display: block; + clear: none; + float: left; + font-family: 'Arvo', serif; + font-weight: bold; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #0A0A0A; +} +.container1 { + width: 1500px; + margin: auto; + margin-top: 0; + background-image: url('../images/shield.png'); + background-repeat: no-repeat; + background-position: -40px -20px; + margin-bottom: 210px; +} +.container-inner { + width: 1200px; + margin: auto; + background-color: rgba(223, 227, 228, 0.75); + padding-bottom: 40px; + padding-top: 40px; + border-radius: 15px; +} +.header-content { + padding: 0; + width: 1000px; +} +.title1 { + font-size: 80px; + font-family: 'Vollkorn', serif; + color: #404040; + text-align: center; + padding-top: 40px; + padding-bottom: 100px; +} +#icon { + margin-top: -18px; +} +.subtext { + font-size: 25px; + font-style: italic; + color: #08b; + text-align: right; + padding-right: 250px; +} +.bg-primary { + background-color: #00468b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:hover { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus:hover { + color: #08b; +} +.text-faded { + font-size: 25px; + font-family: 'Vollkorn', serif; +} +.section-heading { + font-family: 'Vollkorn', serif; + font-size: 45px; + padding-bottom: 10px; +} +hr { + border-color: #00468b; + padding-bottom: 10px; +} +.description { + margin-top: 20px; + padding-bottom: 200px; +} +.description li { + font-family: 'Vollkorn', serif; + font-size: 25px; + color: #525252; + margin-left: 28%; + padding-top: 5px; +} +.gap { + margin-top: 200px; +} +.troubleshootingtext { + color: rgba(255, 255, 255, 0.7); + padding-left: 30%; +} +.troubleshootingtext li { + list-style-type: circle; + font-size: 25px; + padding-bottom: 5px; +} +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; +} +.block.response_body.json:hover { + cursor: pointer; +} +.backdrop { + color: blue; +} +#myModal { + height: 100%; +} +.modal-backdrop { + bottom: 0; + position: fixed; +} +.curl { + padding: 10px; + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; + max-height: 400px; + margin-top: 5px; + overflow-y: auto; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + border-radius: 4px; +} +.curl_title { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; + font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; + font-weight: 500; + line-height: 1.1; +} +.footer { + display: none; +} +.swagger-section .swagger-ui-wrap h2 { + padding: 0; +} +h2 { + margin: 0; + margin-bottom: 5px; +} +.markdown p { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap .code { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap b { + font-family: 'Arvo', serif; +} +#signin:hover { + cursor: pointer; +} +.dropdown-menu { + padding: 15px; +} +.navbar-right .dropdown-menu { + left: 0; + right: auto; +} +#signinbutton { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} +.navbar-default .nav > li .details { + color: #000000; + text-transform: none; + font-size: 15px; + font-weight: normal; + font-family: 'Open Sans', sans-serif; + font-style: italic; + line-height: 20px; + top: -2px; +} +.navbar-default .nav > li .details:hover { + color: black; +} +#signout { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} diff --git a/www/swagger/css/typography.css b/www/swagger/css/typography.css new file mode 100644 index 0000000..3235edd --- /dev/null +++ b/www/swagger/css/typography.css @@ -0,0 +1,14 @@ +/* Google Font's Droid Sans */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 400; + src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype'); +} +/* Google Font's Droid Sans Bold */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 700; + src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype'); +} diff --git a/www/swagger/fonts/DroidSans-Bold.ttf b/www/swagger/fonts/DroidSans-Bold.ttf new file mode 100644 index 0000000..036c4d1 Binary files /dev/null and b/www/swagger/fonts/DroidSans-Bold.ttf differ diff --git a/www/swagger/fonts/DroidSans.ttf b/www/swagger/fonts/DroidSans.ttf new file mode 100644 index 0000000..e517a0c Binary files /dev/null and b/www/swagger/fonts/DroidSans.ttf differ diff --git a/www/swagger/images/collapse.gif b/www/swagger/images/collapse.gif new file mode 100644 index 0000000..8843e8c Binary files /dev/null and b/www/swagger/images/collapse.gif differ diff --git a/www/swagger/images/expand.gif b/www/swagger/images/expand.gif new file mode 100644 index 0000000..477bf13 Binary files /dev/null and b/www/swagger/images/expand.gif differ diff --git a/www/swagger/images/explorer_icons.png b/www/swagger/images/explorer_icons.png new file mode 100644 index 0000000..ed9d2ff Binary files /dev/null and b/www/swagger/images/explorer_icons.png differ diff --git a/www/swagger/images/favicon-16x16.png b/www/swagger/images/favicon-16x16.png new file mode 100644 index 0000000..66b1a5b Binary files /dev/null and b/www/swagger/images/favicon-16x16.png differ diff --git a/www/swagger/images/favicon-32x32.png b/www/swagger/images/favicon-32x32.png new file mode 100644 index 0000000..32f319f Binary files /dev/null and b/www/swagger/images/favicon-32x32.png differ diff --git a/www/swagger/images/favicon.ico b/www/swagger/images/favicon.ico new file mode 100644 index 0000000..8b60bcf Binary files /dev/null and b/www/swagger/images/favicon.ico differ diff --git a/www/swagger/images/logo_small.png b/www/swagger/images/logo_small.png new file mode 100644 index 0000000..5496a65 Binary files /dev/null and b/www/swagger/images/logo_small.png differ diff --git a/www/swagger/images/pet_store_api.png b/www/swagger/images/pet_store_api.png new file mode 100644 index 0000000..f9f9cd4 Binary files /dev/null and b/www/swagger/images/pet_store_api.png differ diff --git a/www/swagger/images/throbber.gif b/www/swagger/images/throbber.gif new file mode 100644 index 0000000..0639388 Binary files /dev/null and b/www/swagger/images/throbber.gif differ diff --git a/www/swagger/images/wordnik_api.png b/www/swagger/images/wordnik_api.png new file mode 100644 index 0000000..dca4f14 Binary files /dev/null and b/www/swagger/images/wordnik_api.png differ diff --git a/www/swagger/index.html b/www/swagger/index.html new file mode 100644 index 0000000..2639ea0 --- /dev/null +++ b/www/swagger/index.html @@ -0,0 +1,128 @@ + + + + + Swagger UI for dcae_dmaapbc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+
+ + diff --git a/www/swagger/lang/en.js b/www/swagger/lang/en.js new file mode 100644 index 0000000..9183136 --- /dev/null +++ b/www/swagger/lang/en.js @@ -0,0 +1,56 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Warning: Deprecated", + "Implementation Notes":"Implementation Notes", + "Response Class":"Response Class", + "Status":"Status", + "Parameters":"Parameters", + "Parameter":"Parameter", + "Value":"Value", + "Description":"Description", + "Parameter Type":"Parameter Type", + "Data Type":"Data Type", + "Response Messages":"Response Messages", + "HTTP Status Code":"HTTP Status Code", + "Reason":"Reason", + "Response Model":"Response Model", + "Request URL":"Request URL", + "Response Body":"Response Body", + "Response Code":"Response Code", + "Response Headers":"Response Headers", + "Hide Response":"Hide Response", + "Headers":"Headers", + "Try it out!":"Try it out!", + "Show/Hide":"Show/Hide", + "List Operations":"List Operations", + "Expand Operations":"Expand Operations", + "Raw":"Raw", + "can't parse JSON. Raw result":"can't parse JSON. Raw result", + "Example Value":"Example Value", + "Model Schema":"Model Schema", + "Model":"Model", + "Click to set as parameter value":"Click to set as parameter value", + "apply":"apply", + "Username":"Username", + "Password":"Password", + "Terms of service":"Terms of service", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"Contact the developer", + "api version":"api version", + "Response Content Type":"Response Content Type", + "Parameter content type:":"Parameter content type:", + "fetching resource":"fetching resource", + "fetching resource list":"fetching resource list", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", + "Please specify the protocol for":"Please specify the protocol for", + "Can't read swagger JSON from":"Can't read swagger JSON from", + "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", + "Unable to read api":"Unable to read api", + "from path":"from path", + "server returned":"server returned" +}); diff --git a/www/swagger/lang/es.js b/www/swagger/lang/es.js new file mode 100644 index 0000000..13fa015 --- /dev/null +++ b/www/swagger/lang/es.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Advertencia: Obsoleto", + "Implementation Notes":"Notas de implementación", + "Response Class":"Clase de la Respuesta", + "Status":"Status", + "Parameters":"Parámetros", + "Parameter":"Parámetro", + "Value":"Valor", + "Description":"Descripción", + "Parameter Type":"Tipo del Parámetro", + "Data Type":"Tipo del Dato", + "Response Messages":"Mensajes de la Respuesta", + "HTTP Status Code":"Código de Status HTTP", + "Reason":"Razón", + "Response Model":"Modelo de la Respuesta", + "Request URL":"URL de la Solicitud", + "Response Body":"Cuerpo de la Respuesta", + "Response Code":"Código de la Respuesta", + "Response Headers":"Encabezados de la Respuesta", + "Hide Response":"Ocultar Respuesta", + "Try it out!":"Pruébalo!", + "Show/Hide":"Mostrar/Ocultar", + "List Operations":"Listar Operaciones", + "Expand Operations":"Expandir Operaciones", + "Raw":"Crudo", + "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo", + "Example Value":"Valor de Ejemplo", + "Model Schema":"Esquema del Modelo", + "Model":"Modelo", + "apply":"aplicar", + "Username":"Nombre de usuario", + "Password":"Contraseña", + "Terms of service":"Términos de Servicio", + "Created by":"Creado por", + "See more at":"Ver más en", + "Contact the developer":"Contactar al desarrollador", + "api version":"versión de la api", + "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta", + "fetching resource":"buscando recurso", + "fetching resource list":"buscando lista del recurso", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.", + "Please specify the protocol for":"Por favor, especificar el protocola para", + "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde", + "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI", + "Unable to read api":"No se puede leer la api", + "from path":"desde ruta", + "server returned":"el servidor retornó" +}); diff --git a/www/swagger/lang/fr.js b/www/swagger/lang/fr.js new file mode 100644 index 0000000..388dff1 --- /dev/null +++ b/www/swagger/lang/fr.js @@ -0,0 +1,54 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Avertissement : Obsolète", + "Implementation Notes":"Notes d'implémentation", + "Response Class":"Classe de la réponse", + "Status":"Statut", + "Parameters":"Paramètres", + "Parameter":"Paramètre", + "Value":"Valeur", + "Description":"Description", + "Parameter Type":"Type du paramètre", + "Data Type":"Type de données", + "Response Messages":"Messages de la réponse", + "HTTP Status Code":"Code de statut HTTP", + "Reason":"Raison", + "Response Model":"Modèle de réponse", + "Request URL":"URL appelée", + "Response Body":"Corps de la réponse", + "Response Code":"Code de la réponse", + "Response Headers":"En-têtes de la réponse", + "Hide Response":"Cacher la réponse", + "Headers":"En-têtes", + "Try it out!":"Testez !", + "Show/Hide":"Afficher/Masquer", + "List Operations":"Liste des opérations", + "Expand Operations":"Développer les opérations", + "Raw":"Brut", + "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut", + "Example Value":"Exemple la valeur", + "Model Schema":"Définition du modèle", + "Model":"Modèle", + "apply":"appliquer", + "Username":"Nom d'utilisateur", + "Password":"Mot de passe", + "Terms of service":"Conditions de service", + "Created by":"Créé par", + "See more at":"Voir plus sur", + "Contact the developer":"Contacter le développeur", + "api version":"version de l'api", + "Response Content Type":"Content Type de la réponse", + "fetching resource":"récupération de la ressource", + "fetching resource list":"récupération de la liste de ressources", + "Explore":"Explorer", + "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.", + "Please specify the protocol for":"Veuillez spécifier un protocole pour", + "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de", + "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI", + "Unable to read api":"Impossible de lire l'api", + "from path":"à partir du chemin", + "server returned":"réponse du serveur" +}); diff --git a/www/swagger/lang/geo.js b/www/swagger/lang/geo.js new file mode 100644 index 0000000..609c20d --- /dev/null +++ b/www/swagger/lang/geo.js @@ -0,0 +1,56 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება", + "Implementation Notes":"იმპლემენტაციის აღწერა", + "Response Class":"რესპონს კლასი", + "Status":"სტატუსი", + "Parameters":"პარამეტრები", + "Parameter":"პარამეტრი", + "Value":"მნიშვნელობა", + "Description":"აღწერა", + "Parameter Type":"პარამეტრის ტიპი", + "Data Type":"მონაცემის ტიპი", + "Response Messages":"პასუხი", + "HTTP Status Code":"HTTP სტატუსი", + "Reason":"მიზეზი", + "Response Model":"რესპონს მოდელი", + "Request URL":"მოთხოვნის URL", + "Response Body":"პასუხის სხეული", + "Response Code":"პასუხის კოდი", + "Response Headers":"პასუხის ჰედერები", + "Hide Response":"დამალე პასუხი", + "Headers":"ჰედერები", + "Try it out!":"ცადე !", + "Show/Hide":"გამოჩენა/დამალვა", + "List Operations":"ოპერაციების სია", + "Expand Operations":"ოპერაციები ვრცლად", + "Raw":"ნედლი", + "can't parse JSON. Raw result":"JSON-ის დამუშავება ვერ მოხერხდა. ნედლი პასუხი", + "Example Value":"მაგალითი", + "Model Schema":"მოდელის სტრუქტურა", + "Model":"მოდელი", + "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე", + "apply":"გამოყენება", + "Username":"მოხმარებელი", + "Password":"პაროლი", + "Terms of service":"მომსახურების პირობები", + "Created by":"შექმნა", + "See more at":"ნახე ვრცლად", + "Contact the developer":"დაუკავშირდი დეველოპერს", + "api version":"api ვერსია", + "Response Content Type":"პასუხის კონტენტის ტიპი", + "Parameter content type:":"პარამეტრის კონტენტის ტიპი:", + "fetching resource":"რესურსების მიღება", + "fetching resource list":"რესურსების სიის მიღება", + "Explore":"ნახვა", + "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება. შეამოწმეთ access-control-origin.", + "Please specify the protocol for":"მიუთითეთ პროტოკოლი", + "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა", + "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება", + "Unable to read api":"api წაკითხვა ვერ მოხერხდა", + "from path":"მისამართიდან", + "server returned":"სერვერმა დააბრუნა" +}); diff --git a/www/swagger/lang/it.js b/www/swagger/lang/it.js new file mode 100644 index 0000000..8529c2a --- /dev/null +++ b/www/swagger/lang/it.js @@ -0,0 +1,52 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Attenzione: Deprecato", + "Implementation Notes":"Note di implementazione", + "Response Class":"Classe della risposta", + "Status":"Stato", + "Parameters":"Parametri", + "Parameter":"Parametro", + "Value":"Valore", + "Description":"Descrizione", + "Parameter Type":"Tipo di parametro", + "Data Type":"Tipo di dato", + "Response Messages":"Messaggi della risposta", + "HTTP Status Code":"Codice stato HTTP", + "Reason":"Motivo", + "Response Model":"Modello di risposta", + "Request URL":"URL della richiesta", + "Response Body":"Corpo della risposta", + "Response Code":"Oggetto della risposta", + "Response Headers":"Intestazioni della risposta", + "Hide Response":"Nascondi risposta", + "Try it out!":"Provalo!", + "Show/Hide":"Mostra/Nascondi", + "List Operations":"Mostra operazioni", + "Expand Operations":"Espandi operazioni", + "Raw":"Grezzo (raw)", + "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).", + "Model Schema":"Schema del modello", + "Model":"Modello", + "apply":"applica", + "Username":"Nome utente", + "Password":"Password", + "Terms of service":"Condizioni del servizio", + "Created by":"Creato da", + "See more at":"Informazioni aggiuntive:", + "Contact the developer":"Contatta lo sviluppatore", + "api version":"versione api", + "Response Content Type":"Tipo di contenuto (content type) della risposta", + "fetching resource":"recuperando la risorsa", + "fetching resource list":"recuperando lista risorse", + "Explore":"Esplora", + "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.", + "Please specify the protocol for":"Si prega di specificare il protocollo per", + "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:", + "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata", + "Unable to read api":"Impossibile leggere la api", + "from path":"da cartella", + "server returned":"il server ha restituito" +}); diff --git a/www/swagger/lang/ja.js b/www/swagger/lang/ja.js new file mode 100644 index 0000000..3207bfc --- /dev/null +++ b/www/swagger/lang/ja.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告: 廃止予定", + "Implementation Notes":"実装メモ", + "Response Class":"レスポンスクラス", + "Status":"ステータス", + "Parameters":"パラメータ群", + "Parameter":"パラメータ", + "Value":"値", + "Description":"説明", + "Parameter Type":"パラメータタイプ", + "Data Type":"データタイプ", + "Response Messages":"レスポンスメッセージ", + "HTTP Status Code":"HTTPステータスコード", + "Reason":"理由", + "Response Model":"レスポンスモデル", + "Request URL":"リクエストURL", + "Response Body":"レスポンスボディ", + "Response Code":"レスポンスコード", + "Response Headers":"レスポンスヘッダ", + "Hide Response":"レスポンスを隠す", + "Headers":"ヘッダ", + "Try it out!":"実際に実行!", + "Show/Hide":"表示/非表示", + "List Operations":"操作一覧", + "Expand Operations":"操作の展開", + "Raw":"Raw", + "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果", + "Model Schema":"モデルスキーマ", + "Model":"モデル", + "apply":"実行", + "Username":"ユーザ名", + "Password":"パスワード", + "Terms of service":"サービス利用規約", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"開発者に連絡", + "api version":"APIバージョン", + "Response Content Type":"レスポンス コンテンツタイプ", + "fetching resource":"リソースの取得", + "fetching resource list":"リソース一覧の取得", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.", + "Please specify the protocol for":"プロトコルを指定してください", + "Can't read swagger JSON from":"次からswagger JSONを読み込めません", + "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています", + "Unable to read api":"APIを読み込めません", + "from path":"次のパスから", + "server returned":"サーバからの返答" +}); diff --git a/www/swagger/lang/pl.js b/www/swagger/lang/pl.js new file mode 100644 index 0000000..ce41e91 --- /dev/null +++ b/www/swagger/lang/pl.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uwaga: Wycofane", + "Implementation Notes":"Uwagi Implementacji", + "Response Class":"Klasa Odpowiedzi", + "Status":"Status", + "Parameters":"Parametry", + "Parameter":"Parametr", + "Value":"Wartość", + "Description":"Opis", + "Parameter Type":"Typ Parametru", + "Data Type":"Typ Danych", + "Response Messages":"Wiadomości Odpowiedzi", + "HTTP Status Code":"Kod Statusu HTTP", + "Reason":"Przyczyna", + "Response Model":"Model Odpowiedzi", + "Request URL":"URL Wywołania", + "Response Body":"Treść Odpowiedzi", + "Response Code":"Kod Odpowiedzi", + "Response Headers":"Nagłówki Odpowiedzi", + "Hide Response":"Ukryj Odpowiedź", + "Headers":"Nagłówki", + "Try it out!":"Wypróbuj!", + "Show/Hide":"Pokaż/Ukryj", + "List Operations":"Lista Operacji", + "Expand Operations":"Rozwiń Operacje", + "Raw":"Nieprzetworzone", + "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane", + "Model Schema":"Schemat Modelu", + "Model":"Model", + "apply":"użyj", + "Username":"Nazwa użytkownika", + "Password":"Hasło", + "Terms of service":"Warunki używania", + "Created by":"Utworzone przez", + "See more at":"Zobacz więcej na", + "Contact the developer":"Kontakt z deweloperem", + "api version":"wersja api", + "Response Content Type":"Typ Zasobu Odpowiedzi", + "fetching resource":"ładowanie zasobu", + "fetching resource list":"ładowanie listy zasobów", + "Explore":"Eksploruj", + "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.", + "Please specify the protocol for":"Proszę podać protokół dla", + "Can't read swagger JSON from":"Nie można odczytać swagger JSON z", + "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI", + "Unable to read api":"Nie można odczytać api", + "from path":"ze ścieżki", + "server returned":"serwer zwrócił" +}); diff --git a/www/swagger/lang/pt.js b/www/swagger/lang/pt.js new file mode 100644 index 0000000..f2e7c13 --- /dev/null +++ b/www/swagger/lang/pt.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Aviso: Depreciado", + "Implementation Notes":"Notas de Implementação", + "Response Class":"Classe de resposta", + "Status":"Status", + "Parameters":"Parâmetros", + "Parameter":"Parâmetro", + "Value":"Valor", + "Description":"Descrição", + "Parameter Type":"Tipo de parâmetro", + "Data Type":"Tipo de dados", + "Response Messages":"Mensagens de resposta", + "HTTP Status Code":"Código de status HTTP", + "Reason":"Razão", + "Response Model":"Modelo resposta", + "Request URL":"URL requisição", + "Response Body":"Corpo da resposta", + "Response Code":"Código da resposta", + "Response Headers":"Cabeçalho da resposta", + "Headers":"Cabeçalhos", + "Hide Response":"Esconder resposta", + "Try it out!":"Tente agora!", + "Show/Hide":"Mostrar/Esconder", + "List Operations":"Listar operações", + "Expand Operations":"Expandir operações", + "Raw":"Cru", + "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru", + "Model Schema":"Modelo esquema", + "Model":"Modelo", + "apply":"Aplicar", + "Username":"Usuário", + "Password":"Senha", + "Terms of service":"Termos do serviço", + "Created by":"Criado por", + "See more at":"Veja mais em", + "Contact the developer":"Contate o desenvolvedor", + "api version":"Versão api", + "Response Content Type":"Tipo de conteúdo da resposta", + "fetching resource":"busca recurso", + "fetching resource list":"buscando lista de recursos", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin", + "Please specify the protocol for":"Por favor especifique o protocolo", + "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de", + "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI", + "Unable to read api":"Não foi possível ler api", + "from path":"do caminho", + "server returned":"servidor retornou" +}); diff --git a/www/swagger/lang/ru.js b/www/swagger/lang/ru.js new file mode 100644 index 0000000..592744e --- /dev/null +++ b/www/swagger/lang/ru.js @@ -0,0 +1,56 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Предупреждение: Устарело", + "Implementation Notes":"Заметки", + "Response Class":"Пример ответа", + "Status":"Статус", + "Parameters":"Параметры", + "Parameter":"Параметр", + "Value":"Значение", + "Description":"Описание", + "Parameter Type":"Тип параметра", + "Data Type":"Тип данных", + "HTTP Status Code":"HTTP код", + "Reason":"Причина", + "Response Model":"Структура ответа", + "Request URL":"URL запроса", + "Response Body":"Тело ответа", + "Response Code":"HTTP код ответа", + "Response Headers":"Заголовки ответа", + "Hide Response":"Спрятать ответ", + "Headers":"Заголовки", + "Response Messages":"Что может прийти в ответ", + "Try it out!":"Попробовать!", + "Show/Hide":"Показать/Скрыть", + "List Operations":"Операции кратко", + "Expand Operations":"Операции подробно", + "Raw":"В сыром виде", + "can't parse JSON. Raw result":"Не удается распарсить ответ:", + "Example Value":"Пример", + "Model Schema":"Структура", + "Model":"Описание", + "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра", + "apply":"применить", + "Username":"Имя пользователя", + "Password":"Пароль", + "Terms of service":"Условия использования", + "Created by":"Разработано", + "See more at":"Еще тут", + "Contact the developer":"Связаться с разработчиком", + "api version":"Версия API", + "Response Content Type":"Content Type ответа", + "Parameter content type:":"Content Type параметра:", + "fetching resource":"Получение ресурса", + "fetching resource list":"Получение ресурсов", + "Explore":"Показать", + "Show Swagger Petstore Example Apis":"Показать примеры АПИ", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа", + "Please specify the protocol for":"Пожалуйста, укажите протокол для", + "Can't read swagger JSON from":"Не получается прочитать swagger json из", + "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим", + "Unable to read api":"Не удалось прочитать api", + "from path":"по адресу", + "server returned":"сервер сказал" +}); diff --git a/www/swagger/lang/tr.js b/www/swagger/lang/tr.js new file mode 100644 index 0000000..16426a9 --- /dev/null +++ b/www/swagger/lang/tr.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uyarı: Deprecated", + "Implementation Notes":"Gerçekleştirim Notları", + "Response Class":"Dönen Sınıf", + "Status":"Statü", + "Parameters":"Parametreler", + "Parameter":"Parametre", + "Value":"Değer", + "Description":"Açıklama", + "Parameter Type":"Parametre Tipi", + "Data Type":"Veri Tipi", + "Response Messages":"Dönüş Mesajı", + "HTTP Status Code":"HTTP Statü Kodu", + "Reason":"Gerekçe", + "Response Model":"Dönüş Modeli", + "Request URL":"İstek URL", + "Response Body":"Dönüş İçeriği", + "Response Code":"Dönüş Kodu", + "Response Headers":"Dönüş Üst Bilgileri", + "Hide Response":"Dönüşü Gizle", + "Headers":"Üst Bilgiler", + "Try it out!":"Dene!", + "Show/Hide":"Göster/Gizle", + "List Operations":"Operasyonları Listele", + "Expand Operations":"Operasyonları Aç", + "Raw":"Ham", + "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç", + "Model Schema":"Model Şema", + "Model":"Model", + "apply":"uygula", + "Username":"Kullanıcı Adı", + "Password":"Parola", + "Terms of service":"Servis şartları", + "Created by":"Oluşturan", + "See more at":"Daha fazlası için", + "Contact the developer":"Geliştirici ile İletişime Geçin", + "api version":"api versiyon", + "Response Content Type":"Dönüş İçerik Tipi", + "fetching resource":"kaynak getiriliyor", + "fetching resource list":"kaynak listesi getiriliyor", + "Explore":"Keşfet", + "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.", + "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz", + "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor", + "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor", + "Unable to read api":"api okunamadı", + "from path":"yoldan", + "server returned":"sunucuya dönüldü" +}); diff --git a/www/swagger/lang/translator.js b/www/swagger/lang/translator.js new file mode 100644 index 0000000..591f6d4 --- /dev/null +++ b/www/swagger/lang/translator.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Translator for documentation pages. + * + * To enable translation you should include one of language-files in your index.html + * after . + * For example - + * + * If you wish to translate some new texsts you should do two things: + * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. + * 2. Mark that text it templates this way New Phrase or . + * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. + * + */ +window.SwaggerTranslator = { + + _words:[], + + translate: function(sel) { + var $this = this; + sel = sel || '[data-sw-translate]'; + + $(sel).each(function() { + $(this).html($this._tryTranslate($(this).html())); + + $(this).val($this._tryTranslate($(this).val())); + $(this).attr('title', $this._tryTranslate($(this).attr('title'))); + }); + }, + + _tryTranslate: function(word) { + return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; + }, + + learn: function(wordsMap) { + this._words = wordsMap; + } +}; diff --git a/www/swagger/lang/zh-cn.js b/www/swagger/lang/zh-cn.js new file mode 100644 index 0000000..570319b --- /dev/null +++ b/www/swagger/lang/zh-cn.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告:已过时", + "Implementation Notes":"实现备注", + "Response Class":"响应类", + "Status":"状态", + "Parameters":"参数", + "Parameter":"参数", + "Value":"值", + "Description":"描述", + "Parameter Type":"参数类型", + "Data Type":"数据类型", + "Response Messages":"响应消息", + "HTTP Status Code":"HTTP状态码", + "Reason":"原因", + "Response Model":"响应模型", + "Request URL":"请求URL", + "Response Body":"响应体", + "Response Code":"响应码", + "Response Headers":"响应头", + "Hide Response":"隐藏响应", + "Headers":"头", + "Try it out!":"试一下!", + "Show/Hide":"显示/隐藏", + "List Operations":"显示操作", + "Expand Operations":"展开操作", + "Raw":"原始", + "can't parse JSON. Raw result":"无法解析JSON. 原始结果", + "Model Schema":"模型架构", + "Model":"模型", + "apply":"应用", + "Username":"用户名", + "Password":"密码", + "Terms of service":"服务条款", + "Created by":"创建者", + "See more at":"查看更多:", + "Contact the developer":"联系开发者", + "api version":"api版本", + "Response Content Type":"响应Content Type", + "fetching resource":"正在获取资源", + "fetching resource list":"正在获取资源列表", + "Explore":"浏览", + "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", + "Please specify the protocol for":"请指定协议:", + "Can't read swagger JSON from":"无法读取swagger JSON于", + "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", + "Unable to read api":"无法读取api", + "from path":"从路径", + "server returned":"服务器返回" +}); diff --git a/www/swagger/lib/backbone-min.js b/www/swagger/lib/backbone-min.js new file mode 100644 index 0000000..a3f544b --- /dev/null +++ b/www/swagger/lib/backbone-min.js @@ -0,0 +1,15 @@ +// 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.$('