summaryrefslogtreecommitdiffstats
path: root/dmaap-bc
diff options
context:
space:
mode:
Diffstat (limited to 'dmaap-bc')
-rw-r--r--dmaap-bc/README.md172
-rw-r--r--dmaap-bc/misc/dbc-api.jksbin3740 -> 0 bytes
-rw-r--r--dmaap-bc/misc/opensource.env120
-rw-r--r--dmaap-bc/misc/policyLogger.properties45
-rw-r--r--dmaap-bc/pom.xml683
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafConnection.java329
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafDecrypt.java58
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafEmpty.java28
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafLurService.java140
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafNamespace.java114
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafObject.java34
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafRole.java74
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafService.java47
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactory.java86
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceImpl.java163
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafUserRole.java80
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/ClearDecrypt.java42
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DecryptionInterface.java30
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapGrant.java79
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapPerm.java89
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFish.java104
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AllowAll.java29
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiAuthorizationCheckInterface.java29
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPerms.java180
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPolicy.java63
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AuthenticationErrorException.java35
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java1101
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrProvConnection.java271
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrTopicConnection.java239
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnWrapper.java83
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnectionFactory.java117
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBException.java34
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBFieldHandler.java205
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBMap.java137
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBSingleton.java98
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DatabaseClass.java286
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/LoadSchema.java57
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/TableHandler.java126
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/BaseLoggingClass.java36
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/DmaapbcLogMessageEnum.java81
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/logmsg.properties240
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ApiError.java92
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/BrTopic.java71
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Node.java94
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Pub.java187
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java391
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DcaeLocation.java119
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Dmaap.java177
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DmaapObject.java144
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Feed.java294
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/FqtnType.java68
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Client.java162
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Cluster.java235
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MirrorMaker.java165
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ReplicationType.java109
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Topic.java352
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java141
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java115
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/Authorization.java35
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AuthorizationFilter.java68
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/BridgeResource.java191
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_NodeResource.java172
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_PubResource.java252
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_SubResource.java243
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResource.java153
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DmaapResource.java123
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java259
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/InfoResource.java72
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClientResource.java208
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResource.java174
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java55
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java52
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredFieldException.java46
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java84
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/TopicResource.java218
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/ApplicationConfig.java37
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CadiCertificateManager.java61
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertficateManagerFactory.java51
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertificateManager.java104
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/JettyServer.java174
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/LegacyCertificateManager.java39
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/Main.java93
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafPermissionService.java122
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafTopicSetupService.java218
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java159
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/Credentials.java44
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/CredentialsParser.java39
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_NodeService.java273
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_PubService.java147
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java228
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DcaeLocationService.java85
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DmaapService.java310
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java572
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClientService.java234
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClusterService.java205
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MirrorMakerService.java255
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java526
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapConfig.java78
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapTimestamp.java46
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java42
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Graph.java132
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java83
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomInteger.java43
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomString.java55
-rw-r--r--dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Singleton.java28
-rw-r--r--dmaap-bc/src/main/resources/docker-compose.yml25
-rw-r--r--dmaap-bc/src/main/resources/docker-databus-controller.conf12
-rw-r--r--dmaap-bc/src/main/resources/docker/Dockerfile (renamed from dmaap-bc/src/main/resources/Dockerfile)39
-rw-r--r--dmaap-bc/src/main/resources/misc/LocalKey27
-rw-r--r--dmaap-bc/src/main/resources/misc/PolicyEngineApi.properties.tmpl36
-rw-r--r--dmaap-bc/src/main/resources/misc/dmaapbc (renamed from dmaap-bc/misc/dmaapbc)91
-rwxr-xr-xdmaap-bc/src/main/resources/misc/dmaapbc.properties.tmpl222
-rw-r--r--dmaap-bc/src/main/resources/misc/havecert.tmpl (renamed from dmaap-bc/misc/log4j.properties.tmpl)26
-rw-r--r--dmaap-bc/src/main/resources/misc/logback.xml (renamed from dmaap-bc/misc/logback.xml)28
-rw-r--r--dmaap-bc/src/main/resources/misc/schema_all.sql144
-rw-r--r--dmaap-bc/src/main/webapp/HelloJetty.html30
-rw-r--r--dmaap-bc/src/main/webapp/WEB-INF/log4j2.xml50
-rw-r--r--dmaap-bc/src/main/webapp/WEB-INF/web.xml38
-rw-r--r--dmaap-bc/src/main/webapp/index.jsp28
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java47
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactoryTest.java103
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceImplTest.java208
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafUserRoleTest.java58
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFishTest.java54
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AllowAllTest.java38
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPermsTest.java52
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPolicyTest.java82
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/DrProvConnectionTest.java136
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrProvConnectionTest.java103
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrTopicConnectionTest.java101
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBFieldHandlerTest.java110
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBMapTest.java84
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBSingletonTest.java67
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/LoadSchemaTest.java68
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/TableHandlerTest.java106
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java59
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRNodeTest.java86
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRPubTest.java90
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRSubTest.java155
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DcaeLocationTest.java94
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DmaapTest.java103
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/FeedTest.java116
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/JUnitTestSuite.java41
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MRClientTest.java111
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MR_ClusterTest.java135
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MirrorMakerTest.java101
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TestRunner.java41
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TopicTest.java87
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java195
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java172
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_NodeResourceTest.java236
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_PubResourceTest.java291
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_SubResourceTest.java434
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResourceTest.java129
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DmaapResourceTest.java92
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java39
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FeedResourceTest.java104
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/InfoResourceTest.java71
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClientResourceTest.java304
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResourceTest.java284
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java78
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java86
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java51
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java96
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java49
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TopicResourceTest.java356
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/JettyServerTest.java79
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/MainTest.java79
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafPermissionServiceTest.java141
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafTopicSetupServiceTest.java470
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/ApiServiceTest.java60
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/CredentialsParserTest.java58
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DR_NodeServiceTest.java96
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DcaeLocationServiceTest.java144
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DmaapServiceTest.java90
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/Dr_PubServiceTest.java108
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/FeedServiceTest.java102
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClientServiceTest.java135
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClusterServiceTest.java127
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTest.java185
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTestMockito.java97
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/TopicServiceTest.java305
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/DmaapObjectFactory.java128
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/ReflectionHarness.java169
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapConfigTest.java72
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapTimestampTest.java42
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/FqdnTest.java33
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/GraphTest.java102
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java164
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomIntegerTest.java40
-rw-r--r--dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomStringTest.java60
-rw-r--r--dmaap-bc/src/test/resources/cadi.properties0
-rw-r--r--dmaap-bc/src/test/resources/dmaapbc.properties274
193 files changed, 24780 insertions, 847 deletions
diff --git a/dmaap-bc/README.md b/dmaap-bc/README.md
new file mode 100644
index 0000000..14ebef1
--- /dev/null
+++ b/dmaap-bc/README.md
@@ -0,0 +1,172 @@
+#
+# ============LICENSE_START==========================================
+# org.onap.dmaap
+# ===================================================================
+# Copyright © 2018 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 is a trademark and service mark of AT&T Intellectual Property.
+#
+#
+DMaaP Bus Controller API
+=======================
+
+Data Movement as a Platform (DMaaP) Bus Controller provides an API for other ONAP 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
+```
+
+### 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
+```
+
+A description of the API is generated, and found in targets/generated-source/swagger.json.
+
+### Properties File
+
+This section is intended to describe the behavior customization of Bus Controller that can be obtained via properties file used by the dbcapi library.
+By default, this file is located in etc/dmaapbc.properties.
+However, a java argument -DConfigFile can be set to a different path. (Our kubernetes deployment relies on this and points to a configmap, for example.)
+
+The table below lists all the settings, default values (if not set), and shows any explicit setting in ONAP oom kubernetes deployment.
+
+|-|-|-|-|
+| Property | Description | Default | ONAP Kubernetes Setting |
+|-|-|-|-|
+|UseAAF | Flag for whether AAF authz API is to be used | false | false |
+|-|-|-|-|
+|csit | Flag for stubbing out many southbound calls in a CSIT environment | No | No |
+|-|-|-|-|
+|DR.provhost | FQDN of Data Router Provisioning Server (deprecated - now set via API) | notSet | dcae-drps.domain.not.set |
+|-|-|-|-|
+|ProvisioningURI | URI to retrieve dynamic DR configuration | /internal/prov | /internal/prov |
+|-|-|-|-|
+|Feed.deleteHandling | indicator for handling feed delete request | DeleteOnDR | SimulateDelete |
+| | DeleteOnDR - means use the DR API to DELETE a feed. (default for backwards compatibility) | | |
+| | SimulateDelete - means preserve the feed on DR (after cleaning it up), and mark as DELETED in DBCL. | | |
+|-|-|-|-|
+|UsePGSQL | flag indicates whether to retain data in Postgresql | false | true |
+| | when false, objects will be kept in memory but will be | | |
+| | lost on restart and not shared between instances | | |
+|-|-|-|-|
+|DB.host | FQDN or service name of Postresql host | dcae-pstg-write-ftl.domain.notset.com | dbc-pg-primary |
+|-|-|-|-|
+|DB.name | name of Postresql database | dmaap | |
+|-|-|-|-|
+|DB.schema | name of database schema | public | |
+|-|-|-|-|
+|DB.user | username for Postgresql access | dmaap_admin | |
+|-|-|-|-|
+|DB.cred | password for Postrgresql access | test234-ftl | onapdemodb |
+|-|-|-|-|
+|MR.multisite | Indicates if there can be multiple sites (locations) where MR is deployed | true | false |
+|-|-|-|-|
+|MR.CentralCname | FQDN or service name of MR (deployed in central if multilocation is true) | MRcname.not.set | message-router |
+|-|-|-|-|
+|MR ClientDeleteLevel | MR Client Delete thoroughness | 0 | 1 |
+| | 0 = don't delete | | |
+| | 1 = delete from persistent store (PG) | | |
+| | 2 = delete from persistent store (PG) and authorization store (AAF) | | |
+|-|-|-|-|
+|MR.TopicFactoryNS | AAF namespace used to create perms for MR topics | MR.topicFactoryNS.not.set | org.onap.dmaap.mr.topicFactory |
+|-|-|-|-|
+|MR.TopicMgrRole | AAF Role used by Buscontroller to create topics on MR | MR.TopicMgrRole.not.set | org.onap.dmaap-bc-topic-mgr.client |
+|-|-|-|-|
+|MR.projectID | Value for some constructs of fully qualified topic names | 99999 | ONAP |
+|-|-|-|-|
+|MR.hostnameVerify | Indicates if we want to relax hostname verification on SSL connection | true | false |
+|-|-|-|-|
+|MR.authentication | Authentication method used when connecting to MR | none | basicAuth |
+| | none = no creds sent (default) | | |
+| | basicAuth = formulate Basic Auth HTTP Header using name and pwd credentials | | |
+| | cert = use client certificate | | |
+|-|-|-|-|
+|cadi.properties | Path to CADI properties file | /opt/app/osaaf/local/org.onap.dmaap-bc.props | /opt/app/osaaf/lcoal/org.onap.dmaap-bc.props |
+|-|-|-|-|
+|aaf.URL | URL of the AAF server | https://authentication.domain.netset.com:8100/proxy/ | https://aaf-service.onap:8100/ |
+|-|-|-|-|
+|aaf.TopicMgrUser | AAF Identity of Topic Mgr | noMechId@domain.netset.com | dmaap-bc-topic-mgr@dmaap-bc-topic-mgr.onap.org |
+|-|-|-|-|
+|aaf.TopicMgrPassword | AAF Credential for Topic Mgr | notSet | demo123456! |
+|-|-|-|-|
+|aaf.AdminUser | AAF Identity of user with Admin role for API namespace | noMechId@domain.netset.com | aaf_admin@people.osaaf.org |
+|-|-|-|-|
+|aaf.AdminPassword | AAF credential of AdminUser | notSet | demo123456! |
+|-|-|-|-|
+|aaf.NsOwnerIdentity | AAF Identity to be used as topic Namespace owner | notSet | aaf_admin@people.osaaf.org |
+|topicNsRoot | AAF namespace value used to create FQTN | org.onap.dcae.dmaap | org.onap.dcae.dmaap |
+|-|-|-|-|
+|CredentialCodeKeyfile | location of the codec keyfile used to decrypt passwords | LocalKey | etc/LocalKey |
+| | in this properties file before they are passed to AAF | LocalKey | etc/LocalKey |
+|-|-|-|-|
+|AafDecryption.Class | Specifies the Class to be used for decryption | org.onap.dmaap.dbcapi.aaf.ClearDecrypt | |
+|-|-|-|-|
+|ApiNamespace | Root namespace for AAF perms related to dbcapi access | apiNamespace.not.set | org.onap.dmaap-bc.api |
+|-|-|-|-|
+|ApiPermission.Class | the Class that determines if a call to API is authorized| allow | |
+|-|-|-|-|
+|MM.ProvRole | AAF Role of client publishing MM prov cmds | notSet | org.onap.dmaap-bc-mm-prov.prov |
+|-|-|-|-|
+|MM.ProvUserMechId | AAF Identity when publishing to MM command topic | notSet | dmaap-bc-mm-prov@dmaap-bc-mm-prov.onap.org|
+|-|-|-|-|
+|MM.ProvUserPwd | AAF credenital for ProvUserMechId | notSet | demo123456! |
+|-|-|-|-|
+|MM.AgentRole | AAF Role of client susbcribing to MM command topic | notSet | org.onal.dmaap-bc-mm-prov.agent |
+|-|-|-|-|
+|DR.provApi | Version name of DR API (ONAP or AT&T) | ONAP | ONAP |
+|-|-|-|-|
+|DR.onBehalfHeader | String for "On Behalf Of" HTTP Header in DR API | X-DR-ON-BEHALF-OF | X-DR-ON-BEHALF-OF |
+|-|-|-|-|
+|DR.feedContentType | Value for Content-Type Header in DR Feed API | application/vnd.dr.feed | application/vnd.dr.feed |
+|-|-|-|-|
+|DR subContentType | Value for Content-Type Header in DR Subscription API | application/vnd.dr.subscription | application/vnd.dr.subscription |
+|-|-|-|-|
+|HttpAllowed | flag indicating whether http is supported | false | true |
+|-|-|-|-|
+|IntHttpPort | Internal port for http service | 80 | 8080 |
+|-|-|-|-|
+|IntHttpsPort | Internal port for https service (0 if no cert is avail) | 443 | 8443 |
+|-|-|-|-|
+|ExtHttpsPort | Externally advertised port for https service (deprecated)| 443 | 443 |
+|-|-|-|-|
+|KeyStoreType | Format of Java keystore | jks | jks |
+|-|-|-|-|
+|KeyStoreFile | Path to java keystore | etc/keystore | etc/keystore |
+|-|-|-|-|
+|KeyStorePassword | Password for keystore | changeit | <provided by Certificate Authority> |
+|-|-|-|-|
+|KeyPassword | Password for private key in the https keystore | changeit | <provided by Certificate Authority> |
+|-|-|-|-|
+|TrustStoreType | Format of Trust Store file | jks | jks |
+|-|-|-|-|
+|TrustStoreFile | Path to Trust Store file | | etc/org.onap.dmaap-bc.trust.jks |
+|-|-|-|-|
+|TrustStorePassword | Password for Trust Store | | <provided by Certificate Authority> |
+|-|-|-|-|
+|QuiesceFile | Path to file which signals needs to queiesce | | etc/SHUTDOWN |
+|-|-|-|-|
+
diff --git a/dmaap-bc/misc/dbc-api.jks b/dmaap-bc/misc/dbc-api.jks
deleted file mode 100644
index 66142d3..0000000
--- a/dmaap-bc/misc/dbc-api.jks
+++ /dev/null
Binary files differ
diff --git a/dmaap-bc/misc/opensource.env b/dmaap-bc/misc/opensource.env
deleted file mode 100644
index a74d333..0000000
--- a/dmaap-bc/misc/opensource.env
+++ /dev/null
@@ -1,120 +0,0 @@
-#
-#
-# ============LICENSE_START==========================================
-# org.onap.dmaap
-# ===================================================================
-# Copyright © 2018 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 is a trademark and service mark of AT&T Intellectual Property.
-#
-#
-# The Controller domain
-#
-CONT_DOMAIN=simpledemo.onap.org
-#
-# The https port
-# set to 0 if certificate is not ready
-DMAAPBC_INT_HTTPS_PORT=0
-
-#
-# The path to the keystore for https
-#
-DMAAPBC_KSTOREFILE=/opt/app/dcae-certificates
-
-# The password for the https keystore
-#
-DMAAPBC_KSTOREPASS=foofoofoo
-#
-# The password for the private key in the https keystore
-#
-DMAAPBC_PVTKEYPASS=barbarbar
-#
-# Flag for whether we are using PG connection for persistence
-#
-DMAAPBC_PG_ENABLED=false
-#
-# The host for postgres access
-#
-DMAAPBC_PGHOST=zldciad1vipstg00.${CONT_DOMAIN}
-#
-# For postgres access
-#
-DMAAPBC_PGCRED=test234-ftl
-#
-# Name of this environment
-#
-DMAAPBC_INSTANCE_NAME=onap1
-#
-# Name of DR prov server
-#
-DMAAPBC_DRPROV_FQDN=dcae-drps.${CONT_DOMAIN}
-
-#################
-# AAF Properties:
-#
-# regarding password encryption:
-# In the dependencies that Maven retrieves (e.g., under dcae_dmaapbc/target/deps/ is a jar file cadi-core-version.jar. Generate the key file with:
-#
-# java \u2013jar wherever/cadi-core-*.jar keygen keyfilename
-# chmod 400 keyfilename
-#
-# To encrypt a key:
-#
-# java \u2013jar wherever/cadi-core-*.jar digest password-to-encrypt keyfilename
-#
-# This will generate a string. Put \u201Cenc:\u201D on the front of the string, and put the result in this properties file.
-#
-# Location of the Codec Keyfile which is used to decrypt passwords in this properties file before they are passed to AAF
-#
-# REF: https://wiki.domain.notset.com/display/cadi/CADI+Deployment
-#
-# URL of AAF environment to use.
-#
-DMAAPBC_AAF_URL=https://aafapi.${CONT_DOMAIN}:8100/proxy/
-#
-# TopicMgr mechid@namespace
-#
-DMAAPBC_TOPICMGR_USER=m99751@dmaapBC.onap.org
-#
-# TopicMgr password
-#
-DMAAPBC_TOPICMGR_PWD=enc:zyRL9zbI0py3rJAjMS0dFOnYfEw_mJhO
-#
-# Bus Controller Namespace Admin mechid@namespace
-#
-DMAAPBC_ADMIN_USER=m99501@dcae.onap.org
-#
-# Bus Controller Namespace Admin password
-#
-DMAAPBC_ADMIN_PWD=enc:YEaHwOJrwhDY8a6usetlhbB9mEjUq9m
-
-#
-# endof AAF Properties
-#################
-
-#################
-# PolicyEngine Properties
-
-#
-# Flag to turn on/off Authentication
-DMAAPBC_PE_ENABLED=false
-#
-# Argument to decisionAttributes.put("AAF_ENVIRONMENT", X);
-# where X is: TEST= UAT, PROD = PROD, DEVL = TEST
-#
-DMAAPBC_PE_AAF_ENV=DEMO
-
-# endof PolicyEngineProperties
-#################
diff --git a/dmaap-bc/misc/policyLogger.properties b/dmaap-bc/misc/policyLogger.properties
deleted file mode 100644
index 6b9ad99..0000000
--- a/dmaap-bc/misc/policyLogger.properties
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# ============LICENSE_START==========================================
-# org.onap.dmaap
-# ===================================================================
-# Copyright © 2018 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 is a trademark and service mark of AT&T Intellectual Property.
-#
-#
-################################### 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/dmaap-bc/pom.xml b/dmaap-bc/pom.xml
index ded2cc2..e141100 100644
--- a/dmaap-bc/pom.xml
+++ b/dmaap-bc/pom.xml
@@ -19,298 +19,40 @@
============LICENSE_END============================================
ECOMP is a trademark and service mark of AT&T Intellectual Property.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>dmaap-bc</artifactId>
<version>${revision}</version>
<name>dmaap-bc</name>
+ <packaging>jar</packaging>
<parent>
<groupId>org.onap.dmaap.buscontroller</groupId>
<artifactId>parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <build>
- <finalName>dmaap-bc</finalName>
-
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-enforcer-plugin</artifactId>
- <executions>
- <execution>
- <id>enforce-no-snapshots</id>
- <goals>
- <goal>enforce</goal>
- </goals>
- <configuration>
- <rules>
- <requireReleaseDeps>
- <message>No Snapshots Allowed!</message>
- <excludes>
-<!-- for example, these might be needed...
- <exclude>org.onap.dmaap.dbcapi:dbcapi</exclude>
- <exclude>org.onap.aaf.authz:aaf-cadi-client</exclude>
- <exclude>org.onap.aaf.authz:aaf-misc-env</exclude>
- <exclude>org.onap.aaf.authz:aaf-cadi-aaf</exclude>
- <exclude>org.onap.aaf.authz:aaf-auth-client</exclude>
- <exclude>org.onap.aaf.authz:aaf-cadi-core</exclude>
- <exclude>org.onap.aaf.authz:aaf-misc-rosetta</exclude>
--->
- </excludes>
- </requireReleaseDeps>
- </rules>
- <fail>true</fail>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <!-- Package an Uber jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.4.3</version>
- <executions>
- <!-- Run shade goal on package phase -->
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <createDependencyReducedPom>false</createDependencyReducedPom>
- <!-- this filter section is needed to avoid runtime error:
- java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
- suggestion found at: https://stackoverflow.com/q/999489
- -->
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- <transformers>
- <!-- NOTE: Need the following transformer else gets "Could not resolve type id 'https' into a subtype" error
- Solution found from here:
- http://stackoverflow.com/questions/27543060/why-does-dropwizard-configuration-is-not-working
- Some more context here:
- https://github.com/dropwizard/dropwizard/issues/455 -->
- <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
- <!-- add Main-Class to manifest file -->
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.onap.dmaap.dbcapi.server.Main</mainClass>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <!-- for Distribution management -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-webdav-jackrabbit</artifactId>
- <version>2.10</version>
- </dependency>
- </dependencies>
- </plugin>
-
- </plugins>
- <pluginManagement>
- <plugins>
- <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>1.0.0</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <versionRange>[2.10,)</versionRange>
- <phase>install</phase>
- <goals>
- <goal>copy-dependencies</goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <ignore/>
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
- <profiles>
- <profile>
- <id>docker</id>
- <properties>
- <skipDockerBuild>false</skipDockerBuild>
- <skipDockerTag>false</skipDockerTag>
- <skipTests>true</skipTests>
- </properties>
- <build>
- <!-- Copy files to docker-stage to be included in image -->
- <resources>
- <resource>
- <targetPath>${basedir}/target/docker-stage</targetPath>
- <directory>${basedir}/src/main/resources</directory>
- <includes>
- <include>Dockerfile</include>
- </includes>
- </resource>
- <resource>
- <targetPath>${basedir}/target/docker-stage/opt/app/dmaapbc/etc</targetPath>
- <directory>${basedir}/misc</directory>
- <includes>
- <include>LocalKey</include>
- <include>logback.xml</include>
- </includes>
- </resource>
-
- <resource>
- <targetPath>${basedir}/target/docker-stage/opt/app/dmaapbc/etc</targetPath>
- <directory>${multiproject.basedir}</directory>
- <includes>
- <include>version.properties</include>
- </includes>
- </resource>
- <resource>
- <targetPath>${basedir}/target/docker-stage/opt/app/dmaapbc/misc</targetPath>
- <directory>${basedir}/misc</directory>
- <includes>
- <include>opensource.env</include>
- <include>*.tmpl</include>
- </includes>
- </resource>
- <resource>
- <targetPath>${basedir}/target/docker-stage/opt/app/dmaapbc/bin</targetPath>
- <directory>${basedir}/misc</directory>
- <includes>
- <include>dmaapbc</include>
- </includes>
- </resource>
- </resources>
- <plugins>
- <!-- Copy jar to docker-stage to be included in image -->
- <plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.7</version>
- <executions>
- <execution>
- <id>copy-jar</id>
- <phase>package</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/target/docker-stage/opt/app/dmaapbc/lib</outputDirectory>
- <resources>
- <resource>
- <directory>${multiproject.basedir}/dmaap-bc/target</directory>
- <includes>
- <include>dmaap-bc.jar</include>
- </includes>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <!-- Setup image tags per https://wiki.onap.org/display/DW/Independent+Versioning+and+Release+Process#IndependentVersioningandReleaseProcess-StandardizedDockerTagging -->
- <plugin>
- <groupId>org.codehaus.groovy.maven</groupId>
- <artifactId>gmaven-plugin</artifactId>
- <executions>
- <execution>
- <phase>validate</phase>
- <goals>
- <goal>execute</goal>
- </goals>
- <configuration>
- <properties>
- <ver>${project.version}</ver>
- <timestamp>${maven.build.timestamp}</timestamp>
- </properties>
- <source>
- println 'ver: ' + project.properties['ver'];
- if ( project.properties['ver'].endsWith("-SNAPSHOT") ) {
- project.properties['dockertag1']=project.properties['ver'] + "-latest";
- project.properties['dockertag2']=project.properties['ver'] + "-" + project.properties['timestamp'];
- } else {
- project.properties['dockertag1']=project.properties['ver'] + "-STAGING-latest";
- project.properties['dockertag2']=project.properties['ver'] + "-STAGING-" + project.properties['timestamp'];
- }
- println 'docker tag 1: ' + project.properties['dockertag1'];
- println 'docker tag 2: ' + project.properties['dockertag2'];
- </source>
- </configuration>
- </execution>
- </executions>
- </plugin>
+ <description>Data Movement as a Platform (DMaaP) Bus Controller provides a REST 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.
+ </description>
+ <properties>
+ <sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}
+ </sitePath>
+ <eelf.version>1.0.0</eelf.version>
+ <dmaapbc.image.name>${docker.image.root}${project.artifactId}</dmaapbc.image.name>
+ <swagger.version>1.5.19</swagger.version>
+ <jackson.version>2.9.5</jackson.version>
+ <jersey.version>2.29</jersey.version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <jettyVersion>9.4.40.v20210413</jettyVersion>
+ <eelf.version>1.0.0</eelf.version>
+ <junit.version>4.12</junit.version>
+ <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**</sonar.exclusions>
+ <docker-stage.target.path>/target/docker-stage/opt/app/dmaapbc/</docker-stage.target.path>
+ </properties>
- <plugin>
- <groupId>io.fabric8</groupId>
- <artifactId>docker-maven-plugin</artifactId>
- <version>0.28.0</version>
- <configuration>
- <verbose>${docker.verbose}</verbose>
- <apiVersion>${docker.apiVersion}</apiVersion>
- <pullRegistry>${docker.pull.registry}</pullRegistry>
- <pushRegistry>${docker.push.registry}</pushRegistry>
- <images>
- <image>
- <name>${docker.image}</name>
- <build>
- <cleanup>try</cleanup>
- <dockerFileDir>${basedir}/target/docker-stage</dockerFileDir>
- <dockerFile>Dockerfile</dockerFile>
- <tags>
- <tag>${dockertag1}</tag>
- <tag>${dockertag2}</tag>
- </tags>
- </build>
- </image>
- </images>
- </configuration>
- <executions>
- <execution>
- <id>generate-images</id>
- <phase>install</phase>
- <goals>
- <goal>build</goal>
- </goals>
- </execution>
- <execution>
- <id>push-images</id>
- <phase>deploy</phase>
- <goals>
- <goal>push</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
<dependencyManagement>
<dependencies>
<dependency>
@@ -322,8 +64,35 @@
</dependency>
</dependencies>
</dependencyManagement>
+
<dependencies>
<dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-moxy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <!-- use this if compatibility issues with jetty artifactId:
+ <artifactId>jersey-test-framework-provider-jetty</artifactId>
+ <version>${jersey.version}</version>
+ -->
+ <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
+ <version>2.29.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-hk2</artifactId>
+ <version>2.29.1</version>
+ </dependency>
+ <dependency>
<groupId>org.onap.aaf.authz</groupId>
<artifactId>aaf-cadi-aaf</artifactId>
<version>2.1.7</version>
@@ -332,12 +101,12 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
- <version>2.9.5</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
- <version>2.9.5</version>
+ <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
@@ -349,6 +118,10 @@
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
+ <!-- DMAAP-656:
+ - override this dependency because it utilized a third party
+ - lib called com.google.guava:20.0 which had severe security threat identified.
+ -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@@ -358,6 +131,12 @@
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>${swagger.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
@@ -370,29 +149,10 @@
<version>${swagger.version}</version>
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.containers</groupId>
- <artifactId>jersey-container-servlet-core</artifactId>
- <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
- <!-- artifactId>jersey-container-servlet</artifactId -->
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.media</groupId>
- <artifactId>jersey-media-moxy</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jettyVersion}</version>
+ <scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@@ -424,50 +184,20 @@
<version>42.2.14</version>
</dependency>
<dependency>
- <groupId>org.onap.dmaap.dbcapi</groupId>
- <artifactId>dbcapi</artifactId>
- <version>2.0.4</version>
- </dependency>
- <dependency>
- <groupId>com.att.eelf</groupId>
- <artifactId>eelf-core</artifactId>
- <version>${eelf.version}</version>
- </dependency>
- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.test-framework.providers</groupId>
- <!-- use this if compatibility issues with jetty artifactId:
- <artifactId>jersey-test-framework-provider-jetty</artifactId>
- <version>${jersey.version}</version>
- -->
- <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
- <version>2.29.1</version>
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.inject</groupId>
- <artifactId>jersey-hk2</artifactId>
- <version>2.29.1</version>
- </dependency>
- <dependency>
<!-- use 2.3.1 to avoid this issue: https://github.com/eclipse-ee4j/jaxb-ri/issues/1222 -->
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
- <groupId>javax.activation</groupId>
- <artifactId>javax.activation-api</artifactId>
- <version>1.2.0</version>
- </dependency>
-
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.12</version>
+ <version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -476,12 +206,264 @@
<version>1.1.0</version>
<scope>test</scope>
</dependency>
+ <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>3.9.0</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
</dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>${eelf.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
+ <build>
+ <finalName>dmaap-bc</finalName>
+ <!-- Copy files to docker-stage to be included in image -->
+ <resources>
+ <resource>
+ <targetPath>${basedir}/target/docker-stage</targetPath>
+ <directory>${basedir}/src/main/resources/docker</directory>
+ <includes>
+ <include>Dockerfile</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>${basedir}${docker-stage.target.path}etc</targetPath>
+ <directory>${basedir}/src/main/resources/misc</directory>
+ <includes>
+ <include>logback.xml</include>
+ <include>LocalKey</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>${basedir}${docker-stage.target.path}etc</targetPath>
+ <directory>${multiproject.basedir}</directory>
+ <includes>
+ <include>version.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>${basedir}${docker-stage.target.path}misc</targetPath>
+ <directory>${basedir}/src/main/resources/misc</directory>
+ <includes>
+ <include>*.tmpl</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>${basedir}${docker-stage.target.path}bin</targetPath>
+ <directory>${basedir}/src/main/resources/misc</directory>
+ <includes>
+ <include>dmaapbc</include>
+ </includes>
+ </resource>
+ <resource>
+ <targetPath>${basedir}${docker-stage.target.path}misc</targetPath>
+ <directory>${basedir}/src/main/resources/misc</directory>
+ <includes>
+ <include>schema_all.sql</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <outputDirectory>${basedir}/target/docker-stage/opt/app/dmaapbc/lib</outputDirectory>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <mainClass>org.onap.dmaap.dbcapi.server.Main</mainClass>
+ </manifest>
+ </archive>
+ <finalName>dmaap-bc.jar</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <!-- this is used for inheritance merges -->
+ <phase>package</phase>
+ <!-- bind to the packaging phase -->
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>onap-java-style</id>
+ <configuration>
+ <consoleOutput>false</consoleOutput>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- reference: https://tech.homeaway.com/development/2016/06/02/generating-swagger-spec.html -->
+ <plugin>
+ <groupId>com.github.kongchen</groupId>
+ <artifactId>swagger-maven-plugin</artifactId>
+ <version>3.1.5</version>
+ <configuration>
+ <apiSources>
+ <apiSource>
+ <springmvc>false</springmvc>
+ <locations>
+ <location>org.onap.dmaap.dbcapi.resources</location>
+ </locations>
+ <schemes>
+ <scheme>http</scheme>
+ <scheme>https</scheme>
+ </schemes>
+ <host>www.[host]:[port]</host>
+ <basePath>/webapi</basePath>
+ <info>
+ <title>DMaaP Bus Controller REST API</title>
+ <version>1.1.0</version>
+ <description>
+ provides an API for OpenDCAE components which need to provision
+ underlying DMaaP technologies (Data Router and Message Router).
+ Primary clients for this API are anticipated to be the OpenDCAE
+ Controller, OpenDCAE Orchestrator, OpenDCAE Inventory and the
+ ECOMP Portal.
+
+ Objects managed by DMaaP are deployed in a dcaeLocation which is
+ a unique identifier for an OpenStack tenant for a dcaeLayer,
+ opendcae-central (aka ecomp) or opendcae-local-ntc (aka edge).
+
+ A dcaeEnvironment (e.g. FTL or prod) has a single DMaaP. A
+ DMaaP is managed by a one or more stateless DMaaP Bus
+ Controller(s), though Bus Controller relies on PGaaS for
+ persistence. Each DMaaP has a single instance of Data Router,
+ which has 1 or more DR_Nodes deployed at each dcaeLocation. DR
+ Clients of type DR_Pub generally publish to a DR_Node that is
+ local to its dcaeLocation. Routing for a Feed is determined by
+ the dcaelocation of its DR_Sub clients.
+
+ A DMaaP may have many Message Router instances. Each instance is
+ deployed as an MR_Cluster. One MR_Cluster is deployed at each
+ dcaeLocation. MR_Clients generally communicate to the
+ MR_Cluster at the same dcaeLocation. Replication of messages
+ between MR_Clusters is accomplished by MR Bridge, which is
+ provioned by DMaaP Bus Controller based on Topic attributes.
+
+ Therefore, the role of DMaaP Bus Controller is to support other
+ DCAE infrastructure components to dynamically provision DMaaP
+ services on behalf of DMaaP clients, and to assist in any
+ management or discovery activity of its clients.
+
+ A convention of this API is to return JSON responses per
+ OpenStack style.
+ </description>
+ <termsOfService>
+ http://www.apache.org/licenses/LICENSE-2.0
+ </termsOfService>
+ <contact>
+ <url>http://www.onap.org</url>
+ </contact>
+ <license>
+ <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+ <name>Licensed under the Apache License, Version 2.0</name>
+ </license>
+ </info>
+ <swaggerDirectory>target/generated-sources/</swaggerDirectory>
+ </apiSource>
+ </apiSources>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>compile</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>docker</id>
+ <properties>
+ <skipDockerBuild>${skip.docker.build}</skipDockerBuild>
+ <skipDockerTag>${skip.docker.tag}</skipDockerTag>
+ <skipTests>false</skipTests>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>0.28.0</version>
+ <configuration>
+ <verbose>${docker.verbose}</verbose>
+ <apiVersion>${docker.apiVersion}</apiVersion>
+ <pullRegistry>${docker.pull.registry}</pullRegistry>
+ <pushRegistry>${docker.push.registry}</pushRegistry>
+ <images>
+ <image>
+ <name>${dmaapbc.image.name}</name>
+ <build>
+ <cleanup>try</cleanup>
+ <dockerFileDir>${basedir}/target/docker-stage</dockerFileDir>
+ <dockerFile>Dockerfile</dockerFile>
+ <tags>
+ <tag>${dockertag1}</tag>
+ <tag>${dockertag2}</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ <executions>
+ <execution>
+ <id>generate-images</id>
+ <phase>install</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>push-images</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>push</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
<reporting>
<plugins>
<plugin>
@@ -502,45 +484,10 @@
</plugin>
</plugins>
</reporting>
-
<distributionManagement>
<site>
<id>ecomp-site</id>
<url>dav:${nexusproxy}${sitePath}</url>
</site>
</distributionManagement>
- <properties>
- <multiproject.basedir>${basedir}/..</multiproject.basedir>
- <docker.maven.plugin.version>1.0.0</docker.maven.plugin.version>
- <jersey.version>2.29</jersey.version>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <log4j.version>2.13.3</log4j.version>
- <jettyVersion>9.4.36.v20210114</jettyVersion>
- <eelf.version>1.0.0</eelf.version>
- <swagger.version>1.5.19</swagger.version>
- <timestamp>${maven.build.timestamp}</timestamp>
- <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
- <!-- SONAR -->
- <jacoco.version>0.7.7.201606060606</jacoco.version>
- <sonar-jacoco-listeners.version>3.2</sonar-jacoco-listeners.version>
- <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
- <!-- Default Sonar configuration -->
- <sonar.jacoco.reportPath>target/code-coverage/jacoco-ut.exec</sonar.jacoco.reportPath>
- <sonar.jacoco.itReportPath>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
- <!-- Note: This list should match jacoco-maven-plugin's exclusion list below -->
- <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**</sonar.exclusions>
-
- <!-- docker image -->
- <docker.image>onap/dmaap/dmaap-bc</docker.image>
-
- <nexusproxy>https://nexus.onap.org</nexusproxy>
- <docker.push.registry>10.12.5.45:5000</docker.push.registry>
-
- <timestamp>${maven.build.timestamp}</timestamp>
- <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
-
- <!-- for Distribution Management -->
- <sitePath>/content/sites/site/org/onap/dmaap/dmaap-bc/${revision}</sitePath>
- </properties>
- <description>Packaging Platform (DMaaP) Bus Controller API as a Docker container.</description>
</project>
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafConnection.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafConnection.java
new file mode 100644
index 0000000..934e541
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafConnection.java
@@ -0,0 +1,329 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.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 java.net.ConnectException;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.commons.codec.binary.Base64;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+public class AafConnection extends BaseLoggingClass {
+
+
+
+
+
+ private String aafCred;
+ private String unit_test;
+
+
+ private HttpsURLConnection uc;
+
+
+ public AafConnection( String cred ) {
+ aafCred = cred;
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ unit_test = p.getProperty( "UnitTest", "No" );
+
+ }
+
+
+ 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 ( UnknownHostException uhe ) {
+ errorLogger.error(DmaapbcLogMessageEnum.UNKNOWN_HOST_EXCEPTION, pURL, uhe.getMessage() );
+ logger.error("Error", uhe);
+ return(false);
+ } catch (Exception e) {
+ logger.error("Error", e);
+ errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_ERROR, pURL, e.getMessage());
+ 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 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.IO_EXCEPTION + ex.getMessage(),ex);
+ }
+
+ return sb.toString();
+ }
+
+
+
+ public int postAaf( AafObject obj, String pURL ) {
+ logger.info( "entry: postAaf() to " + pURL );
+ String auth = "Basic " + Base64.encodeBase64String(aafCred.getBytes());
+ int rc = -1;
+
+
+ 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);
+
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ uc.setSSLSocketFactory(sc.getSocketFactory());
+ OutputStream os = null;
+
+
+ try {
+ uc.connect();
+ os = uc.getOutputStream();
+ os.write( postData );
+
+ } catch (ProtocolException pe) {
+ logger.error("Error", 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) {
+ logger.error("Error", e);
+ }
+ } catch ( SSLHandshakeException she ) {
+ logger.error("Error", she);
+ errorLogger.error( DmaapbcLogMessageEnum.SSL_HANDSHAKE_ERROR, pURL);
+ } catch ( UnknownHostException uhe ) {
+ logger.error("Error", uhe);
+ errorLogger.error(DmaapbcLogMessageEnum.UNKNOWN_HOST_EXCEPTION, pURL, uhe.getMessage() );
+ rc = 500;
+ return rc;
+ } catch ( ConnectException ce ) {
+ logger.error("Error", ce);
+ if ( "Yes".equals(unit_test) ) {
+ rc = 201;
+ return rc;
+ }
+ errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, pURL, ce.getMessage() );
+ rc = 500;
+ return rc;
+ }
+ try {
+ rc = uc.getResponseCode();
+ } catch ( SSLHandshakeException she ) {
+ logger.error("Error", she);
+ errorLogger.error( DmaapbcLogMessageEnum.SSL_HANDSHAKE_ERROR, 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) {
+ logger.error("Unable to read response ");
+ logger.error("Error", e);
+ }
+ finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ logger.error("Error", e);
+ }
+ }
+ return rc;
+
+ }
+
+ public int delAaf(AafObject obj, String pURL) {
+ logger.info( "entry: delAaf() to " + pURL );
+ String auth = "Basic " + Base64.encodeBase64String(aafCred.getBytes());
+ int rc = -1;
+
+
+ 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("DELETE");
+ 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) {
+ logger.error("Error", 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) {
+ logger.error("Error", e);
+ }
+ } catch ( SSLHandshakeException she ) {
+ errorLogger.error( DmaapbcLogMessageEnum.SSL_HANDSHAKE_ERROR +"For:- "+pURL,she);
+ }
+ try {
+ rc = uc.getResponseCode();
+ } catch ( SSLHandshakeException she ) {
+ logger.error("Error", she);
+ errorLogger.error( DmaapbcLogMessageEnum.SSL_HANDSHAKE_ERROR, 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) {
+ logger.error("Unable to read response ");
+ logger.error("Error", e);
+ }
+ return rc;
+
+ }
+
+ private TrustManager[] trustAllCerts = new TrustManager[]{
+ new X509TrustManager() {
+
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers()
+ {
+ return null;
+ }
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
+ {
+ //No need to implement.
+ }
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
+ {
+ //No need to implement.
+ }
+ }
+ };
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafDecrypt.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafDecrypt.java
new file mode 100644
index 0000000..bf5ecf2
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafDecrypt.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.io.IOException;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class AafDecrypt extends BaseLoggingClass {
+ String dClass;
+ DecryptionInterface dec = null;
+
+ public AafDecrypt() {
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ dClass = p.getProperty( "AafDecryption.Class", "org.onap.dmaap.dbcapi.aaf.ClearDecrypt");
+ try {
+ dec = (DecryptionInterface) (Class.forName(dClass).newInstance());
+ dec.init(p.getProperty("CredentialCodecKeyfile", "LocalKey"));
+ } catch (Exception ee ) {
+ logger.error("Error", ee);
+ errorLogger.error(DmaapbcLogMessageEnum.UNEXPECTED_CONDITION, "attempting to instantiate " + dClass );
+ }
+ }
+
+ public String decrypt( String encPwd ) {
+
+ String pwd = "notDecrypted";
+ try {
+ pwd = dec.decrypt( encPwd );
+ } catch( IOException io ) {
+ logger.error("Error", io);
+ errorLogger.error(DmaapbcLogMessageEnum.DECRYPT_IO_ERROR, dClass, encPwd );
+ }
+
+ return pwd;
+
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafEmpty.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafEmpty.java
new file mode 100644
index 0000000..87e56c4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafEmpty.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.aaf;
+
+class AafEmpty extends AafObject {
+ @Override
+ String toJSON() {
+ return "";
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafLurService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafLurService.java
new file mode 100644
index 0000000..fa49ae8
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafLurService.java
@@ -0,0 +1,140 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.cadi.aaf.AAFPermission;
+import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
+import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;
+import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;
+import org.onap.aaf.cadi.principal.UnAuthPrincipal;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+/*
+ * this service uses the AAF Lur object to lookup identities and perms
+ */
+public class AafLurService extends BaseLoggingClass {
+
+ private static AAFConHttp aafcon;
+ private static AAFLurPerm aafLur;
+ private static AAFAuthn<?> aafAuthn;
+
+
+ /*
+ * singleton pattern suggested by AAF
+ */
+ private static AafLurService singleton;
+ private AafLurService() {}
+
+
+
+ private static void init( Access myAccess ) throws APIException, CadiException, LocatorException {
+ appLogger.info( "myAccess=" + myAccess );
+ try {
+ aafcon = new AAFConHttp( myAccess );
+ } catch ( CadiException | LocatorException e) {
+ appLogger.error( "Failure of AAFConHttp: " + e.getMessage() );
+ errorLogger.error( "Failure of AAFConHttp: " + e.getMessage() );
+ errorLogger.error(e.getMessage());
+
+ throw e;
+ }
+ try {
+ aafLur = aafcon.newLur();
+ } catch ( CadiException e) {
+ appLogger.error( "Failure of newLur(): " + e.getMessage() );
+ errorLogger.error( "Failure of newLur(): " + e.getMessage() );
+ errorLogger.error(e.getMessage());
+
+ throw e;
+ }
+ aafAuthn = aafcon.newAuthn( aafLur );
+ }
+
+ public static synchronized AafLurService getInstance( Access myAccess ) throws APIException, CadiException, LocatorException{
+ if ( singleton == null ) {
+ singleton = new AafLurService();
+ try {
+ init( myAccess );
+ } catch (APIException | CadiException | LocatorException e) {
+ errorLogger.error(e.getMessage());
+ throw e;
+ }
+
+ }
+ return singleton;
+ }
+
+
+ public boolean checkPerm(String ns, String fqi, String pwd, DmaapPerm p) throws IOException, CadiException {
+
+ boolean rc = false;
+
+ if ( aafAuthn == null ) {
+ appLogger.error( "AafLurService: aafAuthn not set as expected.");
+ return rc;
+ }
+
+ String ok = aafAuthn.validate( fqi, pwd );
+ if ( ok != null ) {
+ appLogger.info( "FAILED validation of fqi=" + fqi + "with response:" + ok );
+ return rc;
+ }
+
+ Principal principal = new UnAuthPrincipal( fqi );
+ // if we pass ns as first arg to AAFPermission constructor it gets prpended to the instance...
+ // as in ns|instance|type|action. we don't want that.
+ Permission aafPerm = new AAFPermission( null, p.getPermission(), p.getPtype(), p.getAction());
+ if ( aafLur == null ) {
+ appLogger.error( "AafLurService: aafLur not set as expected.");
+ return rc;
+ }
+ rc = aafLur.fish( principal, aafPerm );
+ boolean flag = true;
+ if (rc == flag ) {
+ return rc;
+ }
+
+ List<Permission> perms = new ArrayList<>();
+ aafLur.fishAll( principal, perms);
+ String key = aafPerm.getKey();
+ for ( Permission prm: perms ) {
+ if ( prm.getKey().equals( key )) {
+ appLogger.info( principal + " has MATCHING perm " + prm.getKey() );
+ } else {
+ appLogger.info( principal + " has non-matching perm " + prm.getKey() );
+ }
+ }
+
+ return rc;
+
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafNamespace.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafNamespace.java
new file mode 100644
index 0000000..b6da523
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafNamespace.java
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.util.ArrayList;
+import java.util.Objects;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+public class AafNamespace extends AafObject {
+
+ private String name;
+ private ArrayList<String> admin;
+ private ArrayList<String> responsible;
+
+ // in some environments, an AAF Namespace must be owned by a human.
+ // So, when needed, this var can be set via a property
+ private static String NsOwnerIdentity;
+
+ public AafNamespace(String ns, String identity ) {
+ super();
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ NsOwnerIdentity = p.getProperty( "aaf.NsOwnerIdentity", "");
+ this.admin = new ArrayList<>();
+ this.responsible = new ArrayList<>();
+
+ this.name = ns;
+ this.admin.add( identity );
+ this.responsible.add( NsOwnerIdentity );
+ }
+ public void setName( String ns ) {
+ this.name = ns;
+ }
+ public String getName() {
+ return name;
+ }
+ public ArrayList<String> getAdmin() {
+ return admin;
+ }
+ public void setAdmin(ArrayList<String> admin) {
+ this.admin = admin;
+ }
+ public ArrayList<String> getResponsible() {
+ return responsible;
+ }
+ public void setResponsible(ArrayList<String> responsible) {
+ this.responsible = responsible;
+ }
+
+
+ // given an Array of Strings, return a String that is a separated list of quoted strings.
+ // e.g. input [ a, b, c ]
+ // output "a", "b", "c"
+ private String separatedList( ArrayList<String> list, String sep ) {
+ if (list.isEmpty()) return null;
+ String aList = "";
+ String delim = "";
+ for( String item: list) {
+ if( ! item.isEmpty()) {
+ aList += String.format( "%s\"%s\"", delim, item );
+ delim = sep;
+ }
+ }
+ return aList;
+ }
+
+ public String toJSON() {
+
+ String postJSON = String.format(" { \"name\": \"%s\", \"admin\": [",
+ this.getName()
+ );
+ postJSON += separatedList( this.getAdmin(), "," );
+ postJSON += "], \"responsible\":[";
+ postJSON += separatedList( this.getResponsible(), ",");
+ postJSON += "]}";
+ logger.info( "returning JSON: " + postJSON);
+
+ return postJSON;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AafNamespace that = (AafNamespace) o;
+ return Objects.equals(name, that.name) &&
+ Objects.equals(admin, that.admin) &&
+ Objects.equals(responsible, that.responsible);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, admin, responsible);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafObject.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafObject.java
new file mode 100644
index 0000000..9c8f99e
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafObject.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.nio.charset.StandardCharsets;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public abstract class AafObject extends BaseLoggingClass {
+
+ abstract String toJSON();
+
+ public byte[] getBytes() {
+ return toJSON().getBytes(StandardCharsets.UTF_8);
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafRole.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafRole.java
new file mode 100644
index 0000000..0997dd4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafRole.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.util.Objects;
+
+public class AafRole extends AafObject {
+
+ private String namespace;
+ private String role;
+
+ public AafRole(String ns, String role) {
+ super();
+ this.namespace = ns;
+ this.role = role;
+ }
+ public void setNamespace( String ns ) {
+ this.namespace = ns;
+ }
+ public String getNamespace() {
+ return namespace;
+ }
+ public void setRole(String role) {
+ this.role = role;
+ }
+ public String getRole() {
+ return role;
+ }
+ public String getFullyQualifiedRole() {
+ return namespace + "." + role;
+ }
+
+ public String toJSON() {
+
+ String postJSON = String.format(" { \"name\": \"%s.%s\"}",
+ this.getNamespace(),
+ this.getRole() );
+ logger.info( "returning JSON: " + postJSON);
+
+ return postJSON;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AafRole aafRole = (AafRole) o;
+ return Objects.equals(namespace, aafRole.namespace) &&
+ Objects.equals(role, aafRole.role);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(namespace, role);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafService.java
new file mode 100644
index 0000000..3f009f8
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafService.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+/*
+ * this service uses the AAF REST API endpoints to provision values in AAF
+ */
+public interface AafService {
+ enum ServiceType {
+ AAF_Admin,
+ AAF_TopicMgr
+ }
+
+ String getIdentity();
+
+ int addPerm(DmaapPerm perm);
+
+ int delPerm(DmaapPerm perm, boolean force);
+
+ int addGrant(DmaapGrant grant);
+
+ int addUserRole(AafUserRole ur);
+
+ int addRole(AafRole role);
+
+ int addNamespace(AafNamespace ns);
+
+ int delNamespace(AafNamespace ns, boolean force);
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactory.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactory.java
new file mode 100644
index 0000000..cfde19b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactory.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.aaf;
+
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class AafServiceFactory extends BaseLoggingClass {
+
+ private final DmaapConfig dmaapConfig;
+
+ public AafServiceFactory() {
+ this((DmaapConfig) DmaapConfig.getConfig());
+ }
+
+ AafServiceFactory(DmaapConfig dmaapConfig) {
+ this.dmaapConfig = dmaapConfig;
+ }
+
+ public AafService initAafService(ServiceType serviceType) {
+ boolean useAaf = "true".equalsIgnoreCase(dmaapConfig.getProperty("UseAAF", "false"));
+ String aafUrl = dmaapConfig.getProperty("aaf.URL", "https://authentication.domain.netset.com:8100/proxy/");
+ logger.info("AafService initAafService: useAaf={}, aafUrl={}", useAaf, aafUrl);
+
+ AafCred cred = getCred(serviceType);
+ return new AafServiceImpl(useAaf, aafUrl, cred.getIdentity(), new AafConnection(cred.toString()));
+ }
+
+ AafCred getCred(ServiceType ctype) {
+ String mechIdProperty;
+ String secretProperty;
+ AafDecrypt decryptor = new AafDecrypt();
+
+ if (ctype == ServiceType.AAF_Admin) {
+ mechIdProperty = "aaf.AdminUser";
+ secretProperty = "aaf.AdminPassword";
+ } else if (ctype == ServiceType.AAF_TopicMgr) {
+ mechIdProperty = "aaf.TopicMgrUser";
+ secretProperty = "aaf.TopicMgrPassword";
+ } else {
+ logger.error("Unexpected case for AAF credential type: " + ctype);
+ return null;
+ }
+ String identity = dmaapConfig.getProperty(mechIdProperty, "noMechId@domain.netset.com");
+ String pwd = decryptor.decrypt(dmaapConfig.getProperty(secretProperty, "notSet"));
+
+ return new AafCred(identity, pwd);
+ }
+
+ class AafCred {
+ private final String identity;
+ private final String pwd;
+
+ AafCred(String identity, String pwd) {
+ this.identity = identity;
+ this.pwd = pwd;
+ }
+
+ public String getIdentity() {
+ return identity;
+ }
+
+ public String toString() {
+ return identity + ":" + pwd;
+ }
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceImpl.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceImpl.java
new file mode 100644
index 0000000..1491818
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafServiceImpl.java
@@ -0,0 +1,163 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+
+import static java.lang.String.format;
+
+public class AafServiceImpl extends BaseLoggingClass implements AafService {
+
+ private static final int CREATED = 201;
+ private static final int OK = 200;
+ private static final String FORCE = "?force=true";
+ private final String aafUrl;
+ private final String identity;
+ private final boolean useAAF;
+ private final AafConnection aafConnection;
+
+ AafServiceImpl(boolean useAaf, String aafUrl, String identity, AafConnection aafConnection) {
+ this.useAAF = useAaf;
+ this.aafUrl = aafUrl;
+ this.identity = identity;
+ this.aafConnection = aafConnection;
+ }
+
+ @Override
+ public String getIdentity() {
+ return identity;
+ }
+
+ @Override
+ public int addPerm(DmaapPerm perm) {
+ logger.info("entry: addPerm() ");
+ return doPost(perm, "authz/perm", CREATED);
+ }
+
+ @Override
+ public int delPerm(DmaapPerm perm, boolean force) {
+ logger.info("entry: delPerm()");
+ return doDelete(new AafEmpty(), format(
+ "authz/perm/%s/%s/%s%s",
+ perm.getPermission(), perm.getPtype(), perm.getAction(), force ? FORCE : ""), OK);
+ }
+
+ @Override
+ public int addGrant(DmaapGrant grant) {
+ logger.info("entry: addGrant() ");
+ return doPost(grant, "authz/role/perm", CREATED);
+ }
+
+ @Override
+ public int addUserRole(AafUserRole ur) {
+ logger.info("entry: addUserRole() ");
+ return doPost(ur, "authz/userRole", CREATED);
+ }
+
+ @Override
+ public int addRole(AafRole role) {
+ logger.info("entry: addRole() ");
+ return doPost(role, "authz/role", CREATED);
+ }
+
+ @Override
+ public int addNamespace(AafNamespace ns) {
+ logger.info("entry: addNamespace() ");
+ return doPost(ns, "authz/ns", CREATED);
+ }
+
+ @Override
+ public int delNamespace(AafNamespace ns, boolean force) {
+ logger.info("entry: delNamespace()");
+ return doDelete(new AafEmpty(), format(
+ "authz/ns/%s%s",
+ ns.getName(), force ? FORCE : ""), OK);
+ }
+
+ private int doPost(AafObject obj, String uri, int expect) {
+ int rc;
+ logger.info("entry: doPost() ");
+ String pURL = aafUrl + uri;
+ logger.info("doPost: useAAF=" + useAAF);
+ if (useAAF) {
+ logger.info("doPost: " + obj.toJSON());
+ rc = aafConnection.postAaf(obj, pURL);
+ } else {
+ rc = expect;
+ }
+ switch (rc) {
+ case 401:
+ case 403:
+ errorLogger.error(DmaapbcLogMessageEnum.AAF_CREDENTIAL_ERROR, identity);
+ break;
+ case 409:
+ logger.warn("Object for " + uri + " already exists. Possible conflict.");
+ break;
+ default:
+ if (rc == expect) {
+ logger.info("expected response: " + rc);
+ } else {
+ logger.error("Unexpected response: " + rc);
+ }
+ break;
+ }
+
+ return rc;
+ }
+
+ private int doDelete(AafObject obj, String uri, int expect) {
+ int rc;
+ String pURL = aafUrl + uri;
+ if (useAAF) {
+ logger.info("doDelete: " + obj.toJSON());
+ rc = aafConnection.delAaf(obj, pURL);
+ } else {
+ rc = expect;
+ }
+ switch (rc) {
+ case 401:
+ case 403:
+ errorLogger.error(DmaapbcLogMessageEnum.AAF_CREDENTIAL_ERROR, identity);
+ break;
+ case 404:
+ logger.warn("Object not found...ignore");
+ break;
+ case OK:
+ logger.info("expected response");
+ break;
+ default:
+ logger.error("Unexpected response: " + rc);
+ break;
+ }
+
+ return rc;
+ }
+
+ String getAafUrl() {
+ return aafUrl;
+ }
+
+ boolean isUseAAF() {
+ return useAAF;
+ }
+
+} \ No newline at end of file
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafUserRole.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafUserRole.java
new file mode 100644
index 0000000..b948e61
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/AafUserRole.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.util.Objects;
+
+
+public class AafUserRole extends AafObject {
+
+ private String identity;
+ private String role;
+
+
+
+ public AafUserRole(String identity, String role ) {
+ super();
+ this.identity = identity;
+ this.role = role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+ public String getRole() {
+ return role;
+ }
+
+ public String getIdentity() {
+ return identity;
+ }
+
+ public void setIdentity(String identity) {
+ this.identity = identity;
+ }
+
+ public String toJSON() {
+
+ String postJSON = String.format(" { \"user\": \"%s\", \"role\": \"%s\" }",
+ this.getIdentity(),
+ this.getRole()
+ );
+ logger.info( "returning JSON: " + postJSON);
+
+ return postJSON;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AafUserRole that = (AafUserRole) o;
+ return Objects.equals(identity, that.identity) &&
+ Objects.equals(role, that.role);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(identity, role);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/ClearDecrypt.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/ClearDecrypt.java
new file mode 100644
index 0000000..fe3e3e7
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/ClearDecrypt.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.io.IOException;
+
+public class ClearDecrypt implements DecryptionInterface {
+
+ @Override
+ public String decrypt(String enc) throws IOException {
+ return enc;
+ }
+
+ @Override
+ public String valueOf(String s) {
+ return s;
+ }
+
+ @Override
+ public boolean init(String codecFname) {
+ return false;
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DecryptionInterface.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DecryptionInterface.java
new file mode 100644
index 0000000..eda6465
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DecryptionInterface.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.io.IOException;
+
+public interface DecryptionInterface {
+ public boolean init( String codecFname );
+ public String decrypt(String enc) throws IOException;
+ public String valueOf( String s);
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapGrant.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapGrant.java
new file mode 100644
index 0000000..e171b88
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapGrant.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.util.Objects;
+
+public class DmaapGrant extends AafObject {
+
+ 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;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DmaapGrant that = (DmaapGrant) o;
+ return Objects.equals(perm, that.perm) &&
+ Objects.equals(role, that.role);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(perm, role);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapPerm.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapPerm.java
new file mode 100644
index 0000000..2f1765d
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/aaf/DmaapPerm.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import java.util.Objects;
+
+
+public class DmaapPerm extends AafObject {
+
+ 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;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DmaapPerm dmaapPerm = (DmaapPerm) o;
+ return Objects.equals(permission, dmaapPerm.permission) &&
+ Objects.equals(ptype, dmaapPerm.ptype) &&
+ Objects.equals(action, dmaapPerm.action);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(permission, ptype, action);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFish.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFish.java
new file mode 100644
index 0000000..825b711
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFish.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.dmaap.dbcapi.aaf.AafLurService;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+public class AafLurAndFish extends BaseLoggingClass implements ApiAuthorizationCheckInterface {
+ private AafLurService svc;
+ private static String apiNamespace;
+ private static final String ERROR="Error";
+
+ AafLurAndFish() throws AuthenticationErrorException {
+
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ apiNamespace = p.getProperty( "ApiNamespace", "org.onap.dmaap-bc.api");
+
+ String cadiprop = p.getProperty( "cadi.properties", "/opt/app/osaaf/local/org.onap.dmaap-bc.props");
+ logger.info( "cadiprops in " + cadiprop );
+ Properties props = new Properties();
+ try {
+ FileInputStream fis = new FileInputStream( cadiprop );
+ try {
+ props.load( fis );
+ } finally {
+ fis.close();
+ }
+ } catch ( IOException e ) {
+ errorLogger.error( "Unable to load " + cadiprop );
+ errorLogger.error(ERROR, e);
+ throw new AuthenticationErrorException( );
+ }
+ try {
+ PropAccess myAccess = new PropAccess( props );
+
+ svc = AafLurService.getInstance(myAccess);
+ } catch (APIException | CadiException | LocatorException e ) {
+ errorLogger.error(ERROR, e);
+ errorLogger.error( e.toString() );
+ throw new AuthenticationErrorException();
+ }
+
+ }
+
+ public void check( String mechid, String pwd, DmaapPerm p ) throws AuthenticationErrorException {
+
+ try {
+ if (mechid.isEmpty() || pwd.isEmpty()) {
+ throw new AuthenticationErrorException("No basic authorization value provided");
+ }
+
+ if (!svc.checkPerm( apiNamespace, mechid, pwd, p )) {
+ throw new AuthenticationErrorException();
+ }
+ } catch ( IOException | CadiException e ) {
+ errorLogger.error(ERROR, e);
+ errorLogger.error( e.toString() );
+ throw new AuthenticationErrorException();
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ AafLurAndFish alaf = new AafLurAndFish();
+ DmaapPerm p = new DmaapPerm( "org.onap.dmaap-bc.api.dmaap", "boot", "GET");
+
+ try {
+ alaf.check("mmanager@people.osaaf.org", "demo123456!", p);
+ } catch (AuthenticationErrorException aee ) {
+ errorLogger.error(aee.getMessage());
+ errorLogger.error( "Check failed for: " + p.toJSON());
+ System.exit(-1);
+ }
+ errorLogger.info("Check succeeded for: " + p.toJSON());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AllowAll.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AllowAll.java
new file mode 100644
index 0000000..2e83e6c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AllowAll.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.authentication;
+
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+
+public class AllowAll implements ApiAuthorizationCheckInterface {
+ @Override
+ public void check(String mechid, String pwd, DmaapPerm p) {
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiAuthorizationCheckInterface.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiAuthorizationCheckInterface.java
new file mode 100644
index 0000000..1fef09d
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiAuthorizationCheckInterface.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+
+@FunctionalInterface
+public interface ApiAuthorizationCheckInterface {
+ public void check( String mechid, String pwd, DmaapPerm p ) throws AuthenticationErrorException;
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPerms.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPerms.java
new file mode 100644
index 0000000..b082102
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPerms.java
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.AafServiceFactory;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class ApiPerms extends BaseLoggingClass {
+ static String topic = "topics";
+ static String mrClusters = "mr_clusters";
+ static String mrClients = "mr_clients";
+ static String feed = "feeds";
+ static String drSubs = "dr_subs";
+ static String drPubs = "dr_pubs";
+ static String drNodes = "dr_nodes";
+ static String dcaeLocations = "dcaeLocations";
+ static String inventory = "Inventory";
+ static String portalUser = "PortalUser";
+ static String orchestrator = "Orchestrator";
+ static String delete = "DELETE";
+ static String dmaap = "dmaap";
+ static String controller = "Controller";
+
+ private static class PermissionMap {
+ static final EELFLogger logger = EELFManager.getInstance().getLogger( PermissionMap.class );
+ static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ String uri;
+ String action;
+ String[] roles;
+
+ private PermissionMap( String u, String a, String[] r ) {
+ this.setUri(u);
+ this.setAction(a);
+ this.setRoles(r);
+ }
+
+ public String getUri() {
+ return uri;
+ }
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+ public String getAction() {
+ return action;
+ }
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ public String[] getRoles() {
+ return roles;
+ }
+ public void setRoles(String[] roles) {
+ this.roles = roles;
+ }
+
+ public static void initMap( PermissionMap[] pmap, String instance ) {
+
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ String api = p.getProperty("ApiNamespace", "apiNamespace.not.set");
+
+ AafService aaf = new AafServiceFactory().initAafService(ServiceType.AAF_Admin);
+
+ for ( int i = 0; i < pmap.length ; i++ ) {
+ String uri = new String( api + "." + pmap[i].getUri());
+ DmaapPerm perm = new DmaapPerm( uri, instance, pmap[i].getAction() );
+ int rc = aaf.addPerm( perm );
+ if ( rc != 201 && rc != 409 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.AAF_UNEXPECTED_RESPONSE, Integer.toString(rc), "add perm", perm.toString() );
+
+ }
+ for( String r: pmap[i].getRoles()) {
+ String fr = new String( api + "." + r );
+ logger.debug( "i:" + i + " granting perm " + perm.toString()+ " to role=" + fr );
+ DmaapGrant grant = new DmaapGrant( perm, fr );
+ rc = aaf.addGrant( grant );
+ if ( rc != 201 && rc != 409 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.AAF_UNEXPECTED_RESPONSE, Integer.toString(rc), "grant perm", perm.toString() );
+ }
+ }
+
+ }
+ }
+ }
+
+ static PermissionMap[] bootMap = {
+ new PermissionMap( dmaap, "GET", new String[] { controller }),
+ new PermissionMap( dmaap, "POST", new String[] { controller }),
+ new PermissionMap( dmaap, "PUT", new String[] { controller }),
+ new PermissionMap( dmaap, delete, new String[] { controller })
+
+ };
+
+ static PermissionMap[] envMap = {
+ new PermissionMap( dmaap, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( dmaap, "POST", new String[] { controller } ),
+ new PermissionMap( dmaap, "PUT", new String[] { controller }),
+ new PermissionMap( dmaap, delete, new String[] { controller }),
+ new PermissionMap( "bridge", "GET", new String[] { "Metrics" }),
+ //new PermissionMap( "bridge", "POST", new String[] { "Metrics" } ),
+ //new PermissionMap( "bridge", "PUT", new String[] { "Metrics" }),
+ //new PermissionMap( "bridge", delete, new String[] { "Metrics" }),
+ new PermissionMap( dcaeLocations, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( dcaeLocations, "POST", new String[] { controller } ),
+ new PermissionMap( dcaeLocations, "PUT", new String[] { controller }),
+ new PermissionMap( dcaeLocations, delete, new String[] { controller }),
+ new PermissionMap( drNodes, "GET", new String[] { controller, orchestrator, inventory, portalUser }),
+ new PermissionMap( drNodes, "POST", new String[] { controller } ),
+ new PermissionMap( drNodes, "PUT", new String[] { controller }),
+ new PermissionMap( drNodes, delete, new String[] { controller }),
+ new PermissionMap( drPubs, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( drPubs, "POST", new String[] { controller, orchestrator,portalUser } ),
+ new PermissionMap( drPubs, "PUT", new String[] { controller, orchestrator,portalUser }),
+ new PermissionMap( drPubs, delete, new String[] { controller, orchestrator,portalUser }),
+ new PermissionMap( drSubs, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( drSubs, "POST", new String[] { controller, orchestrator,portalUser } ),
+ new PermissionMap( drSubs, "PUT", new String[] { controller, orchestrator,portalUser }),
+ new PermissionMap( drSubs, delete, new String[] { controller, orchestrator,portalUser }),
+ new PermissionMap( feed, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( feed, "POST", new String[] { controller, orchestrator,portalUser } ),
+ new PermissionMap( feed, "PUT", new String[] { controller, orchestrator, portalUser }),
+ new PermissionMap( feed, delete, new String[] { controller, portalUser }),
+ new PermissionMap( mrClients, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( mrClients, "POST", new String[] { controller,orchestrator, portalUser } ),
+ new PermissionMap( mrClients, "PUT", new String[] { controller, orchestrator,portalUser }),
+ new PermissionMap( mrClients, delete, new String[] { controller,orchestrator, portalUser }),
+ new PermissionMap( mrClusters, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( mrClusters, "POST", new String[] { controller } ),
+ new PermissionMap( mrClusters, "PUT", new String[] { controller }),
+ new PermissionMap( mrClusters, delete, new String[] { controller }),
+ new PermissionMap( topic, "GET", new String[] { controller, orchestrator, inventory, "Metrics", portalUser }),
+ new PermissionMap( topic, "POST", new String[] { controller, orchestrator } ),
+ new PermissionMap( topic, "PUT", new String[] { controller, orchestrator }),
+ new PermissionMap( topic, delete, new String[] { controller, orchestrator })
+ };
+
+ public void setBootMap() {
+ String instance = "boot";
+ PermissionMap.initMap( bootMap, instance );
+ }
+
+ public void setEnvMap() {
+ Dmaap dmaapVar = new DmaapService().getDmaap();
+ String dmaapName = dmaapVar.getDmaapName();
+ PermissionMap.initMap( envMap, dmaapName );
+ }
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPolicy.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPolicy.java
new file mode 100644
index 0000000..16d0367
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/ApiPolicy.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import java.util.Properties;
+
+public class ApiPolicy extends BaseLoggingClass {
+
+ private boolean permissionClassSet = true;
+ private ApiAuthorizationCheckInterface perm = null;
+
+ public ApiPolicy() {
+ this(DmaapConfig.getConfig());
+ }
+
+ ApiPolicy(Properties p) {
+ String dClass = p.getProperty("ApiPermission.Class");
+ logger.info("ApiPolicy implements " + dClass);
+ logger.info("dClass=" + dClass + " permissionClassSet=" + permissionClassSet);
+
+ try {
+ perm = (ApiAuthorizationCheckInterface) (Class.forName(dClass).newInstance());
+ } catch (Exception ee) {
+ errorLogger.error(DmaapbcLogMessageEnum.UNEXPECTED_CONDITION, "attempting to instantiate " + dClass);
+ errorLogger.error("trace is: " + ee);
+ permissionClassSet = false;
+ }
+ }
+
+ public void check(String mechid, String pwd, DmaapPerm p) throws AuthenticationErrorException {
+ perm.check(mechid, pwd, p);
+ }
+
+ public boolean isPermissionClassSet() {
+ return permissionClassSet;
+ }
+
+ ApiAuthorizationCheckInterface getPerm() {
+ return perm;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AuthenticationErrorException.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AuthenticationErrorException.java
new file mode 100644
index 0000000..01200f7
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/authentication/AuthenticationErrorException.java
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+public class AuthenticationErrorException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public AuthenticationErrorException() {
+ }
+
+ public AuthenticationErrorException(String s) {
+ super(s);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java
new file mode 100644
index 0000000..dffe830
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java
@@ -0,0 +1,1101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.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.Arrays;
+import javax.net.ssl.HttpsURLConnection;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+
+public class DrProvConnection extends BaseLoggingClass {
+
+
+ private String provURL;
+ private String provApi;
+ private String behalfHeader;
+ private String feedContentType;
+ private String subContentType;
+ private String unit_test;
+ private String provURI;
+
+ private HttpsURLConnection uc;
+
+
+ public DrProvConnection() {
+ provURL = new DmaapService().getDmaap().getDrProvUrl();
+ if ( provURL.length() < 1 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.PREREQ_DMAAP_OBJECT, "DmaapService().getDmaap().getDrProvUrl()");
+ }
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ provApi = p.getProperty( "DR.provApi", "ONAP" );
+ behalfHeader = p.getProperty( "DR.onBehalfHeader", "X-DMAAP-DR-ON-BEHALF-OF");
+ feedContentType = p.getProperty( "DR.feedContentType", "application/vnd.dmaap-dr.feed");
+ subContentType = p.getProperty( "DR.subContentType", "application/vnd.dmaap-dr.subscription");
+ provURI = p.getProperty( "DR.ProvisioningURI", "/internal/prov");
+ logger.info( "provURL=" + provURL + " provApi=" + provApi + " behalfHeader=" + behalfHeader
+ + " feedContentType=" + feedContentType + " subContentType=" + subContentType );
+ unit_test = p.getProperty( "UnitTest", "No" );
+
+ }
+
+ public boolean makeFeedConnection() {
+ return makeConnection( provURL );
+ }
+ public boolean makeFeedConnection(String feedId) {
+ return makeConnection( provURL + "/feed/" + feedId );
+ }
+ public boolean makeSubPostConnection( String subURL ) {
+ String[] parts = subURL.split("/");
+ String revisedURL = provURL + "/" + parts[3] + "/" + parts[4];
+ logger.info( "mapping " + subURL + " to " + revisedURL );
+ return makeConnection( revisedURL );
+ }
+ public boolean makeSubPutConnection( String subId ) {
+ String revisedURL = provURL + "/subs/" + subId;
+ logger.info( "mapping " + subId + " 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 );
+ }
+ public boolean makeEgressConnection( String sub, String nodep ) {
+ String uri = String.format("/internal/route/egress/?sub=%s&node=%s",
+ sub, nodep );
+ return makeConnection( provURL + uri );
+ }
+ public boolean makeDumpConnection() {
+ String url = provURL + provURI;
+ return makeConnection( url );
+ }
+ public boolean makeNodesConnection( String varName ) {
+
+ String uri = String.format("/internal/api/%s", varName);
+ return makeConnection( provURL + uri );
+ }
+
+ public boolean makeNodesConnection( String varName, String val ) {
+
+ if ( val == null ) {
+ return false;
+ }
+ String cv = val.replaceAll("\\|", "%7C");
+ String uri = String.format( "/internal/api/%s?val=%s", varName, cv );
+
+ 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 );
+ uc.setSSLSocketFactory(DmaapConfig.getSSLSocketFactory());
+ return(true);
+ } catch (Exception e) {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_ERROR, pURL, e.getMessage() );
+ return(false);
+ }
+ }
+
+ public 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 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.IO_EXCEPTION, ex.getMessage());
+ }
+
+ return sb.toString();
+ }
+
+
+ public String doPostFeed( Feed postFeed, ApiError err ) {
+
+ byte[] postData = postFeed.getBytes();
+ logger.info( "post fields=" + Arrays.toString(postData) );
+ String responsemessage = null;
+ String responseBody = null;
+ int rc = -1;
+
+ try {
+ logger.info( "uc=" + uc );
+ uc.setRequestMethod("POST");
+ uc.setRequestProperty("Content-Type", feedContentType);
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, 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();
+ 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 (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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) {
+ errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+ err.setCode( 500 );
+ err.setMessage("Backend connection refused");
+ } catch (SocketException se) {
+ errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from prov server" );
+ err.setCode( 500 );
+ err.setMessage( "Unable to read response from DR");
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPostFeed because unit_test =" + unit_test );
+ } else {
+ logger.warn("Unable to read response " );
+ errorLogger.error("Unable to read response ", e.getMessage());
+ 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 ) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return responseBody;
+
+ }
+
+
+ // the POST for /internal/route/ingress doesn't return any data, so needs a different function
+ // the POST for /internal/route/egress doesn't return any data, so needs a different function
+ public int doXgressPost( ApiError err ) {
+
+ String responsemessage = null;
+ int rc = -1;
+
+ try {
+ uc.setRequestMethod("POST");
+
+
+ try {
+ uc.connect();
+
+ } 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doXgressPost because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response " );
+ logger.error(e.getMessage(), e);
+ }
+ }
+ finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ return rc;
+
+ }
+
+ public String doPostDr_Sub( DR_Sub postSub, ApiError err ) {
+ logger.info( "entry: doPostDr_Sub() " );
+ byte[] postData = postSub.getBytes(provApi );
+ logger.info( "post fields=" + postData );
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+
+ uc.setRequestMethod("POST");
+
+ uc.setRequestProperty("Content-Type", subContentType );
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, "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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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 (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPostDr_Sub because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response ", e.getMessage());
+ }
+ }
+ finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return responseBody;
+
+ }
+
+
+ public String doPutFeed(Feed putFeed, ApiError err) {
+ byte[] postData = putFeed.getBytes();
+ logger.info( "post fields=" + Arrays.toString(postData) );
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+ logger.info( "uc=" + uc );
+ uc.setRequestMethod("PUT");
+ uc.setRequestProperty("Content-Type", feedContentType );
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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 );
+ err.setCode( rc );
+ } 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 );
+ errorLogger.error( DmaapbcLogMessageEnum.PROV_OUT_OF_SYNC, "Feed", putFeed.getFeedId() );
+
+ } else {
+ err.setCode( rc );
+ err.setMessage(responsemessage);
+ }
+
+ } catch (ConnectException ce) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPutFeed because unit_test =" + unit_test );
+ } else {
+ errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage());
+ err.setCode(500);
+ err.setMessage("Backend connection refused");
+ }
+ } catch (SocketException se) {
+ errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from Prov server" );
+ err.setCode( 500 );
+ err.setMessage( "Unable to read response from DR");
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPutFeed because unit_test =" + unit_test );
+ } else {
+ logger.warn("Unable to read response " );
+ logger.error(e.getMessage(), e);
+ }
+ try {
+ err.setCode( uc.getResponseCode());
+ err.setMessage(uc.getResponseMessage());
+ } catch (Exception e2) {
+ err.setCode( 500 );
+ err.setMessage("Unable to determine response message");
+ logger.error(e2.getMessage(), e2);
+ }
+ } finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return responseBody;
+ }
+ public String doPutDr_Sub(DR_Sub postSub, ApiError err) {
+ logger.info( "entry: doPutDr_Sub() " );
+ byte[] postData = postSub.getBytes(provApi);
+ logger.info( "post fields=" + postData );
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+
+ uc.setRequestMethod("PUT");
+
+ uc.setRequestProperty("Content-Type", subContentType );
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, "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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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 ) {
+ responseBody = bodyToString( uc.getInputStream() );
+ logger.info( "responseBody=" + responseBody );
+
+ } else {
+ err.setCode(rc);
+ err.setMessage(responsemessage);
+ }
+
+ } catch (ConnectException ce) {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+ err.setCode( 500 );
+ err.setMessage("Backend connection refused");
+ logger.error(ce.getMessage(), ce);
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPutDr_Sub because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response " );
+ logger.error(e.getMessage(), e);
+ }
+ } finally {
+ if(null != uc){
+ uc.disconnect();
+ }
+ }
+ return responseBody;
+
+ }
+
+ public String doGetNodes( ApiError err ) {
+ logger.info( "entry: doGetNodes() " );
+ //byte[] postData = postSub.getBytes();
+ //logger.info( "get fields=" + postData );
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+
+ uc.setRequestMethod("GET");
+ int rc = -1;
+
+
+ try {
+ uc.connect();
+
+
+ } 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+
+ 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);
+ }
+ }
+ }
+
+ err.setCode(rc); // may not really be an error, but we save rc
+ if (rc == 200 ) {
+ responseBody = bodyToString( uc.getInputStream() );
+ logger.info( "responseBody=" + responseBody );
+ } else {
+ err.setMessage(responsemessage);
+ }
+
+
+ } catch (ConnectException ce) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+ } else {
+ errorLogger.error(DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage());
+ err.setCode(500);
+ err.setMessage("Backend connection refused");
+ logger.error(ce.getMessage(), ce);
+ }
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response ", e.getMessage());
+ }
+ } finally {
+
+ if ( uc != null ) uc.disconnect();
+ }
+
+ return responseBody;
+
+ }
+ public String doPutNodes( ApiError err ) {
+ logger.info( "entry: doPutNodes() " );
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+ uc.setRequestMethod("PUT");
+ uc.setUseCaches(false);
+ int rc = -1;
+
+ try {
+ uc.connect();
+ } 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 (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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);
+ }
+ }
+ }
+ err.setCode(rc);
+ if (rc == 200 ) {
+ responseBody = bodyToString( uc.getInputStream() );
+ logger.info( "responseBody=" + responseBody );
+
+ } else {
+
+ err.setMessage(responsemessage);
+ }
+
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPutNodes because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response ", e.getMessage());
+ }
+ } finally {
+ if ( uc != null ) {
+ uc.disconnect();
+ }
+ }
+ return responseBody;
+
+ }
+
+ public String doDeleteFeed(Feed putFeed, ApiError err) {
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+ logger.info( "uc=" + uc );
+ uc.setRequestMethod("DELETE");
+ uc.setRequestProperty("Content-Type", feedContentType );
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, putFeed.getOwner() );
+ 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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 );
+ errorLogger.error( DmaapbcLogMessageEnum.PROV_OUT_OF_SYNC, "Feed", putFeed.getFeedId() );
+
+ } else {
+ err.setCode( rc );
+ err.setMessage(responsemessage);
+ }
+
+ } catch (ConnectException ce) {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+ err.setCode( 500 );
+ err.setMessage("Backend connection refused");
+ logger.error(ce.getMessage(), ce);
+ } catch (SocketException se) {
+ errorLogger.error( DmaapbcLogMessageEnum.SOCKET_EXCEPTION, se.getMessage(), "response from Prov server" );
+ err.setCode( 500 );
+ err.setMessage( "Unable to read response from DR");
+ logger.error(se.getMessage(), se);
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doDeleteFeed because unit_test =" + unit_test );
+ } else {
+ logger.warn("Unable to read response " );
+ logger.error(e.getMessage(), e);
+ try {
+ err.setCode( uc.getResponseCode());
+ err.setMessage(uc.getResponseMessage());
+ } catch (Exception e2) {
+ err.setCode( 500 );
+ err.setMessage("Unable to determine response message");
+ logger.error(e2.getMessage(), e2);
+ }
+ }
+ } finally {
+ try {
+ if(uc != null) {
+ uc.disconnect();
+ }
+ } catch ( Exception e ) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return responseBody;
+ }
+
+ public String doDeleteDr_Sub(DR_Sub delSub, ApiError err) {
+ logger.info( "entry: doDeleteDr_Sub() " );
+ byte[] postData = delSub.getBytes(provApi);
+ logger.info( "post fields=" + Arrays.toString(postData));
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+
+ uc.setRequestMethod("DELETE");
+
+ uc.setRequestProperty("Content-Type", subContentType);
+ uc.setRequestProperty( "charset", "utf-8");
+ uc.setRequestProperty( behalfHeader, "DGL" );
+ 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+ 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);
+ }
+ }
+ }
+ err.setCode(rc);
+ if (rc == 204 ) {
+ responseBody = bodyToString( uc.getInputStream() );
+ logger.info( "responseBody=" + responseBody );
+ } else {
+ err.setMessage(responsemessage);
+ }
+
+ } catch (ConnectException ce) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+ } else {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+ err.setCode( 500 );
+ err.setMessage("Backend connection refused");
+ }
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doDeleteDr_Sub because unit_test =" + unit_test );
+ } else {
+ logger.error("Unable to read response ", e.getMessage());
+ }
+ } finally {
+ if(uc != null){
+ uc.disconnect();
+ }
+ }
+ return responseBody;
+
+ }
+
+ // add double-quotes around a value
+ // hope his is easier to read than in-line escaping...
+ private String dq( String v ) {
+ return ( "\"" + v + "\"");
+ }
+ private String dq( String k, String v) {
+ return( dq(k) + ":" + dq(v));
+ }
+ private String dqc( String k, String v) {
+ return( dq(k) + ":" + dq(v) + ",");
+ }
+
+ private String dumpSimulation() {
+ logger.info( "enter dumpSimulation()");
+ String responseBody =
+ "{"
+ + dq("feeds") + ":["
+ + "{" + dq( "suspend") + ":false,"
+ + dq( "groupid") + ":0,"
+ + dqc( "description", "Some description" )
+ + dqc( "version", "m1.1")
+ + dq( "authorization") + ":"
+ + "{" + dq( "endpoint_addrs" ) + ":[],"
+ + dq( "classification", "unclassified")
+ + dq( "endpoint_ids") + ":[{"
+ + dqc( "password", "dradmin" )
+ + dq( "id", "dradmin")
+ + "}]}"
+ + dq( "last_mod") + ":1553738110000,"
+ + dq( "deleted") + ":false,"
+ + dq( "feedid") + ":1,"
+ + dqc( "name", "Default PM Feed")
+ + dq( "business_description") + ":\"\","
+ + dqc( "publisher", "onap")
+ + dq( "links") + ":{"
+ + dqc( "subscribe", "https://dmaap-dr-prov/subscribe/1")
+ + dqc( "log", "https://dmaap-dr-prov/feedlog/1")
+ + dqc( "publish", "https://dmaap-dr-prov/publish/1")
+ + dq( "self", "https:/dmaap-dr-prov/feed/1")
+ + "}"
+ + dq( "created_date") + ":1553738110000 }"
+ + "],"
+ + dq( "groups") + ":["
+ + "],"
+ + dq( "subscriptions") + ":["
+ + "],"
+ + dq( "ingress") + ":["
+ + "],"
+ + dq( "egress") + ":{"
+ + "},"
+ + dq( "routing") + ":["
+ + "],"
+ + "}";
+ return responseBody;
+ }
+
+ public String doGetDump( ApiError err ) {
+ logger.info( "entry: doGetDump() " );
+
+ String responsemessage = null;
+ String responseBody = null;
+
+ try {
+
+ uc.setRequestMethod("GET");
+ int rc = -1;
+
+
+ try {
+ uc.connect();
+
+
+ } 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) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (Exception e) {
+ logger.info( "Exception: " + e.getMessage() );
+ e.printStackTrace();
+ }
+
+ 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);
+ }
+ }
+ }
+
+ err.setCode(rc); // may not really be an error, but we save rc
+ if (rc == 200 ) {
+ responseBody = bodyToString( uc.getInputStream() );
+ logger.info( "responseBody=" + responseBody );
+ } else {
+ err.setMessage(responsemessage);
+ }
+
+
+ } catch (ConnectException ce) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+ responseBody = dumpSimulation();
+
+ } else {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() );
+ err.setCode( 500 );
+ err.setMessage("Backend connection refused");
+ logger.error(ce.getMessage(), ce);
+ }
+ } catch (Exception e) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doGetNodes because unit_test =" + unit_test );
+ responseBody = dumpSimulation();
+
+ } else {
+ logger.error("Unable to read response ", e.getMessage());
+ }
+ } finally {
+
+ if ( uc != null ) uc.disconnect();
+ }
+
+ return responseBody;
+
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrProvConnection.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrProvConnection.java
new file mode 100644
index 0000000..9c3fa4e
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrProvConnection.java
@@ -0,0 +1,271 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.client;
+
+import org.apache.commons.codec.binary.Base64;
+import org.onap.dmaap.dbcapi.aaf.AafDecrypt;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import java.io.*;
+import java.net.*;
+import java.util.Arrays;
+
+public class MrProvConnection extends BaseLoggingClass{
+
+ private String provURL;
+
+ private HttpURLConnection uc;
+
+
+ private String topicMgrCred;
+ private String authMethod;
+ private String user;
+ private String encPwd;
+ private String unit_test;
+ private boolean hostnameVerify;
+
+ public MrProvConnection() {
+ String mechIdProperty = "aaf.TopicMgrUser";
+ String pwdProperty = "aaf.TopicMgrPassword";
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ user = p.getProperty( mechIdProperty, "noMechId@domain.netset.com" );
+ encPwd = p.getProperty( pwdProperty, "notSet" );
+ authMethod = p.getProperty("MR.authentication", "none");
+ topicMgrCred = getCred();
+ hostnameVerify= "true".equalsIgnoreCase(p.getProperty("MR.hostnameVerify", "true"));
+ unit_test = p.getProperty( "UnitTest", "No" );
+
+ }
+
+ private String getCred( ) {
+
+
+ String pwd = "";
+ AafDecrypt decryptor = new AafDecrypt();
+ pwd = decryptor.decrypt(encPwd);
+ return user + ":" + pwd;
+ }
+
+
+ public boolean makeTopicConnection( MR_Cluster cluster ) {
+ boolean rc = false;
+ logger.info( "connect to cluster: " + cluster.getDcaeLocationName());
+
+
+ provURL = cluster.getTopicProtocol() + "://" + cluster.getFqdn() + ":" + cluster.getTopicPort() + "/topics/create";
+
+ if ( cluster.getTopicProtocol().equals( "https" ) ) {
+ rc = makeSecureConnection( provURL );
+ } else {
+ rc = makeConnection( provURL );
+ }
+ if ( rc && unit_test.equals( "Yes" ) ) {
+ // set timeouts low so we don't hold up unit tests in build process
+ uc.setReadTimeout(5);
+ uc.setConnectTimeout(5);
+ }
+ return rc;
+
+ }
+
+ private boolean makeSecureConnection( String pURL ) {
+ logger.info( "makeConnection to " + pURL );
+
+ try {
+
+ HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+ @Override
+ public boolean verify( String hostname, SSLSession session ) {
+ return true;
+ }
+
+ };
+ URL u = new URL( pURL );
+ uc = (HttpsURLConnection) u.openConnection();
+ uc.setInstanceFollowRedirects(false);
+ if ( ! hostnameVerify ) {
+ HttpsURLConnection ucs = (HttpsURLConnection) uc;
+ ucs.setHostnameVerifier(hostnameVerifier);
+ }
+ logger.info( "open secure 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 );
+ logger.error("Unexpected error during openConnection of ",e );
+ return(false);
+ }
+
+ }
+ private boolean makeConnection( String pURL ) {
+ logger.info( "makeConnection to " + pURL );
+
+ try {
+ URL u = new URL( pURL );
+ uc = (HttpURLConnection) u.openConnection();
+ uc.setInstanceFollowRedirects(false);
+
+ logger.info( "open 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 );
+ logger.error("Unexpected error during openConnection of ",e );
+ 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 ) {
+ errorLogger.error( "IOexception:" + ex);
+ }
+
+ return sb.toString();
+ }
+
+ public String doPostTopic( Topic postTopic, ApiError err ) {
+ String auth = "Basic " + Base64.encodeBase64String(topicMgrCred.getBytes());
+
+
+ String responsemessage = null;
+ int rc = -1;
+
+
+ try {
+ byte[] postData = postTopic.getBytes();
+ logger.info( "post fields=" + Arrays.toString(postData));
+
+ if ( authMethod.equalsIgnoreCase("basicAuth") ) {
+ uc.setRequestProperty("Authorization", auth);
+ logger.info( "Authenticating with " + auth );
+ } else if ( authMethod.equalsIgnoreCase("cert")) {
+ logger.error( "MR.authentication set for client certificate. Not supported yet.");
+ }
+ 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 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.UNKNOWN_HOST_EXCEPTION , "Unknown Host Exception" , provURL );
+ err.setCode(500);
+ err.setMessage("Unknown Host Exception");
+ err.setFields( uc.getURL().getHost());
+ return new String( "500: " + uhe.getMessage());
+ }catch ( ConnectException ce ) {
+ if ( unit_test.equals( "Yes" ) ) {
+ err.setCode(200);
+ err.setMessage( "simulated response");
+ logger.info( "artificial 200 response from doPostMessage because unit_test =" + unit_test );
+ } else {
+ errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, "HTTP Connection Exception" );
+ err.setCode(500);
+ err.setMessage("HTTP Connection Exception");
+ err.setFields( uc.getURL().getHost());
+ return new String( "500: " + ce.getMessage());
+ }
+ }
+ rc = uc.getResponseCode();
+ logger.info( "http response code:" + rc );
+ err.setCode(rc);
+ responsemessage = uc.getResponseMessage();
+ logger.info( "responsemessage=" + responsemessage );
+ err.setMessage(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) {
+ errorLogger.error("Unable to read response: " + e.getMessage() );
+
+ }
+ finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ errorLogger.error("Unable to disconnect");
+ }
+ }
+ return new String( rc +": " + responsemessage );
+
+ }
+
+
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrTopicConnection.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrTopicConnection.java
new file mode 100644
index 0000000..b3f713f
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/client/MrTopicConnection.java
@@ -0,0 +1,239 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.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 java.net.HttpURLConnection;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+import org.apache.commons.codec.binary.Base64;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class MrTopicConnection extends BaseLoggingClass {
+ private String topicURL;
+
+ private HttpURLConnection uc;
+
+
+ private String mmProvCred;
+ private String unit_test;
+ private String authMethod;
+ private boolean hostnameVerify;
+
+ public MrTopicConnection(String user, String pwd ) {
+ mmProvCred = new String( user + ":" + pwd );
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ unit_test = p.getProperty( "UnitTest", "No" );
+ authMethod = p.getProperty("MR.authentication", "none");
+ hostnameVerify= "true".equalsIgnoreCase(p.getProperty("MR.hostnameVerify", "true"));
+ }
+
+ public boolean makeTopicConnection( MR_Cluster cluster, String topic, String overrideFqdn ) {
+ String fqdn = overrideFqdn != null ? overrideFqdn : cluster.getFqdn();
+ logger.info( "connect to cluster: " + fqdn + " for topic: " + topic );
+
+
+ topicURL = cluster.getTopicProtocol() + "://" + fqdn + ":" + cluster.getTopicPort() + "/events/" + topic ;
+
+ if ( "https".equals(cluster.getTopicProtocol())) {
+ return makeSecureConnection( topicURL );
+ }
+ return makeConnection( topicURL );
+ }
+
+
+ private boolean makeSecureConnection( String pURL ) {
+ logger.info( "makeConnection to " + pURL );
+
+ try {
+ HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+ @Override
+ public boolean verify( String hostname, SSLSession session ) {
+ return true;
+ }
+
+ };
+
+
+ URL u = new URL( pURL );
+ uc = (HttpsURLConnection) u.openConnection();
+ uc.setInstanceFollowRedirects(false);
+ if ( ! hostnameVerify ) {
+ HttpsURLConnection ucs = (HttpsURLConnection) uc;
+ ucs.setHostnameVerifier(hostnameVerifier);
+ }
+
+ logger.info( "open connection to " + pURL );
+ return(true);
+ } catch (Exception e) {
+ logger.error("Unexpected error during openConnection of " + pURL );
+ logger.error("Error", e);;
+ return(false);
+ }
+
+ }
+ private boolean makeConnection( String pURL ) {
+ logger.info( "makeConnection to " + pURL );
+
+ try {
+ URL u = new URL( pURL );
+ uc = (HttpURLConnection) u.openConnection();
+ uc.setInstanceFollowRedirects(false);
+ logger.info( "open connection to " + pURL );
+ return(true);
+ } catch (Exception e) {
+ logger.error("Unexpected error during openConnection of " + pURL );
+ logger.error("error", e);
+ 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 ) {
+ errorLogger.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 );
+ if ( authMethod.equalsIgnoreCase("basicAuth") ) {
+ uc.setRequestProperty("Authorization", auth);
+ logger.info( "Authenticating with " + auth );
+ } else if ( authMethod.equalsIgnoreCase("cert")) {
+ logger.error( "MR.authentication set for client certificate. Not supported yet.");
+ }
+ 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
+ callSetDoOutputOnError();
+
+ } catch ( SSLException se ) {
+ logger.error("Error", se);
+ response.setCode(500);
+ response.setMessage( se.getMessage());
+ return response;
+
+ }
+ 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) {
+ if ( unit_test.equals( "Yes" ) ) {
+ response.setCode(201);
+ response.setMessage( "simulated response");
+ logger.info( "artificial 201 response from doPostMessage because unit_test =" + unit_test );
+ } else {
+
+ response.setCode(500);
+ response.setMessage( "Unable to read response");
+ logger.warn( response.getMessage() );
+ logger.error("Error", e);
+ }
+ }
+ finally {
+ try {
+ uc.disconnect();
+ } catch ( Exception e ) {
+ logger.error("Error", e);
+ }
+ }
+ return response;
+
+ }
+
+ public void callSetDoOutputOnError() {
+ 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) {
+ logger.error("Error", e);
+ }
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnWrapper.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnWrapper.java
new file mode 100644
index 0000000..2317fe4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnWrapper.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.sql.*;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+
+public abstract class ConnWrapper<T, U> {
+ EELFLogger logger = EELFManager.getInstance().getLogger( ConnWrapper.class );
+ protected Connection c;
+ protected PreparedStatement ps;
+ protected ResultSet rs;
+ protected abstract T run(U u) throws Exception;
+ public T protect(ConnectionFactory cf, U u) {
+ try {
+ try {
+ return(attempt(cf, u, false));
+ } catch (SQLException sqle) {
+ logger.error("Error", 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) {
+ logger.error("Error", e);
+ }}
+ rs = null;
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (Exception e) {
+ logger.error("Error", e);
+ }}
+ ps = null;
+ if (c != null) {
+ try {
+ c.close();
+ } catch (Exception e) {
+ logger.error("Error", e);
+ }}
+ c = null;
+ }
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnectionFactory.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnectionFactory.java
new file mode 100644
index 0000000..6004d9b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/ConnectionFactory.java
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class ConnectionFactory extends BaseLoggingClass {
+
+ static final int PREPARE_PSQL_CONNECTION_ATTEMPTS = 5;
+
+ static {
+ try {
+ Class.forName("org.postgresql.Driver");
+ } catch (Exception e) {
+ errorLogger.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;
+ private String schema;
+
+ 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 = getValue(p, "DB.user", "dmaap_admin");
+ dbcr = getValue(p, "DB.cred", "test234-ftl");
+ schema = p.getProperty("DB.schema", "dmaap_admin");
+ }
+
+ private static String getValue(final Properties props, final String value, final String defaultValue) {
+ String prop = props.getProperty(value, defaultValue);
+ if (prop != null && prop.matches("[$][{].*[}]$")) {
+ return System.getenv(prop.substring(2, prop.length() - 1));
+ }
+ return prop;
+ }
+
+ 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);
+ for (int i=1; i<PREPARE_PSQL_CONNECTION_ATTEMPTS; i++){
+ try{
+ return(DriverManager.getConnection("jdbc:postgresql://" + host + "/" + dbname, p));
+ }catch(SQLException e){
+ errorLogger.error("Unable to connect to the postgres server. " + i + "attempt failed. ", e);
+ waitFor(1);
+ }
+ }
+ return(DriverManager.getConnection("jdbc:postgresql://" + host + "/" + dbname, p));
+ }
+ public String getSchema() {
+ return(schema);
+ }
+ public void release(Connection c) {
+ synchronized(this) {
+ if (cur < pool.length) {
+ pool[cur++] = c;
+ return;
+ }
+ }
+ try {
+ c.close();
+ } catch (Exception e) {
+ errorLogger.error("Error", e);
+ }
+ }
+ private void waitFor(long seconds){
+ try {
+ TimeUnit.SECONDS.sleep(seconds);
+ } catch (InterruptedException e) {
+ debugLogger.debug("Waiting interrupted. ", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBException.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBException.java
new file mode 100644
index 0000000..6538167
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBException.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+
+public class DBException extends RuntimeException {
+ static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ public DBException(Exception e) {
+ super(e);
+ errorLogger.error(DmaapbcLogMessageEnum.DB_ACCESS_ERROR, e.getMessage());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBFieldHandler.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBFieldHandler.java
new file mode 100644
index 0000000..618932e
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBFieldHandler.java
@@ -0,0 +1,205 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+
+
+public class DBFieldHandler {
+ static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+
+ 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;
+ StringBuilder sb = new StringBuilder();
+ 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) {
+ errorLogger.warn("No 'is' method for " + c.getName() + " so trying 'get' method");
+ 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;
+ }
+ errorLogger.error(DmaapbcLogMessageEnum.DB_NO_FIELD_HANDLER, c.getName(), fieldname, Integer.toString(fieldnum), x.getName());
+ }
+
+ 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;
+ }
+ StringBuilder sb = new StringBuilder();
+ 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) {
+ errorLogger.error(DmaapbcLogMessageEnum.DB_FIELD_INIT_ERROR, Integer.toString(index), val.toString(), ps.toString());
+ throw e;
+ }
+ }
+ }
+ private static Map<String, SqlOp> 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) {
+ errorLogger.error("Error", e);
+ errorLogger.error(DmaapbcLogMessageEnum.DB_ACCESS_INIT_ERROR, e.getMessage() );
+ }
+ }
+ 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 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/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBMap.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBMap.java
new file mode 100644
index 0000000..b3282ed
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBMap.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.sql.*;
+import java.util.*;
+
+public class DBMap<C> extends TableHandler<C> implements Map<String, C> {
+ public DBMap(Class<C> cls, String tabname, String keyfield) throws Exception {
+ this(ConnectionFactory.getDefaultInstance(), cls, tabname, keyfield);
+ }
+ public DBMap(ConnectionFactory cf, Class<C> cls, String tabname, String keyfield) throws Exception {
+ super(cf, cls, tabname, keyfield);
+ }
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+ public boolean containsKey(Object key) {
+ return(get(key) != null);
+ }
+ public boolean containsValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+ public boolean isEmpty() {
+ return(false);
+ }
+ public Set<Map.Entry<String, C>> entrySet() {
+ return(list());
+ }
+ public Set<String> keySet() {
+ Set<String> ret = new HashSet<>();
+ for (Map.Entry<String, C> x: list()) {
+ ret.add(x.getKey());
+ }
+ return(ret);
+ }
+ public void putAll(Map<? extends String, ? extends C> m) {
+ throw new UnsupportedOperationException();
+ }
+ public int size() {
+ return(2);
+ }
+ public Collection<C> values() {
+ Collection<C> ret = new ArrayList<>();
+ for (Map.Entry<String, C> x: list()) {
+ ret.add(x.getValue());
+ }
+ return(ret);
+ }
+ public C get(Object key) {
+ if (!(key instanceof String)) {
+ return(null);
+ }
+ return((new ConnWrapper<C, String>() {
+ 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<Map.Entry<String, C>> list() {
+ return((new ConnWrapper<Set<Map.Entry<String, C>>, Object>() {
+ protected Set<Map.Entry<String, C>> run(Object junk) throws Exception {
+ DBFieldHandler keyfield = fields[fields.length - 1];
+ ps = c.prepareStatement(liststmt);
+ rs = ps.executeQuery();
+ Set<Map.Entry<String, C>> 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<String, C>(key, val));
+ }
+ return(ret);
+ }
+ }).protect(cf, null));
+ }
+ public C put(String key, C val) {
+ try {
+ fields[fields.length - 1].setKey(val, key);
+ } catch (Exception e) {
+ throw new DBException(e);
+ }
+ return((new ConnWrapper<C, C>() {
+ 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) {
+ if (!(key instanceof String)) {
+ return(null);
+ }
+ return((new ConnWrapper<C, String>() {
+ 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/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBSingleton.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBSingleton.java
new file mode 100644
index 0000000..2633d70
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DBSingleton.java
@@ -0,0 +1,98 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.sql.*;
+import java.util.*;
+
+import org.onap.dmaap.dbcapi.util.Singleton;
+
+public class DBSingleton<C> extends TableHandler<C> implements Singleton<C> {
+ private C singleton;
+ public DBSingleton(Class<C> cls, String tabname) throws Exception {
+ this(ConnectionFactory.getDefaultInstance(), cls, tabname);
+ }
+ public DBSingleton(ConnectionFactory cf, Class<C> cls, String tabname) throws Exception {
+ super(cf, cls, tabname, null);
+ singleton = cls.newInstance();
+ }
+ public C get() {
+ return((new ConnWrapper<C, Object>() {
+ 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) {
+ if (get() != null) {
+ return;
+ }
+ (new ConnWrapper<Void, C>() {
+ 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) {
+ (new ConnWrapper<Void, C>() {
+ 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<Void, Object>() {
+ protected Void run(Object junk) throws Exception {
+ ps = c.prepareStatement(delstmt);
+ ps.executeUpdate();
+ return(null);
+ }
+ }).protect(cf, null);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DatabaseClass.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DatabaseClass.java
new file mode 100644
index 0000000..c82e964
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/DatabaseClass.java
@@ -0,0 +1,286 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.util.*;
+import java.sql.*;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.Singleton;
+
+
+public class DatabaseClass extends BaseLoggingClass {
+
+ private static Singleton<Dmaap> dmaap;
+ private static Map<String, DcaeLocation> dcaeLocations;
+ private static Map<String, DR_Node> dr_nodes;
+ private static Map<String, DR_Pub> dr_pubs;
+ private static Map<String, DR_Sub> dr_subs;
+ private static Map<String, MR_Client> mr_clients;
+ private static Map<String, MR_Cluster> mr_clusters;
+ private static Map<String, Feed> feeds;
+ private static Map<String, Topic> topics;
+ private static Map<String, MirrorMaker> mirrors;
+
+ private static long lastTime = 0L;
+ private static DBType databaseType;
+
+ private enum DBType {
+ PGSQL, MEMORY
+ }
+
+ public static Singleton<Dmaap> getDmaap() {
+ return dmaap;
+ }
+
+
+ public static Map<String, DcaeLocation> getDcaeLocations() {
+ return dcaeLocations;
+ }
+
+ public static Map<String, DR_Node> getDr_nodes() {
+ return dr_nodes;
+ }
+
+ public static Map<String, DR_Sub> getDr_subs() {
+ return dr_subs;
+ }
+
+ public static Map<String, DR_Pub> getDr_pubs() {
+ return dr_pubs;
+ }
+
+ public static Map<String, MR_Client> getMr_clients() {
+ return mr_clients;
+ }
+
+
+ public static Map<String, MR_Cluster> getMr_clusters() {
+ return mr_clusters;
+ }
+
+ public static Map<String, Feed> getFeeds() {
+ return feeds;
+ }
+
+ public static Map<String, Topic> getTopics() {
+ return topics;
+ }
+
+ public static Map<String, MirrorMaker> getMirrorMakers() {
+ return mirrors;
+ }
+
+ static {
+ try {
+ appLogger.info("begin static initialization");
+ appLogger.info("initializing dmaap");
+ determineDatabaseType();
+
+ switch (databaseType) {
+ case PGSQL:
+ databaseResourceInit();
+ break;
+ case MEMORY:
+ inMemoryResourceInit();
+ break;
+ }
+
+ dmaap.init(new Dmaap.DmaapBuilder().setVer("0").setTnr("").setDn("").setDpu("").setLu("").setBat("").setNk("").setAko("").createDmaap());
+ // force initial read from DB, if it exists
+ @SuppressWarnings("unused")
+ Dmaap dmx = dmaap.get();
+
+ // old code in this spot would read from properties file as part of init.
+ // but all those properties are now set via /dmaap API
+
+ } catch (Exception e) {
+ errorLogger.error("Error", e);
+ errorLogger.error(DmaapbcLogMessageEnum.DB_UPDATE_ERROR, e.getMessage());
+ }
+
+ }
+
+ public static synchronized String getNextClientId() {
+
+ long id = System.currentTimeMillis();
+ if (id <= lastTime) {
+ id = lastTime + 1;
+ }
+ lastTime = id;
+ return Long.toString(id);
+ }
+
+ public static synchronized void clearDatabase() {
+ switch (databaseType) {
+ case PGSQL:
+ try {
+ initDatabase();
+ } catch (Exception e) {
+ errorLogger.error("Error initializing database access " + e, e);
+ }
+ break;
+ case MEMORY:
+ initMemoryDatabase();
+ break;
+ }
+ }
+
+ private static void inMemoryResourceInit() {
+ appLogger.info("Data from memory");
+ dmaap = new Singleton<Dmaap>() {
+ private Dmaap dmaap;
+
+ public void remove() {
+ dmaap = null;
+ }
+
+ public void init(Dmaap val) {
+ if (dmaap == null) {
+ dmaap = val;
+ } else {
+ update(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());
+ }
+ };
+ initMemoryDatabase();
+ }
+
+ private static void databaseResourceInit() {
+ appLogger.info("Data from database");
+ try {
+ LoadSchema.loadSchema();
+ } catch (Exception e) {
+ appLogger.warn("Problem updating DB schema", e);
+ }
+ try {
+ Thread.sleep(5000);
+ dmaap = new DBSingleton<>(Dmaap.class, "dmaap");
+ TableHandler.setSpecialCase("topic", "replication_case", new TopicReplicationTypeHandler());
+ TableHandler.setSpecialCase("mirror_maker", "topics", new MirrorTopicsHandler());
+ initDatabase();
+ } catch (Exception e) {
+ errorLogger.error("Error initializing database access " + e, e);
+ System.exit(1);
+ }
+ }
+
+ 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<String> rv = new ArrayList<>();
+ for (String s : val.split(",")) {
+ 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<String> xv = (List<String>) val;
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ for (Object o : xv) {
+ String rv = (String) o;
+ sb.append(sep).append(DBFieldHandler.fesc(rv));
+ sep = ",";
+ }
+ ps.setString(index, sb.toString());
+ }
+ }
+
+ private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
+
+ public Object get(ResultSet rs, int index) throws Exception {
+ int val = rs.getInt(index);
+
+ return (ReplicationType.valueOf(val));
+ }
+
+ public void set(PreparedStatement ps, int index, Object val) throws Exception {
+ if (val == null) {
+ ps.setInt(index, 0);
+ return;
+ }
+ @SuppressWarnings("unchecked")
+ ReplicationType rep = (ReplicationType) val;
+ ps.setInt(index, rep.getValue());
+ }
+ }
+
+ private static void initMemoryDatabase() {
+ 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<>();
+ }
+
+ private static void initDatabase() throws Exception {
+ 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");
+ mirrors = new DBMap<>(MirrorMaker.class, "mirror_maker", "mm_name");
+ }
+
+ private static void determineDatabaseType() {
+ DmaapConfig dmaapConfig = (DmaapConfig) DmaapConfig.getConfig();
+ String isPgSQLset = dmaapConfig.getProperty("UsePGSQL", "false");
+ databaseType = isPgSQLset.equalsIgnoreCase("true") ? DBType.PGSQL : DBType.MEMORY;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/LoadSchema.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/LoadSchema.java
new file mode 100644
index 0000000..97bea4d
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/LoadSchema.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.io.FileReader;
+import java.io.LineNumberReader;
+import java.sql.Connection;
+import java.sql.Statement;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public class LoadSchema extends BaseLoggingClass {
+
+ private LoadSchema(){}
+
+ static void loadSchema() {
+ ConnectionFactory cf = ConnectionFactory.getDefaultInstance();
+ try (LineNumberReader lineReader = new LineNumberReader(new FileReader("/opt/app/dmaapbc/misc/schema_all.sql"));
+ Connection c = cf.get(true);
+ Statement stmt = c.createStatement()) {
+ StringBuilder strBuilder = new StringBuilder();
+ String line;
+ while ((line = lineReader.readLine()) != null) {
+ if (!line.startsWith("--")) {
+ line = line.trim();
+ strBuilder.append(line);
+ if (line.endsWith(";")) {
+ String sql = strBuilder.toString();
+ strBuilder.setLength(0);
+ stmt.execute(sql);
+ appLogger.debug("SQL EXECUTE SUCCESS: " + sql);
+ }
+ }
+ }
+ strBuilder.setLength(0);
+ } catch (Exception e) {
+ errorLogger.error("Error when initializing table: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/TableHandler.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/TableHandler.java
new file mode 100644
index 0000000..a85bdae
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/database/TableHandler.java
@@ -0,0 +1,126 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+class TableHandler<C> extends BaseLoggingClass {
+ protected ConnectionFactory cf;
+ protected boolean haskey;
+ protected String delstmt;
+ protected String insorreplstmt;
+ protected String getstmt;
+ protected String liststmt;
+ protected String initstmt;
+ protected Class<C> cls;
+ protected DBFieldHandler[] fields;
+ private static Map<String, Map<String, DBFieldHandler.SqlOp>> exceptions = new HashMap<>();
+ private String select = "SELECT ";
+ private String from = " FROM ";
+
+ protected TableHandler(Class<C> cls, String tabname, String keyname) throws Exception {
+ this(ConnectionFactory.getDefaultInstance(), cls, tabname, keyname);
+ }
+ protected TableHandler(ConnectionFactory cf, Class<C> 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);
+ }
+ }
+ }
+
+ public static void setSpecialCase(String dbtabname, String dbfldname, DBFieldHandler.SqlOp handler) {
+ Map<String, DBFieldHandler.SqlOp> 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<String, DBFieldHandler.SqlOp> m = exceptions.get(dbtabname);
+ if (m != null) {
+ return(m.get(dbfldname));
+ }
+ return(null);
+ }
+
+ private void setup(DatabaseMetaData dmd, Class<C> cls, String tabname, String keyname) throws Exception {
+ this.cls = cls;
+ Vector<DBFieldHandler> h = new Vector<>();
+ String qualifiedTableName = String.format( "%s.%s", cf.getSchema(), tabname );
+ ResultSet rs = dmd.getColumns("", cf.getSchema(), tabname, null);
+ StringBuilder sb1 = new StringBuilder();
+ StringBuilder sb2 = new StringBuilder();
+ StringBuilder sb3 = new StringBuilder();
+ 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 " + qualifiedTableName + " WHERE " + keyname + " = ?";
+ insorreplstmt = "INSERT INTO " + qualifiedTableName + " (" + clist + ", " + keyname + ") VALUES (" + qlist + ", ?) ON CONFLICT(" + keyname + ") DO UPDATE SET (" + clist + ") = (" + elist + ")";
+ getstmt = select + clist + ", " + keyname + from + qualifiedTableName + " WHERE " + keyname + " = ?";
+ liststmt = select + clist + ", " + keyname + from + qualifiedTableName;
+ } else {
+ delstmt = "DELETE FROM " + qualifiedTableName;
+ initstmt = "INSERT INTO " + qualifiedTableName + " (" + clist + ") VALUES (" + qlist + ")";
+ insorreplstmt = "UPDATE " + qualifiedTableName + " SET (" + clist + ") = (" + qlist + ")";
+ getstmt = select + clist + ", " + keyname + from + qualifiedTableName;
+ }
+ fields = h.toArray(new DBFieldHandler[h.size()]);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/BaseLoggingClass.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/BaseLoggingClass.java
new file mode 100644
index 0000000..4bde17a
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/BaseLoggingClass.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.logging;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public abstract class BaseLoggingClass {
+ protected EELFLogger logger = EELFManager.getInstance().getLogger( super.getClass());
+ protected static final EELFLogger appLogger = EELFManager.getInstance().getApplicationLogger();
+ protected static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
+ protected static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger();
+ protected static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ protected static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ protected static final EELFLogger serverLogger = EELFManager.getInstance().getServerLogger();
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/DmaapbcLogMessageEnum.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/DmaapbcLogMessageEnum.java
new file mode 100644
index 0000000..86c5fe0
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/DmaapbcLogMessageEnum.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.logging;
+
+import com.att.eelf.i18n.EELFResourceManager;
+import com.att.eelf.i18n.EELFResolvableErrorEnum;
+
+public enum DmaapbcLogMessageEnum implements EELFResolvableErrorEnum {
+//0xx sample stock messages
+ MESSAGE_SAMPLE_NOARGS,
+ MESSAGE_SAMPLE_ONE_ARG,
+ MESSAGE_SAMPLE_TWO_ARGS,
+
+// 1xx Permission Errors
+ AAF_CREDENTIAL_ERROR,
+ CODEC_CREDENTIAL_ERROR,
+ PE_AUTHENTICATION_ERROR,
+ DR_PROV_AUTHORIZATION,
+
+// 2xx Availability Errors/Timeouts
+ DRIVER_UNAVAILABLE,
+ HTTP_CONNECTION_ERROR,
+ HTTP_CONNECTION_EXCEPTION,
+ UNKNOWN_HOST_EXCEPTION,
+
+
+// 3xx Data Errors
+ IO_EXCEPTION,
+ SSL_HANDSHAKE_ERROR,
+ AAF_UNEXPECTED_RESPONSE,
+ PE_EXCEPTION,
+ SOCKET_EXCEPTION,
+ JSON_PARSING_ERROR,
+ DECRYPT_IO_ERROR,
+
+//4xx Schema Errors
+ DB_UPGRADE_ERROR,
+ DB_INIT_ERROR,
+ DB_UPDATE_ERROR,
+ DB_ACCESS_ERROR,
+ DB_FIELD_INIT_ERROR,
+ DB_ACCESS_INIT_ERROR,
+ DB_NO_FIELD_HANDLER,
+
+
+// 5xx Business Process Errors
+ PREREQ_DMAAP_OBJECT,
+ PROV_OUT_OF_SYNC,
+ MM_CIRCULAR_REF,
+ TOPIC_CREATE_ERROR,
+ INGRESS_CREATE_ERROR,
+ FEED_PUB_PROV_ERROR,
+ FEED_SUB_PROV_ERROR,
+ MM_PUBLISH_ERROR,
+ EGRESS_CREATE_ERROR,
+
+// 900 Unknown Errors
+ UNEXPECTED_CONDITION;
+
+ static {
+ EELFResourceManager.loadMessageBundle("logmsg");
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/logmsg.properties b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/logmsg.properties
new file mode 100644
index 0000000..6548433
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/logging/logmsg.properties
@@ -0,0 +1,240 @@
+###
+# ============LICENSE_START=======================================================
+# org.onap.dmaap
+# ================================================================================
+# 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=========================================================
+###
+
+# 0xx sample stock messages
+MESSAGE_SAMPLE_NOARGS=\
+ 01|\
+ Ignore: demo msg with no arg|\
+ No resolution|\
+ An example of a message with no args
+
+MESSAGE_SAMPLE_ONE_ARG=\
+ 02|\
+ Ignore: demo msg with 1 arg {0}|\
+ No resolution|\
+ An example of a message with 1 arg
+
+MESSAGE_SAMPLE_TWO_ARGS=\
+ 03|\
+ Ignore: demo msg with arg1 {0} and arg2 {1}|\
+ No resolution|\
+ An example of a message with 2 args
+
+
+
+# 1xx Permission Errors
+AAF_CREDENTIAL_ERROR=\
+ 101|\
+ Service credentials ({0}) are not valid for AAF connection|\
+ Check credentials are valid in appropriate AAF environment.|\
+ Connection to AAF was not allowed for the specified credentials.
+
+CODEC_CREDENTIAL_ERROR=\
+ 102|\
+ Failed to read CredentialCodecKeyfile {0} with error {1}|\
+ Check if CredentialCodecKeyfile has been corrupted.|\
+ CredentialCodecKeyfile is not in sync with application
+
+PE_AUTHENTICATION_ERROR=\
+ 103|\
+ User {0} perms {1} caught PolicyEngineException {1}|\
+ User needs to be granted perm before access.|\
+ Identified user was not authorized for the specific perm.
+
+DR_PROV_AUTHORIZATION=\
+ 104|\
+ Not authorized for API {0}|\
+ Bus Controller host needs to be provisioned as a Node and an AUTHORIZED_HOST.|\
+ DR Prov indicates that Bus Controller host is not authorized for the specified API.
+
+# 2xx Availability Errors/Timeouts
+DRIVER_UNAVAILABLE=\
+ 201|\
+ Unable to load driver {0}. Error {1}|\
+ Check that specified driver is installed and accessible to application.|\
+ The software attempted to load a driver and was not successful.
+
+HTTP_CONNECTION_ERROR=\
+ 202|\
+ Exception during openConnection to {0} failed with {1}|\
+ Confirm syntax of URL is correct and network access from this host is allowed.|\
+ An attempt to URL.openConnection failed
+
+HTTP_CONNECTION_EXCEPTION=\
+ 203|\
+ Connection to {0} refused because {1}|\
+ Check if this is the proper server.|\
+ Application caught a ConnectionException
+
+UNKNOWN_HOST_EXCEPTION=\
+ 204|\
+ Caught exception {0} attempting to access {1}|\
+ Confirm that host is in DNS|\
+ Caught UnknownHostException when connecting to the designated host name.
+
+# 3xx Data Errors
+IO_EXCEPTION=\
+ 301|\
+ IOexception {0}|\
+ No resolution.|\
+ Generic IO Exception condition
+
+SSL_HANDSHAKE_ERROR=\
+ 302|\
+ SSLHandshakeException from URL {0}|\
+ Confirm that target host has proper SSL certificate for DNS value used to access it.|\
+ SSLHandshake exception thrown on HttpsURLConnection method
+
+AAF_UNEXPECTED_RESPONSE=\
+ 303|\
+ rc= {0} :unable to {1} for {2}|\
+ Check configuration for this AAF instance.|\
+ Unexpected response from AAF for the intended action
+
+PE_EXCEPTION=\
+ 304|\
+ Trying to read {0} and caught PolicyEngineException {1}|\
+ Check config file exists and has proper settings.|\
+ An unexpected exception from PE was caught.
+
+SOCKET_EXCEPTION=\
+ 305|\
+ Caught exception {0} while {1}|\
+ No comment.|\
+ An unexpected socket exception was caught while performing the specified action.
+
+JSON_PARSING_ERROR=\
+ 306|\
+ ParsingException for object {0} using data:{1}|\
+ No comment.|\
+ The JSON data provided to the object was not in the expected format
+
+ DECRYPT_IO_ERROR=\
+ 307|\
+ IO Error attempting using {0} to decrypt value {1}|\
+ Check permissions of file set for property CredentialCodecKeyfile.|\
+ Error using codec file for decryption.
+
+# 4xx Schema Errors
+
+DB_UPGRADE_ERROR=\
+ 401|\
+ Problem updating DB schema. {0}|\
+ Examine stack trace for clues.|\
+ The software was not able to process the sql file resources in the jar file.
+
+DB_INIT_ERROR=\
+ 402|\
+ Error initializing database access: {0}|\
+ Correct configuration based on detail.|\
+ The software was not able initialize objects from the DB.
+
+DB_UPDATE_ERROR=\
+ 403|\
+ Error while updating DB: {0}|\
+ Correct configuration based on detail.|\
+ The software was not able to update record(s) in the DB.
+
+DB_ACCESS_ERROR=\
+ 404|\
+ Database access problem: {0}|\
+ Correct configuration based on detail.|\
+ An exception related to DB access was caught and logged.
+
+DB_FIELD_INIT_ERROR=\
+ 405|\
+ Problem setting field {0} to {1} statement is {2}|\
+ DB schema may be out of sync with code.|\
+ SQLDate.set() failed to set field value.
+
+DB_ACCESS_INIT_ERROR=\
+ 406|\
+ Problem initializing sql access methods {0} |\
+ No comment.|\
+ Error encountered while initializing basic field types.
+
+DB_NO_FIELD_HANDLER=\
+ 407|\
+ No field handler for class {0} field {1} index {2} type {3}|\
+ No comment.|\
+ Missing field handler for specified code.
+
+
+# 5xx Business Process Errors
+PREREQ_DMAAP_OBJECT=\
+ 501|\
+ Attempt to access {0} before dmaap object resource is available.|\
+ No remediation.|\
+ The dmaap object needs to be defined before attempting the desired access
+
+PROV_OUT_OF_SYNC=\
+ 502|\
+ Resource {0} with id {1} was not in sync with DR Prov.\
+ May need manual sync steps.\
+ The Bus Controller view of a resource does not match what was found on DR Prov
+
+MM_CIRCULAR_REF=\
+ 503|\
+ Trying to add edge from source {0} into Map belonging to {1}|\
+ May indicate a provisioning error.|\
+ Some error in logic is attempting to add an edge to a Map that is an edge.
+
+TOPIC_CREATE_ERROR=\
+ 504|\
+ Unable to create topic for {0} err={1} fields={2} msg={3}|\
+ No comment.|\
+ Reporting an error caught while creating a topic
+
+INGRESS_CREATE_ERROR=\
+ 505|\
+ rc={0} unable to create ingress rule for {1} on feed {2} to {3}|\
+ No comment.|\
+ Unexpected response while creating ingress rule
+
+FEED_PUB_PROV_ERROR=\
+ 506|\
+ For feed {0} resulting set of publishers do not match requested set of publishers {1} vs {2}|\
+ No comment.|\
+ The number of publishers on a feed do not match after provisioning request.
+
+FEED_SUB_PROV_ERROR=\
+ 507|\
+ For feed {0} i={1} url={2} err={3}|\
+ No comment.|\
+ An error occurred when provisioning subs on a feed.
+
+MM_PUBLISH_ERROR=\
+ 508|\
+ Unable to publish {0} provisioning message. rc={1} msg={2}|\
+ No comment.|\
+ An error occurred when publishing a message to MM
+
+EGRESS_CREATE_ERROR=\
+ 509|\
+ rc={0} unable to create egress rule for {1} on feed {2} to {3}|\
+ No comment.|\
+ Unexpected response while creating egress rule
+
+# 900 Unknown Errors
+UNEXPECTED_CONDITION=\
+ 901|\
+ Unexpected exception encountered {0}|\
+ No resolution|\
+ An error to catch unexpected conditions. Hopefully a clue in the stack trace.
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ApiError.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ApiError.java
new file mode 100644
index 0000000..c67e55b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ApiError.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Objects;
+
+@XmlRootElement
+public class ApiError implements Serializable {
+ private int code;
+ private String message;
+ private String fields;
+
+ public ApiError() {
+ this(0, null, null);
+ }
+
+ public ApiError(int code, String message) {
+ this(code, message, null);
+ }
+
+ public ApiError(int code, String message, String fields) {
+ this.code = code;
+ this.message = message;
+ this.fields = 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;
+ }
+ public void reset() {
+ code = 0;
+ message = null;
+ fields = null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ApiError apiError = (ApiError) o;
+ return code == apiError.code &&
+ Objects.equals(message, apiError.message) &&
+ Objects.equals(fields, apiError.fields);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(code, message, fields);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/BrTopic.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/BrTopic.java
new file mode 100644
index 0000000..ba050c3
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/BrTopic.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class BrTopic {
+
+ private String brSource;
+ private String brTarget;
+ private String mmAgentName;
+ 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;
+ }
+
+ public String getMmAgentName() {
+ return mmAgentName;
+ }
+
+ public void setMmAgentName(String mmAgentName) {
+ this.mmAgentName = mmAgentName;
+ }
+
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Node.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Node.java
new file mode 100644
index 0000000..4b2ef90
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Node.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Objects;
+
+@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;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DR_Node dr_node = (DR_Node) o;
+ return Objects.equals(fqdn, dr_node.fqdn) &&
+ Objects.equals(dcaeLocationName, dr_node.dcaeLocationName) &&
+ Objects.equals(hostName, dr_node.hostName) &&
+ Objects.equals(version, dr_node.version);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(fqdn, dcaeLocationName, hostName, version);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Pub.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Pub.java
new file mode 100644
index 0000000..4e64089
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Pub.java
@@ -0,0 +1,187 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.onap.dmaap.dbcapi.util.RandomString;
+
+import java.util.Objects;
+
+@XmlRootElement
+public class DR_Pub extends DmaapObject {
+
+ private String dcaeLocationName;
+ private String username;
+ private String userpwd;
+ private String feedId;
+ private String pubId;
+
+ // NOTE: the following fields are optional in the API but not stored in the DB
+ private String feedName;
+ private String feedVersion;
+
+
+ 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 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 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();
+
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DR_Pub dr_pub = (DR_Pub) o;
+ return Objects.equals(dcaeLocationName, dr_pub.dcaeLocationName) &&
+ Objects.equals(username, dr_pub.username) &&
+ Objects.equals(userpwd, dr_pub.userpwd) &&
+ Objects.equals(feedId, dr_pub.feedId) &&
+ Objects.equals(pubId, dr_pub.pubId);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(dcaeLocationName, username, userpwd, feedId, pubId);
+ }
+
+ @Override
+ public String toString() {
+ return "DR_Pub{" +
+ "dcaeLocationName='" + dcaeLocationName + '\'' +
+ ", username='" + username + '\'' +
+ ", userpwd='" + userpwd + '\'' +
+ ", feedId='" + feedId + '\'' +
+ ", pubId='" + pubId + '\'' +
+ ", feedName='" + feedName + '\'' +
+ ", feedVersion='" + feedVersion + '\'' +
+ '}';
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java
new file mode 100644
index 0000000..90da956
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java
@@ -0,0 +1,391 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import java.nio.charset.StandardCharsets;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+
+@XmlRootElement
+public class DR_Sub extends DmaapObject {
+
+ 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;
+ private boolean guaranteedDelivery;
+ private boolean guaranteedSequence;
+ private boolean privilegedSubscriber;
+ private boolean decompress;
+
+ // NOTE: the following fields are optional in the API but not stored in the DB
+
+ private String feedName;
+ private String feedVersion;
+ 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 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.JSON_PARSING_ERROR, "DR_Sub", json );
+ this.setStatus( DmaapObject_Status.INVALID );
+ return;
+ }
+
+ this.setOwner( (String) jsonObj.get("subscriber"));
+ this.setSuspended( (boolean) jsonObj.get("suspend"));
+
+ try {
+ 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") );
+ } catch (NullPointerException npe ) {
+
+ }
+ try {
+ this.setGuaranteedDelivery( (boolean) jsonObj.get("guaranteed_delivery"));
+ } catch( NullPointerException npe ) {
+ this.setGuaranteedDelivery(false);
+ }
+ try {
+ this.setGuaranteedSequence( (boolean) jsonObj.get("guaranteed_sequence"));
+ } catch( NullPointerException npe ) {
+ this.setGuaranteedSequence(false);
+ }
+ try {
+ this.setPrivilegedSubscriber((boolean) jsonObj.get("privilegedSubscriber"));
+ } catch( NullPointerException npe ) {
+ this.setPrivilegedSubscriber(false);
+ }
+ try {
+ this.setDecompress((boolean) jsonObj.get("decompress"));
+ } catch( NullPointerException npe ) {
+ this.setDecompress(false);
+ }
+
+ 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 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 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 boolean isGuaranteedDelivery() {
+ return guaranteedDelivery;
+ }
+
+ public void setGuaranteedDelivery(boolean guaranteedDelivery) {
+ this.guaranteedDelivery = guaranteedDelivery;
+ }
+
+ public boolean isGuaranteedSequence() {
+ return guaranteedSequence;
+ }
+
+ public void setGuaranteedSequence(boolean guaranteedSequence) {
+ this.guaranteedSequence = guaranteedSequence;
+ }
+
+ public boolean isPrivilegedSubscriber() {
+ return privilegedSubscriber;
+ }
+
+ public void setPrivilegedSubscriber(boolean privilegedSubscriber) {
+ this.privilegedSubscriber = privilegedSubscriber;
+ }
+
+ public boolean isDecompress() {
+ return decompress;
+ }
+
+ public void setDecompress(boolean decompressData) {
+ this.decompress = decompressData;
+ }
+
+ 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 byte[] getBytes(String provApi) {
+ if ( "AT&T".equals(provApi)) {
+ return toProvJSONforATT().getBytes(StandardCharsets.UTF_8);
+ }
+ return toProvJSON().getBytes(StandardCharsets.UTF_8);
+ }
+ // returns the DR_Sub object in JSON that conforms to ONAP DR Prov Server expectations
+ public String toProvJSON() {
+ // this is the original DR API that was contributed to ONAP
+ String postJSON = String.format("{\"suspend\": %s, \"delivery\":"
+ + "{\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": %s }"
+ + ", \"metadataOnly\": %s, \"groupid\": \"%s\", \"follow_redirect\": %s "
+ + ", \"privilegedSubscriber\": %s, \"decompress\": %s "
+ + "}"
+ ,this.suspended
+ ,this.getDeliveryURL()
+ ,this.getUsername()
+ ,this.getUserpwd()
+ ,this.isUse100()
+ ,"false"
+ ,"0"
+ ,"true"
+ ,this.isPrivilegedSubscriber()
+ ,this.isDecompress()
+ );
+
+ logger.info( postJSON );
+ return postJSON;
+ }
+ // returns the DR_Sub object in JSON that conforms to AT&T DR Prov Server expectations
+ // In Jan, 2019, the DR API used internally at AT&T diverged, so this function can be used in
+ // that runtime environment
+ public String toProvJSONforATT() {
+ // 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...
+ // Similarly, in the 1704 Release, a new subscriber attribute "follow_redirect" was introduced.
+ // We are setting it to "true" because that is the general behavior desired in OpenDCAE.
+ // But it is really a no-op for OpenDCAE because we've deployed DR with the SYSTEM-level parameter for FOLLOW_REDIRECTS set to true.
+ // In the event we abandon that, then setting the sub attribute to true will be a good thing.
+ // Update Jan, 2019: added guaranteed_delivery and guaranteed_sequence with value false for
+ // backwards compatibility
+ // TODO:
+ // - introduce Bus Controller API support for these attributes
+ // - store the default values in the DB
+ String postJSON = String.format("{\"suspend\": %s, \"delivery\":"
+ + "{\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": %s}"
+ + ", \"metadataOnly\": %s, \"groupid\": \"%s\", \"follow_redirect\": %s "
+ + ", \"guaranteed_delivery\": %s, \"guaranteed_sequence\": %s"
+ + "}"
+ ,this.suspended
+ ,this.getDeliveryURL()
+ ,this.getUsername()
+ ,this.getUserpwd()
+ ,this.isUse100()
+ ,"false"
+ ,"0"
+ ,"true"
+ ,this.isGuaranteedDelivery()
+ ,this.isGuaranteedSequence()
+ );
+
+ logger.info( postJSON );
+ return postJSON;
+ }
+
+ @Override
+ public String toString() {
+ return String.format ( "DR_Sub: {dcaeLocationName=%s username=%s userpwd=%s feedId=%s deliveryURL=%s logURL=%s subid=%s use100=%s suspended=%s owner=%s}",
+ dcaeLocationName,
+ username,
+ userpwd,
+ feedId,
+ deliveryURL,
+ logURL,
+ subId,
+ use100,
+ suspended,
+ owner
+ );
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ DR_Sub drSub = (DR_Sub) o;
+
+ if (use100 != drSub.use100) {
+ return false;
+ }
+ if (suspended != drSub.suspended) {
+ return false;
+ }
+ if (!dcaeLocationName.equals(drSub.dcaeLocationName)) {
+ return false;
+ }
+ if (!username.equals(drSub.username)) {
+ return false;
+ }
+ if (!userpwd.equals(drSub.userpwd)) {
+ return false;
+ }
+ if (!feedId.equals(drSub.feedId)) {
+ return false;
+ }
+ return subId.equals(drSub.subId);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = dcaeLocationName.hashCode();
+ result = 31 * result + username.hashCode();
+ result = 31 * result + userpwd.hashCode();
+ result = 31 * result + feedId.hashCode();
+ result = 31 * result + subId.hashCode();
+ result = 31 * result + (use100 ? 1 : 0);
+ result = 31 * result + (suspended ? 1 : 0);
+ return result;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DcaeLocation.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DcaeLocation.java
new file mode 100644
index 0000000..f459c6c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DcaeLocation.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import java.util.Objects;
+
+@XmlRootElement
+public class DcaeLocation extends DmaapObject {
+ 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;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DcaeLocation that = (DcaeLocation) o;
+ return Objects.equals(clli, that.clli) &&
+ Objects.equals(dcaeLayer, that.dcaeLayer) &&
+ Objects.equals(dcaeLocationName, that.dcaeLocationName) &&
+ Objects.equals(openStackAvailabilityZone, that.openStackAvailabilityZone) &&
+ Objects.equals(subnet, that.subnet);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(clli, dcaeLayer, dcaeLocationName, openStackAvailabilityZone, subnet);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Dmaap.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Dmaap.java
new file mode 100644
index 0000000..96248f3
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Dmaap.java
@@ -0,0 +1,177 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Dmaap extends DmaapObject {
+
+ 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( DmaapBuilder builder ) {
+ this.version = builder.ver;
+ this.topicNsRoot = builder.tnr;
+ this.dmaapName = builder.dn;
+ this.drProvUrl = builder.dpu;
+ this.bridgeAdminTopic = builder.bat;
+ this.loggingUrl = builder.lu;
+ this.nodeKey = builder.nk;
+ this.accessKeyOwner = builder.ako;
+ this.setStatus( DmaapObject_Status.NEW );
+
+ }
+
+ public static class DmaapBuilder {
+ private String ver;
+ private String tnr;
+ private String dn;
+ private String dpu;
+ private String lu;
+ private String bat;
+ private String nk;
+ private String ako;
+
+ public DmaapBuilder setVer(String ver) {
+ this.ver = ver;
+ return this;
+ }
+
+ public DmaapBuilder setTnr(String tnr) {
+ this.tnr = tnr;
+ return this;
+ }
+
+ public DmaapBuilder setDn(String dn) {
+ this.dn = dn;
+ return this;
+ }
+
+ public DmaapBuilder setDpu(String dpu) {
+ this.dpu = dpu;
+ return this;
+ }
+
+ public DmaapBuilder setLu(String lu) {
+ this.lu = lu;
+ return this;
+ }
+
+ public DmaapBuilder setBat(String bat) {
+ this.bat = bat;
+ return this;
+ }
+
+ public DmaapBuilder setNk(String nk) {
+ this.nk = nk;
+ return this;
+ }
+
+ public DmaapBuilder setAko(String ako) {
+ this.ako = ako;
+ return this;
+ }
+
+ public Dmaap createDmaap() {
+ return new Dmaap(this);
+ }
+ }
+
+ 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/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DmaapObject.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DmaapObject.java
new file mode 100644
index 0000000..4ff2eec
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/DmaapObject.java
@@ -0,0 +1,144 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+@XmlRootElement
+public abstract class DmaapObject extends BaseLoggingClass {
+ @ApiModelProperty( value = "datestamp for last update to this object")
+ 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 void setStatus( String val ) {
+ if ( val == null || val.isEmpty() ) {
+ this.status = DmaapObject_Status.EMPTY;
+ } else if (val.compareToIgnoreCase("new") == 0 ) {
+ this.status = DmaapObject_Status.NEW;
+ } else if ( val.compareToIgnoreCase("staged" ) == 0) {
+ this.status = DmaapObject_Status.STAGED;
+ } else if ( val.compareToIgnoreCase("valid") == 0) {
+ this.status = DmaapObject_Status.VALID;
+ } else if ( val.compareToIgnoreCase("invalid") == 0) {
+ this.status = DmaapObject_Status.INVALID;
+ } else if ( val.compareToIgnoreCase("deleted") == 0) {
+ this.status = DmaapObject_Status.DELETED;
+ } else {
+ this.status = DmaapObject_Status.INVALID;
+ }
+ }
+
+ @ApiModelProperty( hidden=true )
+ public boolean isStatusValid() {
+ if ( this.status == DmaapObject_Status.VALID ) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * TODO: get this working so arrays and sub-class within an Object can be logged
+ *
+ public String toString() {
+ return classToString( this );
+ }
+
+ private String classToString( Object obj ) {
+ Field[] fields = obj.getClass().getDeclaredFields();
+ StringBuilder res = new StringBuilder( "{");
+ boolean first = true;
+ for ( Field field: fields ) {
+ logger.info( field.getName() + " toString=" + field.toString() + " toGenericString=" + field.toGenericString());
+ if ( first ) {
+ first = false;
+ } else {
+ res.append( ", ");
+ }
+
+
+ field.setAccessible(true); // avoid IllegalAccessException
+
+
+ Class<?> t = field.getType();
+
+ if ( t == String.class ) {
+ res.append( "\"" ).append( field.getName() ).append( "\": \"");
+
+ try {
+ res.append(field.get(this));
+ } catch ( IllegalAccessException iae) {
+ res.append( "UNK(iae)");
+ } catch (IllegalArgumentException iae2 ) {
+ res.append( "UNK(iae2)");
+ } catch ( NullPointerException npe ) {
+ res.append( "UNK(npe)");
+ } catch ( ExceptionInInitializerError eie ) {
+ res.append( "UNK(eie)");
+ }
+ res.append( "\"");
+ } else if ( t == ArrayList.class ){
+ res.append( "[");
+ res.append( classToString( field ));
+ res.append( "]");
+
+ }
+ }
+ res.append( "}");
+ return( res.toString());
+
+
+ }
+ */
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Feed.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Feed.java
new file mode 100644
index 0000000..b3c7332
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Feed.java
@@ -0,0 +1,294 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.json.simple.*;
+import org.json.simple.parser.*;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+@XmlRootElement
+public class Feed extends DmaapObject {
+
+ 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<DR_Pub> pubs;
+ private ArrayList<DR_Sub> subs;
+
+
+ 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> 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 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 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() {
+
+ 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<DR_Pub> getPubs() {
+ return pubs;
+ }
+
+ public void setPubs( ArrayList<DR_Pub> pubs) {
+ this.pubs = pubs;
+ }
+
+ public ArrayList<DR_Sub> getSubs() {
+ return subs;
+ }
+
+ public void setSubs( ArrayList<DR_Sub> subs) {
+ this.subs = subs;
+ }
+
+ public byte[] getBytes() {
+ return toProvJSON().getBytes(StandardCharsets.UTF_8);
+ }
+
+ public static String getSubProvURL( String feedId ) {
+ return new DmaapService().getDmaap().getDrProvUrl() + "/subscribe/" + feedId;
+ }
+
+ @Override
+ public String toString() {
+ String rc = String.format ( "Feed: {feedId=%s feedName=%s feedVersion=%s feedDescription=%s owner=%s asprClassification=%s publishURL=%s subscriberURL=%s suspended=%s logURL=%s formatUuid=%s}",
+ feedId,
+ feedName,
+ feedVersion,
+ feedDescription,
+ owner,
+ asprClassification,
+ publishURL,
+ subscribeURL,
+ suspended,
+ logURL,
+ formatUuid
+
+
+ );
+
+ for( DR_Pub pub: pubs) {
+ rc += "\n" + pub.toString();
+ }
+
+ for( DR_Sub sub: subs ) {
+ rc += "\n" + sub.toString();
+ }
+ return rc;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/FqtnType.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/FqtnType.java
new file mode 100644
index 0000000..697e9b8
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/FqtnType.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+public enum FqtnType {
+ FQTN_NOT_SPECIFIED(0),
+ FQTN_LEGACY_FORMAT(1),
+ FQTN_PROJECTID_FORMAT(2),
+ FQTN_PROJECTID_VERSION_FORMAT(3);
+
+
+ private int value;
+ private static Map map = new HashMap<>();
+
+ private FqtnType(int value) {
+ this.value = value;
+ }
+
+ static {
+ for (FqtnType repType : FqtnType.values()) {
+ map.put(repType.value, repType);
+ }
+ }
+
+ public static FqtnType valueOf(int repType) {
+ return (FqtnType) map.get(repType);
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ static public FqtnType Validator( String input ){
+
+ FqtnType t;
+ try {
+ t = FqtnType.valueOf( input );
+ } catch ( IllegalArgumentException e ) {
+ t = FQTN_NOT_SPECIFIED;
+ }
+ return t;
+ }
+
+} \ No newline at end of file
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Client.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Client.java
new file mode 100644
index 0000000..0631f07
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Client.java
@@ -0,0 +1,162 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import java.util.Date;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+
+import io.swagger.annotations.ApiModelProperty;
+
+@XmlRootElement
+public class MR_Client extends DmaapObject {
+
+ @ApiModelProperty( value="a tag indicating a logical deployment site")
+ private String dcaeLocationName;
+ @ApiModelProperty( value="the URL for a MR instance - typically in the same dcaeLocation - that this client should use to access the topic")
+ private String topicURL;
+ @ApiModelProperty( value="Fully Qualified Topic Name constructed by dbcapi")
+ private String fqtn;
+ @ApiModelProperty( value="an AAF Role to be granted an appropriate Permission. If specified, takes precedence over clientIdentity, for backwards compatibility.")
+ private String clientRole;
+ @ApiModelProperty( value="one or more actions from the set (\"pub\", \"sub\", \"view\") for which this client needs Permission")
+ private String[] action;
+ @ApiModelProperty( value="a unique identifier generated by dbcapi for this client")
+ private String mrClientId;
+ @ApiModelProperty( value="an AAF identity to be associated to an appropriate topic Role")
+ private String clientIdentity;
+
+
+ public MR_Client() {
+ this.mrClientId = DatabaseClass.getNextClientId();
+ this.lastMod = new Date();
+ this.setLastMod();
+ debugLogger.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 (a != 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();
+ debugLogger.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;
+ }
+
+ @ApiModelProperty( hidden=true )
+ public boolean isPublisher() {
+ return hasAction( "pub");
+ }
+ @ApiModelProperty( hidden=true )
+ public boolean isSubscriber() {
+ return hasAction( "sub");
+ }
+
+ public boolean hasAction( String val ) {
+ for (String s: this.action) {
+ if ( s!= null && s.equals(val)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ 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;
+ }
+
+ public String getClientIdentity() {
+ return clientIdentity;
+ }
+
+ public void setClientIdentity(String clientIdentity) {
+ this.clientIdentity = clientIdentity;
+ }
+ public boolean hasClientIdentity() {
+ if ( this.clientIdentity == null || this.clientIdentity.isEmpty() ) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Cluster.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Cluster.java
new file mode 100644
index 0000000..06b6194
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MR_Cluster.java
@@ -0,0 +1,235 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.DmaapTimestamp;
+
+
+
+@XmlRootElement
+public class MR_Cluster extends DmaapObject {
+
+ private String dcaeLocationName;
+ private String fqdn;
+ private DmaapTimestamp lastMod;
+ private String topicProtocol;
+ private String topicPort;
+ private String replicationGroup;
+ private String sourceReplicationPort;
+ private String targetReplicationPort;
+
+
+ // TODO: make this a system property
+ private static String defaultTopicProtocol;
+ private static String defaultTopicPort;
+ private static String defaultReplicationGroup;
+ private static String defaultSourceReplicationPort;
+ private static String defaultTargetReplicationPort;
+
+ private static void setDefaults() {
+ /* boolean been_here = false;
+ if ( been_here ) {
+ return;
+ } */
+ DmaapConfig dc = (DmaapConfig)DmaapConfig.getConfig();
+ defaultTopicProtocol = dc.getProperty("MR.TopicProtocol", "https");
+ defaultTopicPort = dc.getProperty( "MR.TopicPort", "3905");
+ defaultReplicationGroup = dc.getProperty( "MR.ReplicationGroup", "" );
+ defaultSourceReplicationPort = dc.getProperty( "MR.SourceReplicationPort", "2181");
+ defaultTargetReplicationPort = dc.getProperty( "MR.TargetReplicationPort", "9092");
+ // been_here = true;
+ }
+
+
+ public MR_Cluster() {
+ setDefaults();
+ this.topicProtocol = defaultTopicProtocol;
+ this.topicPort = defaultTopicPort;
+ this.replicationGroup = null;
+ this.sourceReplicationPort = defaultSourceReplicationPort;
+ this.targetReplicationPort = defaultTargetReplicationPort;
+ this.lastMod = new DmaapTimestamp();
+ this.lastMod.mark();
+
+ debugLogger.debug( "MR_Cluster constructor " + this.lastMod );
+
+ }
+
+ // new style constructor
+ public MR_Cluster( String dLN,
+ String f,
+ String prot,
+ String port) {
+ setDefaults();
+ this.dcaeLocationName = dLN;
+ this.fqdn = f;
+
+ if ( prot == null || prot.isEmpty() ) {
+ this.topicProtocol = defaultTopicProtocol;
+ } else {
+ this.topicProtocol = prot;
+ }
+ if ( port == null || port.isEmpty() ) {
+ this.topicPort = defaultTopicPort;
+ } else {
+ this.topicPort = port;
+ }
+
+ this.replicationGroup = defaultReplicationGroup;
+ this.sourceReplicationPort = defaultSourceReplicationPort;
+ this.targetReplicationPort = defaultTargetReplicationPort;
+
+ this.lastMod = new DmaapTimestamp();
+ this.lastMod.mark();
+
+ debugLogger.debug( "MR_Cluster constructor w initialization complete" + this.lastMod.getVal() );
+ }
+
+ public MR_Cluster( String dLN,
+ String f,
+ String prot,
+ String port,
+ String repGroup,
+ String sourceRepPort,
+ String targetRepPort ) {
+ setDefaults();
+ this.dcaeLocationName = dLN;
+ this.fqdn = f;
+
+ if ( prot == null || prot.isEmpty() ) {
+ this.topicProtocol = defaultTopicProtocol;
+ } else {
+ this.topicProtocol = prot;
+ }
+ if ( port == null || port.isEmpty() ) {
+ this.topicPort = defaultTopicPort;
+ } else {
+ this.topicPort = port;
+ }
+ if ( repGroup == null || repGroup.isEmpty() ) {
+ this.replicationGroup = defaultReplicationGroup;
+ } else {
+ this.replicationGroup = repGroup;
+ }
+ if ( sourceRepPort == null || sourceRepPort.isEmpty()) {
+ this.sourceReplicationPort = defaultSourceReplicationPort;
+ } else {
+ this.sourceReplicationPort = sourceRepPort;
+ }
+ if ( targetRepPort == null || targetRepPort.isEmpty()) {
+ this.targetReplicationPort = defaultTargetReplicationPort;
+ } else {
+ this.targetReplicationPort = targetRepPort;
+ }
+
+ this.lastMod = new DmaapTimestamp();
+ this.lastMod.mark();
+
+ debugLogger.debug( "MR_Cluster constructor w initialization complete" + this.lastMod.getVal() );
+ }
+ 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 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 getReplicationGroup() {
+ return replicationGroup;
+ }
+
+ public void setReplicationGroup(String replicationGroup) {
+ this.replicationGroup = replicationGroup;
+ }
+
+
+
+
+ public String getSourceReplicationPort() {
+ return sourceReplicationPort;
+ }
+
+
+
+ public void setSourceReplicationPort(String sourceReplicationPort) {
+ this.sourceReplicationPort = sourceReplicationPort;
+ }
+
+
+
+ public String getTargetReplicationPort() {
+ return targetReplicationPort;
+ }
+
+
+
+ public void setTargetReplicationPort(String targetReplicationPort) {
+ this.targetReplicationPort = targetReplicationPort;
+ }
+
+
+
+ public String genTopicURL(String overideFqdn, String topic) {
+
+ StringBuilder str = new StringBuilder( topicProtocol );
+ str.append("://")
+ .append( overideFqdn != null ? overideFqdn : fqdn)
+ .append(":")
+ .append(topicPort)
+ .append("/events/")
+ .append(topic);
+
+ return str.toString();
+
+
+ }
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MirrorMaker.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MirrorMaker.java
new file mode 100644
index 0000000..098524c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/MirrorMaker.java
@@ -0,0 +1,165 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import org.onap.dmaap.dbcapi.service.MirrorMakerService;
+
+import java.util.ArrayList;
+
+public class MirrorMaker extends DmaapObject {
+
+ private String sourceCluster;
+ private String targetCluster;
+ private String mmName;
+ private ArrayList<String> topics; //re-using this var name for backwards DB compatibility
+
+ public MirrorMaker(){
+
+ }
+
+ public MirrorMaker(String source, String target, int i) {
+ initMM( source, target );
+ // original mm names did not have any index, so leave off index 0 for
+ // backwards compatibility
+ if ( i != 0 ) {
+ String n = this.getMmName() + "_" + i;
+ this.setMmName(n);
+ }
+ }
+
+ public MirrorMaker(String source, String target) {
+ initMM( source, target );
+ }
+
+ private void initMM(String source, String target) {
+ sourceCluster = source;
+ targetCluster = target;
+ mmName = genKey(source, target);
+ topics = new ArrayList<>();
+
+ }
+
+ public String getMmName() {
+ return mmName;
+ }
+
+ public void setMmName(String mmName) {
+ this.mmName = mmName;
+ }
+
+ // 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 getWhitelistUpdateJSON() {
+ StringBuilder str = new StringBuilder( "{ \"messageID\": \"" + MirrorMakerService.genTransactionId() + "\", \"updateWhiteList\": {" );
+ str.append( " \"name\": \"" + this.getMmName() + "\", \"whitelist\": \"" );
+ int numTargets = 0;
+
+ for (String rv: topics) {
+ if ( numTargets > 0 ) {
+ str.append( ",");
+ }
+ 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( String consumerPort, String producerPort ) {
+ StringBuilder str = new StringBuilder( "{ \"messageID\": \"" + MirrorMakerService.genTransactionId() + "\", \"createMirrorMaker\": {" );
+ str.append( " \"name\": \"" + this.getMmName() + "\", " );
+ str.append( " \"consumer\": \"" + this.sourceCluster + ":" + consumerPort + "\", " );
+ str.append( " \"producer\": \"" + this.targetCluster + ":" + producerPort + "\", ");
+
+ str.append( " \"numStreams\": \"10\" } }" );
+
+ 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 ArrayList<String> getTopics() {
+ return topics;
+ }
+
+ public void setTopics(ArrayList<String> 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 ) {
+ if ( ! topics.contains(topic)) {
+ topics.add(topic);
+ }
+ logger.info( "Mirrormaker.addTopic: topic=" + topic + " . Now have " + topics.size() + " topics" );
+ }
+
+ public int getTopicCount() {
+ return topics.size();
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ReplicationType.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ReplicationType.java
new file mode 100644
index 0000000..5d5b6c6
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/ReplicationType.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+public enum ReplicationType {
+ REPLICATION_NOT_SPECIFIED(0),
+ REPLICATION_NONE(1),
+ REPLICATION_EDGE_TO_CENTRAL(10),
+ REPLICATION_EDGE_TO_CENTRAL_TO_GLOBAL(110),
+ REPLICATION_CENTRAL_TO_EDGE(20),
+ REPLICATION_CENTRAL_TO_GLOBAL(21),
+ REPLICATION_GLOBAL_TO_CENTRAL(30),
+ REPLICATION_GLOBAL_TO_CENTRAL_TO_EDGE(120),
+ REPLICATION_EDGE_TO_FQDN(40),
+ REPLICATION_FQDN_TO_EDGE(41),
+ REPLICATION_FQDN_TO_GLOBAL(50),
+ REPLICATION_GLOBAL_TO_FQDN(51),
+ REPLICATION_EDGE_TO_FQDN_TO_GLOBAL(130),
+ REPLICATION_GLOBAL_TO_FQDN_TO_EDGE (140);
+
+ private int value;
+ private static Map map = new HashMap<>();
+
+ private ReplicationType(int value) {
+ this.value = value;
+ }
+
+ static {
+ for (ReplicationType repType : ReplicationType.values()) {
+ map.put(repType.value, repType);
+ }
+ }
+
+ public static ReplicationType valueOf(int repType) {
+ return (ReplicationType) map.get(repType);
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ static public ReplicationType Validator( String input ){
+
+ ReplicationType t;
+ try {
+ t = ReplicationType.valueOf( input );
+ } catch ( IllegalArgumentException e ) {
+ t = REPLICATION_NOT_SPECIFIED;
+ }
+ return t;
+ }
+
+ public boolean involvesGlobal() {
+
+
+ if ( ( this.compareTo(REPLICATION_CENTRAL_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_CENTRAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_EDGE_TO_CENTRAL_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_CENTRAL_TO_EDGE) == 0 ) ||
+ ( this.compareTo(REPLICATION_EDGE_TO_FQDN_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_FQDN_TO_EDGE) == 0 ) ||
+ ( this.compareTo(REPLICATION_FQDN_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_FQDN) == 0 ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean involvesFQDN() {
+ if (
+ ( this.compareTo(REPLICATION_EDGE_TO_FQDN) == 0 ) ||
+ ( this.compareTo(REPLICATION_EDGE_TO_FQDN_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_FQDN_TO_EDGE) == 0 ) ||
+ ( this.compareTo(REPLICATION_FQDN_TO_GLOBAL) == 0 ) ||
+ ( this.compareTo(REPLICATION_GLOBAL_TO_FQDN) == 0 ) ||
+ ( this.compareTo(REPLICATION_FQDN_TO_EDGE) == 0 )
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Topic.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Topic.java
new file mode 100644
index 0000000..d2a9077
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/model/Topic.java
@@ -0,0 +1,352 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import com.google.common.base.Objects;
+import io.swagger.annotations.ApiModelProperty;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+@XmlRootElement
+public class Topic extends DmaapObject {
+
+ @ApiModelProperty( value="Fully Qualified Topic Name constructed by dbcapi, following the rules for `fqtnStyle`")
+ private String fqtn;
+ @ApiModelProperty( value="the short name used by humans, and utilized to construct the `FQTN`")
+ private String topicName;
+ @ApiModelProperty( value="a description of what this Topic is used for")
+ private String topicDescription;
+ private String tnxEnabled;
+ @ApiModelProperty( value="a label used to identify who requested this `Topic` to be provisioned. In the future this "
+ + "may be an AAF Identity.")
+ private String owner;
+ @ApiModelProperty( value="a reference to an identifier that describes a data format used for this `Topic`")
+ private String formatUuid;
+ @ApiModelProperty( value="An indicator for how this `Topic` should be replicated when there are more than one `MR_Cluster` instances")
+ private ReplicationType replicationCase;
+ @ApiModelProperty( value="the URL of an outside MR instance")
+ private String globalMrURL; // optional: URL of global MR to replicate to/from
+ @ApiModelProperty( value="the construction rule for the `fqtn` field")
+ private FqtnType fqtnStyle;
+ @ApiModelProperty( value="a hook for any versioning needed for managing a `Topic` over time")
+ private String version;
+ @ApiModelProperty( value="the kafka attribute for specifying the number of partitions")
+ private String partitionCount;
+ @ApiModelProperty( value="the kafka attribute for specifying replication within an `MR_Cluster` instance")
+ private String replicationCount;
+ @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to publish to this `Topic`")
+ private String publisherRole;
+ @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to subscribe to this `Topic`")
+ private String subscriberRole;
+
+ @ApiModelProperty( value="an array of `MR_Client` objects associated to this `Topic`")
+ private List<MR_Client> clients;
+
+
+
+ private static Dmaap dmaap = new DmaapService().getDmaap();
+
+ private static String defaultPartitionCount;
+ private static String defaultReplicationCount;
+
+ // during unit testing, discovered that presence of dots in some values
+ // creates an unplanned topic namespace as we compose the FQTN.
+ // this may create sensitivity (i.e. 403) for subsequent creation of AAF perms, so best to not allow it
+ private static String removeDots( String source, String def ) {
+ if ( source == null || source.isEmpty()) {
+ return def;
+ }
+ return source.replaceAll("\\.", "_");
+ }
+ //
+ // utility function to generate the FQTN of a topic
+ public String genFqtn( ) {
+ DmaapConfig dc = (DmaapConfig)DmaapConfig.getConfig();
+ String projectId = dc.getProperty("MR.projectID", "99999");
+ CharSequence signal = ".";
+ String ret;
+ if ( this.getTopicName().contains( signal )) {
+ // presence of a dot indicates the name is already fully qualified
+ ret = this.getTopicName();
+ } else {
+ // these vars may not contain dots
+ String p = removeDots( projectId, "90909");
+ String v = removeDots( this.getVersion(), "v1");
+ switch( this.getFqtnStyle() ) {
+ case FQTN_PROJECTID_VERSION_FORMAT:
+
+ ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName() + "-" + v;
+ break;
+
+ case FQTN_PROJECTID_FORMAT:
+
+ ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName();
+ break;
+
+ case FQTN_LEGACY_FORMAT:
+ default: // for backwards compatibility
+ ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + this.getTopicName();
+ break;
+
+
+ }
+
+ }
+ return ret;
+ }
+
+
+
+ public Topic() {
+ super();
+ this.clients = new ArrayList<>();
+ this.lastMod = new Date();
+ this.replicationCase = ReplicationType.Validator("none");
+ this.setLastMod();
+ logger.debug( "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.tnxEnabled = tnxEnabled;
+ this.owner = owner;
+ this.init();
+ this.setLastMod();
+ logger.debug( "Topic constructor w args " + this.getLastMod() );
+ }
+
+ public Topic init() {
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+
+ defaultPartitionCount = p.getProperty( "MR.partitionCount", "2");
+ defaultReplicationCount = p.getProperty( "MR.replicationCount", "1");
+
+ this.setStatus( DmaapObject_Status.NEW );
+ this.replicationCase = ReplicationType.Validator("none");
+ this.fqtnStyle = FqtnType.Validator("none");
+ this.setPartitionCount( defaultPartitionCount );
+ this.setReplicationCount( defaultReplicationCount );
+
+ return this;
+ }
+
+ // expects a String in JSON format, with known fields to populate Topic object
+ public Topic ( 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.setFqtn( (String) jsonObj.get( "fqtn" ) );
+ this.setTopicName( (String) jsonObj.get( "topicName" ) );
+ this.setTopicDescription( (String) jsonObj.get( "topicDescription" ));
+ this.setOwner( (String) jsonObj.get( "owner" ) );
+ this.setStatus( (String) jsonObj.get( "status" ) );
+ this.setReplicationCase( ReplicationType.Validator( (String) jsonObj.get( "replicationCase" ) ));
+ this.setFqtnStyle( FqtnType.Validator( (String) jsonObj.get( "fqtnStyle" ) ) );
+ this.setPartitionCount( (String) jsonObj.get("partitionCount"));
+
+ }
+ 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 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 String getPartitionCount() {
+ return partitionCount;
+ }
+ public void setPartitionCount(String partitions) {
+ this.partitionCount = partitions;
+ }
+ public String getReplicationCount() {
+ return replicationCount;
+ }
+ public void setReplicationCount(String replicationCount) {
+ this.replicationCount = replicationCount;
+ }
+
+
+ public void setClients(List<MR_Client> clients) {
+ this.clients = clients;
+ }
+
+ public List<MR_Client> getClients() {
+ return clients;
+ }
+
+ @ApiModelProperty( hidden=true )
+ 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 ReplicationType getReplicationCase() {
+ return replicationCase;
+ }
+
+
+ public void setReplicationCase(ReplicationType t) {
+ this.replicationCase = t;
+ }
+ public FqtnType getFqtnStyle() {
+ return fqtnStyle;
+ }
+
+
+ public void setFqtnStyle(FqtnType t) {
+ this.fqtnStyle = t;
+ }
+
+ public String getGlobalMrURL() {
+ return globalMrURL;
+ }
+
+
+
+ public void setGlobalMrURL(String globalMrURL) {
+ this.globalMrURL = globalMrURL;
+ }
+
+
+
+ public String getVersion() {
+ return version;
+ }
+
+
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+
+
+ public String getPublisherRole() {
+ return publisherRole;
+ }
+ public void setPublisherRole(String publisherRole) {
+ this.publisherRole = publisherRole;
+ }
+ public String getSubscriberRole() {
+ return subscriberRole;
+ }
+ public void setSubscriberRole(String subscriberRole) {
+ this.subscriberRole = subscriberRole;
+ }
+ public String toProvJSON() {
+ StringBuilder str = new StringBuilder();
+ str.append("{ \"topicName\": \"");
+ str.append( this.getFqtn() );
+ str.append( "\", \"topicDescription\": \"");
+ str.append( this.getTopicDescription());
+ str.append( "\", \"partitionCount\": \"");
+ str.append( this.getPartitionCount());
+ str.append( "\", \"replicationCount\": \"");
+ str.append( this.getReplicationCount());
+ str.append( "\" } ");
+
+ logger.info( str.toString() );
+ return str.toString();
+ }
+ @ApiModelProperty( hidden=true )
+ public byte[] getBytes() {
+ return toProvJSON().getBytes(StandardCharsets.UTF_8);
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Topic topic = (Topic) o;
+ return Objects.equal(fqtn, topic.fqtn) &&
+ Objects.equal(topicName, topic.topicName) &&
+ Objects.equal(tnxEnabled, topic.tnxEnabled) &&
+ Objects.equal(owner, topic.owner);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(fqtn, topicName, tnxEnabled, owner);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java
new file mode 100644
index 0000000..d8a7302
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilter.java
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class AAFAuthenticationFilter extends BaseLoggingClass implements Filter{
+
+ static final String CADI_PROPERTIES = "cadi.properties";
+ static final String CADI_AUTHN_FLAG = "enableCADI";
+
+ private boolean isCadiEnabled;
+ private CadiFilter cadiFilter;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ DmaapConfig dmaapConfig = getConfig();
+ String flag = dmaapConfig.getProperty(CADI_AUTHN_FLAG, "false");
+ isCadiEnabled = "true".equalsIgnoreCase(flag);
+ initCadi(dmaapConfig);
+ }
+
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+
+ if(isCadiEnabled) {
+ cadiFilter.doFilter(servletRequest, servletResponse, filterChain);
+ updateResponseBody((HttpServletResponse)servletResponse);
+ } else {
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+ }
+
+ private void updateResponseBody(HttpServletResponse httpResponse)
+ throws IOException {
+ if(httpResponse.getStatus() == 401) {
+ String errorMsg = "invalid or no credentials provided";
+ errorLogger.error(errorMsg);
+ httpResponse.setContentType("application/json");
+ httpResponse.setCharacterEncoding("UTF-8");
+ httpResponse.getWriter().print(buildErrorResponse(errorMsg));
+ httpResponse.getWriter().flush();
+ }
+ }
+
+ private String buildErrorResponse(String msg) {
+ try {
+ return new ObjectMapper().writeValueAsString(new ApiError(HttpStatus.UNAUTHORIZED_401, msg, "Authentication"));
+ } catch (JsonProcessingException e) {
+ logger.warn("Could not serialize response entity: " + e.getMessage());
+ return "";
+ }
+ }
+
+
+ @Override
+ public void destroy() {
+ //nothing to cleanup
+ }
+
+ private void initCadi(DmaapConfig dmaapConfig) throws ServletException {
+ if(isCadiEnabled) {
+ try {
+ String cadiPropertiesFile = dmaapConfig.getProperty(CADI_PROPERTIES);
+ if(cadiPropertiesFile != null && !cadiPropertiesFile.isEmpty()) {
+ cadiFilter = new CadiFilter(loadCadiProperties(cadiPropertiesFile));
+ } else {
+ throw new ServletException("Cannot initialize CADI filter.CADI properties not available.");
+ }
+ } catch (ServletException e) {
+ errorLogger.error("CADI init error :" + e.getMessage());
+ throw e;
+ }
+ }
+ }
+
+ private PropAccess loadCadiProperties(String propertiesFilePath) throws ServletException {
+ try {
+ Properties props = new Properties();
+ props.load(new FileInputStream(propertiesFilePath));
+ return new PropAccess(props);
+ } catch (IOException e) {
+ String msg = "Could not load CADI properties file: " + propertiesFilePath;
+ errorLogger.error(msg, e);
+ throw new ServletException(msg);
+ }
+ }
+
+ DmaapConfig getConfig() {
+ return (DmaapConfig) DmaapConfig.getConfig();
+ }
+
+ //tests only
+ CadiFilter getCadiFilter() {
+ return cadiFilter;
+ }
+
+ void setCadiFilter(CadiFilter cadiFilter) {
+ this.cadiFilter = cadiFilter;
+ }
+
+ boolean isCadiEnabled() {
+ return isCadiEnabled;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java
new file mode 100644
index 0000000..779f71b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilter.java
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.PermissionBuilder;
+
+public class AAFAuthorizationFilter extends BaseLoggingClass implements Filter {
+
+ static final String CADI_AUTHZ_FLAG = "enableCADI";
+ private boolean isCadiEnabled = false;
+
+ private PermissionBuilder permissionBuilder;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ DmaapConfig dmaapConfig = getConfig();
+ isCadiEnabled = "true".equalsIgnoreCase(dmaapConfig.getProperty(CADI_AUTHZ_FLAG, "false"));
+ if(isCadiEnabled) {
+ permissionBuilder = new PermissionBuilder(dmaapConfig, getDmaapService());
+ }
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+
+ if(isCadiEnabled) {
+ HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
+ permissionBuilder.updateDmaapInstance();
+ String permission = permissionBuilder.buildPermission(httpRequest);
+
+ if (httpRequest.isUserInRole(permission)) {
+ logger.info("User " + httpRequest.getUserPrincipal().getName() + " has permission " + permission);
+ filterChain.doFilter(servletRequest, servletResponse);
+ } else {
+ String msg = "User " + httpRequest.getUserPrincipal().getName() + " does not have permission " + permission;
+ errorLogger.error(msg);
+ ((HttpServletResponse) servletResponse).setStatus(HttpStatus.FORBIDDEN_403);
+ servletResponse.setContentType("application/json");
+ servletResponse.setCharacterEncoding("UTF-8");
+ servletResponse.getWriter().print(buildErrorResponse(msg));
+ servletResponse.getWriter().flush();
+ }
+ } else {
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ //nothing to cleanup
+ }
+
+ DmaapConfig getConfig() {
+ return (DmaapConfig) DmaapConfig.getConfig();
+ }
+
+ DmaapService getDmaapService() {
+ return new DmaapService();
+ }
+
+ private String buildErrorResponse(String msg) {
+ try {
+ return new ObjectMapper().writeValueAsString(new ApiError(HttpStatus.FORBIDDEN_403, msg, "Authorization"));
+ } catch (JsonProcessingException e) {
+ logger.warn("Could not serialize response entity: " + e.getMessage());
+ return "";
+ }
+ }
+
+ PermissionBuilder getPermissionBuilder() {
+ return permissionBuilder;
+ }
+
+ void setPermissionBuilder(PermissionBuilder permissionBuilder) {
+ this.permissionBuilder = permissionBuilder;
+ }
+
+ void setCadiEnabled(boolean cadiEnabled) {
+ isCadiEnabled = cadiEnabled;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/Authorization.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/Authorization.java
new file mode 100644
index 0000000..e8b05c6
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/Authorization.java
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+import javax.ws.rs.NameBinding;
+
+// @Authorization annotation
+@NameBinding
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Authorization {
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AuthorizationFilter.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AuthorizationFilter.java
new file mode 100644
index 0000000..32e8845
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/AuthorizationFilter.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+
+import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.service.ApiService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+@Authorization
+public class AuthorizationFilter extends BaseLoggingClass implements ContainerRequestFilter {
+
+ private static final String AAF_CADI_FLAG = "enableCADI";
+ private final ResponseBuilder responseBuilder = new ResponseBuilder();
+ private final boolean isCadiEnabled;
+
+
+ public AuthorizationFilter() {
+ DmaapConfig dmaapConfig = (DmaapConfig) DmaapConfig.getConfig();
+ String flag = dmaapConfig.getProperty(AAF_CADI_FLAG, "false");
+ isCadiEnabled = "true".equalsIgnoreCase(flag);
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) {
+
+ if(!isCadiEnabled) {
+ ApiService apiResp = new ApiService()
+ .setAuth(requestContext.getHeaderString("Authorization"))
+ .setUriPath(requestContext.getUriInfo().getPath())
+ .setHttpMethod(requestContext.getMethod())
+ .setRequestId(requestContext.getHeaderString("X-ECOMP-RequestID"));
+
+ try {
+ apiResp.checkAuthorization();
+ } catch (AuthenticationErrorException ae) {
+ errorLogger.error("Error", ae);
+ requestContext.abortWith(responseBuilder.unauthorized(apiResp.getErr().getMessage()));
+ } catch (Exception e) {
+ errorLogger.error("Error", e);
+ requestContext.abortWith(responseBuilder.unavailable());
+ }
+ }
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/BridgeResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/BridgeResource.java
new file mode 100644
index 0000000..299c48f
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/BridgeResource.java
@@ -0,0 +1,191 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.BrTopic;
+import org.onap.dmaap.dbcapi.model.MirrorMaker;
+import org.onap.dmaap.dbcapi.service.MirrorMakerService;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
+@Path("/bridge")
+@Api( value= "bridge", description = "Endpoint for retreiving MR Bridge metrics" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class BridgeResource extends BaseLoggingClass {
+
+ private MirrorMakerService mmService = new MirrorMakerService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+
+ @GET
+ @ApiOperation( value = "return BrTopic details",
+ notes = "Returns array of `BrTopic` objects. If source and target query params are specified, only report on that bridge. "
+ + "If detail param is true, list topics names, else just a count is returned.",
+ response = BrTopic.class)
+@ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = BrTopic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+})
+ public Response getBridgedTopics(@QueryParam("mmagent") String mmagent,
+ @QueryParam("detail") Boolean detailFlag ){
+
+ if ( mmagent == null ) {
+ return responseBuilder.success(getMMcounts(Boolean.TRUE.equals(detailFlag)));
+
+ }
+ logger.info( "getBridgeTopics():" + " mmagent=" + mmagent);
+
+ if ( ! Boolean.TRUE.equals(detailFlag)) {
+ BrTopic brTopic = new BrTopic();
+
+ // get topics between 2 bridged locations
+
+ MirrorMaker mm = mmService.getMirrorMaker(mmagent);
+ if ( mm == null ) {
+ return responseBuilder.notFound();
+ }
+
+ brTopic.setTopicCount( mm.getTopicCount() );
+ brTopic.setBrSource( mm.getSourceCluster());
+ brTopic.setBrTarget( mm.getTargetCluster());
+ brTopic.setMmAgentName(mm.getMmName());
+
+ logger.info( "topicCount [2 locations]: " + brTopic.getTopicCount() );
+
+ return responseBuilder.success(brTopic);
+ } else {
+ logger.info( "getBridgeTopics() detail:" + " mmagent=" + mmagent);
+ // get topics between 2 bridged locations
+ MirrorMaker mm = mmService.getMirrorMaker(mmagent);
+ if ( mm == null ) {
+ return responseBuilder.notFound();
+ }
+
+ return responseBuilder.success(mm);
+ }
+ }
+
+ private BrTopic[] getMMcounts( Boolean showDetail ) {
+
+ List<String> mmList = mmService.getAllMirrorMakers();
+ int s = 1;
+ if ( showDetail ) {
+ s = mmList.size() + 1;
+ }
+ BrTopic[] brTopic = new BrTopic[s];
+
+ int totCnt = 0;
+ s = 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;
+ if (showDetail && mm!=null) {
+ brTopic[s] = new BrTopic();
+ brTopic[s].setBrSource( mm.getSourceCluster());
+ brTopic[s].setBrTarget(mm.getTargetCluster());
+ brTopic[s].setMmAgentName(mm.getMmName());
+ brTopic[s].setTopicCount(mm.getTopicCount());
+ s++;
+ }
+ }
+
+ logger.info( "topicCount [all locations]: " + totCnt );
+ brTopic[s] = new BrTopic();
+ brTopic[s].setBrSource("all");
+ brTopic[s].setBrTarget("all");
+ brTopic[s].setMmAgentName("n/a");
+ brTopic[s].setTopicCount(totCnt);
+ return brTopic;
+ }
+
+ @PUT
+ @ApiOperation( value = "update MirrorMaker details",
+ notes = "replace the topic list for a specific Bridge. Use JSON Body for value to replace whitelist, "
+ + "but if refreshFlag param is true, simply refresh using existing whitelist."
+ + "If split param is true, spread whitelist over smaller mmagents.",
+ response = MirrorMaker.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = BrTopic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response putBridgedTopics(@QueryParam("mmagent") String mmagent,
+ @QueryParam("refresh") Boolean refreshFlag,
+ @QueryParam("split") Boolean splitFlag,
+ MirrorMaker newBridge ){
+ logger.info( "putBridgeTopics() mmagent:" + mmagent );
+
+ if ( mmagent != null ) { // put topics between 2 bridged locations
+
+ MirrorMaker mm = mmService.getMirrorMaker(mmagent);
+ if ( mm == null ) {
+ return responseBuilder.notFound();
+ }
+
+ if ( splitFlag != null && splitFlag == true ) {
+ mm = mmService.splitMM( mm );
+ } else if ( refreshFlag == null || refreshFlag == false ) {
+ logger.info( "setting whitelist from message body containing mmName=" + newBridge.getMmName());
+ if ( ! mmagent.equals(newBridge.getMmName()) ){
+ logger.error( "mmagent query param does not match mmName in body");
+ return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+ "mmagent query param does not match mmName in body"));
+ }
+ mm.setTopics( newBridge.getTopics() );
+ } else {
+ logger.info( "refreshing whitelist from memory");
+ }
+ mmService.updateMirrorMaker(mm);
+ return responseBuilder.success(mm);
+ }
+
+ else {
+ logger.error( "mmagent is required for PUT");
+ return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(), "mmagent is required for PUT"));
+ }
+
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_NodeResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_NodeResource.java
new file mode 100644
index 0000000..f001136
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_NodeResource.java
@@ -0,0 +1,172 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcae
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Node;
+import org.onap.dmaap.dbcapi.service.DR_NodeService;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
+@Path("/dr_nodes")
+@Api( value= "dr_nodes", description = "Endpoint for a Data Router Node server" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class DR_NodeResource extends BaseLoggingClass {
+
+ private DR_NodeService dr_nodeService = new DR_NodeService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return DR_Node details",
+ notes = "Returns array of `DR_Node` object array. Need to add filter by dcaeLocation.",
+ response = DR_Node.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Node.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getDr_Nodes() {
+ List<DR_Node> nodes = dr_nodeService.getAllDr_Nodes();
+
+ GenericEntity<List<DR_Node>> list = new GenericEntity<List<DR_Node>>(nodes) {
+ };
+ return responseBuilder.success(list);
+ }
+
+ @POST
+ @ApiOperation( value = "return DR_Node details",
+ notes = "create a `DR_Node` in a *dcaeLocation*. Note that multiple `DR_Node`s may exist in the same `dcaeLocation`.",
+ response = DR_Node.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Node.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addDr_Node(DR_Node node) {
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "dcaeLocation", node.getDcaeLocationName());
+ checker.required( "fqdn", node.getFqdn());
+ } catch ( RequiredFieldException rfe ) {
+ return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+ "missing required field", "dcaeLocation, fqdn"));
+ }
+ DR_Node nNode = dr_nodeService.addDr_Node(node, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(nNode);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @PUT
+ @ApiOperation( value = "return DR_Node details",
+ notes = "Update a single `DR_Node` object.",
+ response = DR_Node.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Node.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{fqdn}")
+ public Response updateDr_Node(@PathParam("fqdn") String name, DR_Node node) {
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "dcaeLocation", node.getDcaeLocationName());
+ checker.required( "fqdn", node.getFqdn());
+ } catch ( RequiredFieldException rfe ) {
+ return responseBuilder.error(new ApiError(BAD_REQUEST.getStatusCode(),
+ "missing required field", "dcaeLocation, fqdn"));
+ }
+ node.setFqdn(name);
+ DR_Node nNode = dr_nodeService.updateDr_Node(node, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(nNode);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @DELETE
+ @ApiOperation( value = "No Content",
+ notes = "Delete a single `DR_Node` object.",
+ response = DR_Node.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = DR_Node.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{fqdn}")
+ public Response deleteDr_Node(
+ @PathParam("fqdn") String name){
+
+
+ ApiError apiError = new ApiError();
+
+ dr_nodeService.removeDr_Node(name, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @GET
+ @ApiOperation( value = "return DR_Node details",
+ notes = "Retrieve a single `DR_Node` object.",
+ response = DR_Node.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Node.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{fqdn}")
+ public Response get(@PathParam("fqdn") String name) {
+
+ ApiError apiError = new ApiError();
+
+ DR_Node nNode = dr_nodeService.getDr_Node( name, apiError );
+ if (apiError.is2xx()) {
+ return responseBuilder.success(nNode);
+ }
+ return responseBuilder.error(apiError);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_PubResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_PubResource.java
new file mode 100644
index 0000000..f512124
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_PubResource.java
@@ -0,0 +1,252 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+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.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.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.service.DR_PubService;
+import org.onap.dmaap.dbcapi.service.FeedService;
+
+
+@Path("/dr_pubs")
+@Api( value= "dr_pubs", description = "Endpoint for a Data Router client that implements a Publisher" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class DR_PubResource extends BaseLoggingClass {
+
+ private DR_PubService dr_pubService = new DR_PubService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return DR_Pub details",
+ notes = "Returns array of `DR_Pub` objects. Add filter for feedId.",
+ response = DR_Pub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getDr_Pubs() {
+ logger.info( "Entry: GET /dr_pubs");
+ List<DR_Pub> pubs = dr_pubService.getAllDr_Pubs();
+
+ GenericEntity<List<DR_Pub>> list = new GenericEntity<List<DR_Pub>>(pubs) {
+ };
+ return responseBuilder.success(list);
+ }
+
+
+ @POST
+ @ApiOperation( value = "return DR_Pub details",
+ notes = "create a DR Publisher in the specified environment.",
+ response = DR_Pub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addDr_Pub(DR_Pub pub) {
+ ApiError apiError = new ApiError();
+ FeedService feeds = new FeedService();
+ Feed fnew = null;
+
+ logger.info( "Entry: POST /dr_pubs");
+
+ try {
+ checker.required( "feedId", pub.getFeedId());
+ } catch ( RequiredFieldException rfe ) {
+ try {
+ checker.required( "feedName", pub.getFeedName());
+ }catch ( RequiredFieldException rfe2 ) {
+ logger.debug( rfe2.getApiError().toString() );
+ return responseBuilder.error(rfe2.getApiError());
+ }
+ // if we found a FeedName instead of a FeedId then try to look it up.
+ List<Feed> nfeeds = feeds.getAllFeeds( pub.getFeedName(), pub.getFeedVersion(), "equals");
+ if ( nfeeds.isEmpty() ) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ apiError.setFields("feedName");
+ return responseBuilder.error(apiError);
+ }
+ fnew = nfeeds.get(0);
+ }
+ try {
+ checker.required( "dcaeLocationName", pub.getDcaeLocationName());
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+
+ // we may have fnew already if located by FeedName
+ if ( fnew == null ) {
+ fnew = feeds.getFeed(pub.getFeedId(), apiError);
+ }
+ if ( fnew == null ) {
+ logger.info( "Specified feed " + pub.getFeedId() + " or " + pub.getFeedName() + " not known to Bus Controller");
+ return responseBuilder.error(apiError);
+ }
+
+ ArrayList<DR_Pub> pubs = fnew.getPubs();
+ logger.info( "num existing pubs before = " + pubs.size() );
+
+ 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, apiError);
+
+ if (!apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+ pubs = fnew.getPubs();
+ logger.info( "num existing pubs after = " + pubs.size() );
+
+ DR_Pub pnew = dr_pubService.getDr_Pub(pub.getPubId(), apiError);
+ return responseBuilder.success(Status.CREATED.getStatusCode(), pnew);
+ }
+
+ @PUT
+ @ApiOperation( value = "return DR_Pub details",
+ notes = "update a DR Publisher in the specified environment. Update a `DR_Pub` object by pubId",
+ response = DR_Pub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{pubId}")
+ public Response updateDr_Pub(@PathParam("pubId") String name, DR_Pub pub) {
+ logger.info( "Entry: PUT /dr_pubs");
+ pub.setPubId(name);
+ DR_Pub res = dr_pubService.updateDr_Pub(pub);
+ return responseBuilder.success(res);
+ }
+
+ @DELETE
+ @ApiOperation( value = "return DR_Pub details",
+ notes = "delete a DR Publisher in the specified environment. Delete a `DR_Pub` object by pubId",
+ response = DR_Pub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{pubId}")
+ public Response deleteDr_Pub(@PathParam("pubId") String id){
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "pubId", id);
+ } catch ( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ DR_Pub pub = dr_pubService.getDr_Pub(id, apiError);
+ if ( !apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+ FeedService feeds = new FeedService();
+ Feed fnew = feeds.getFeed(pub.getFeedId(), apiError);
+ if ( fnew == null ) {
+ logger.info( "Specified feed " + pub.getFeedId() + " not known to Bus Controller");
+ return responseBuilder.error(apiError);
+ }
+ ArrayList<DR_Pub> pubs = fnew.getPubs();
+ if ( pubs.size() == 1 ) {
+ apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+ apiError.setMessage( "Can't delete the last publisher of a feed");
+ return responseBuilder.error(apiError);
+ }
+
+ for( Iterator<DR_Pub> i = pubs.iterator(); i.hasNext(); ) {
+ DR_Pub listItem = i.next();
+ if ( listItem.getPubId().equals(id)) {
+ i.remove();
+ }
+ }
+ fnew.setPubs(pubs);
+ fnew = feeds.updateFeed(fnew,apiError);
+ if (!apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+
+ dr_pubService.removeDr_Pub(id, apiError);
+ if (!apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+ return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
+ }
+
+ @GET
+ @ApiOperation( value = "return DR_Pub details",
+ notes = "returns a DR Publisher in the specified environment. Gets a `DR_Pub` object by pubId",
+ response = DR_Pub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{pubId}")
+ public Response get(@PathParam("pubId") String id) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "feedId", id);
+ } catch ( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ DR_Pub pub = dr_pubService.getDr_Pub(id, apiError);
+ if (!apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+ return responseBuilder.success(Status.OK.getStatusCode(), pub);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_SubResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_SubResource.java
new file mode 100644
index 0000000..2fa6ccd
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DR_SubResource.java
@@ -0,0 +1,243 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import com.google.common.collect.Iterables;
+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.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.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.service.DR_SubService;
+import org.onap.dmaap.dbcapi.service.FeedService;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import static javax.ws.rs.core.Response.Status.CREATED;
+
+
+@Path("/dr_subs")
+@Api( value= "dr_subs", description = "Endpoint for a Data Router client that implements a Subscriber" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class DR_SubResource extends BaseLoggingClass {
+
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return DR_Sub details",
+ notes = "Returns array of `DR_Sub` objects. Add filter for feedId.",
+ response = DR_Sub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getDr_Subs() {
+ DR_SubService dr_subService = new DR_SubService();
+ List<DR_Sub> subs = dr_subService.getAllDr_Subs();
+
+ GenericEntity<List<DR_Sub>> list = new GenericEntity<List<DR_Sub>>(subs) {
+ };
+ return responseBuilder.success(list);
+ }
+
+ @POST
+ @ApiOperation( value = "return DR_Sub details",
+ notes = "Create a `DR_Sub` object. ",
+ response = DR_Sub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addDr_Sub(DR_Sub sub) {
+
+ ApiError apiError = new ApiError();
+ FeedService feeds = new FeedService();
+ Feed fnew = null;
+ try {
+ checker.required( "feedId", sub.getFeedId());
+ } catch ( RequiredFieldException rfe ) {
+ try {
+ checker.required( "feedName", sub.getFeedName());
+ }catch ( RequiredFieldException rfe2 ) {
+ logger.debug( rfe2.getApiError().toString() );
+ return responseBuilder.error(rfe2.getApiError());
+ }
+ // if we found a FeedName instead of a FeedId then try to look it up.
+ List<Feed> nfeeds = feeds.getAllFeeds( sub.getFeedName(), sub.getFeedVersion(), "equals");
+ if ( nfeeds.isEmpty() ) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ apiError.setFields("feedName");
+ return responseBuilder.error(apiError);
+ } else if (nfeeds.size() > 1) {
+ logger.debug( "Attempt to match "+ sub.getFeedName() + " ver="+sub.getFeedVersion() + " matched " + nfeeds.size() );
+ apiError.setCode(Status.CONFLICT.getStatusCode());
+ apiError.setFields("feedName");
+ return responseBuilder.error(apiError);
+ }
+ fnew = Iterables.getOnlyElement(nfeeds);
+ }
+
+ try {
+ checker.required( "dcaeLocationName", sub.getDcaeLocationName());
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ // we may have fnew already if located by FeedName
+ if ( fnew == null ) {
+ fnew = feeds.getFeed( sub.getFeedId(), apiError);
+ }
+ if ( fnew == null ) {
+ logger.warn( "Specified feed " + sub.getFeedId() + " or " + sub.getFeedName() + " not known to Bus Controller");
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ return responseBuilder.error(apiError);
+ }
+ DR_SubService dr_subService = new DR_SubService( fnew.getSubscribeURL());
+ ArrayList<DR_Sub> subs = fnew.getSubs();
+ logger.info( "num existing subs before = " + subs.size() );
+ DR_Sub snew = dr_subService.addDr_Sub(sub, apiError);
+ if (!apiError.is2xx()) {
+ return responseBuilder.error(apiError);
+ }
+ subs.add( snew );
+ logger.info( "num existing subs after = " + subs.size() );
+
+ fnew.setSubs(subs);
+ logger.info( "update feed");
+ return responseBuilder.success(CREATED.getStatusCode(), snew);
+
+ }
+
+ @PUT
+ @ApiOperation( value = "return DR_Sub details",
+ notes = "Update a `DR_Sub` object, selected by subId",
+ response = DR_Sub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{subId}")
+ public Response updateDr_Sub(@PathParam("subId") String name, DR_Sub sub) {
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "subId", name);
+ checker.required( "feedId", sub.getFeedId());
+ checker.required( "dcaeLocationName", sub.getDcaeLocationName());
+
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ FeedService feeds = new FeedService();
+ Feed fnew = feeds.getFeed(sub.getFeedId(), apiError);
+ if ( fnew == null ) {
+ logger.warn( "Specified feed " + sub.getFeedId() + " not known to Bus Controller");
+ return responseBuilder.error(apiError);
+ }
+
+ DR_SubService dr_subService = new DR_SubService();
+ sub.setSubId(name);
+ DR_Sub nsub = dr_subService.updateDr_Sub(sub, apiError);
+ if ( nsub != null && nsub.isStatusValid() ) {
+ return responseBuilder.success(nsub);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @DELETE
+ @ApiOperation( value = "return DR_Sub details",
+ notes = "Delete a `DR_Sub` object, selected by subId",
+ response = DR_Sub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{subId}")
+ public Response deleteDr_Sub(@PathParam("subId") String id){
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "subId", id);
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ DR_SubService dr_subService = new DR_SubService();
+ dr_subService.removeDr_Sub(id, apiError);
+ if (!apiError.is2xx() ) {
+ return responseBuilder.error(apiError);
+ }
+ return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null );
+ }
+
+ @GET
+ @ApiOperation( value = "return DR_Sub details",
+ notes = "Retrieve a `DR_Sub` object, selected by subId",
+ response = DR_Sub.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Sub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{subId}")
+ public Response get(@PathParam("subId") String id) {
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "subId", id);
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ DR_SubService dr_subService = new DR_SubService();
+ DR_Sub sub = dr_subService.getDr_Sub(id, apiError);
+ if ( sub != null && sub.isStatusValid() ) {
+ return responseBuilder.success(sub);
+ }
+ return responseBuilder.error(apiError);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResource.java
new file mode 100644
index 0000000..89c9b49
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResource.java
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.service.DcaeLocationService;
+
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
+
+@Path("/dcaeLocations")
+@Api( value= "dcaeLocations", description = "an OpenStack tenant purposed for OpenDCAE (i.e. where OpenDCAE components might be deployed)" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class DcaeLocationResource extends BaseLoggingClass {
+ private DcaeLocationService locationService = new DcaeLocationService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+
+ @GET
+ @ApiOperation( value = "return dcaeLocation details",
+ notes = "Returns array of `dcaeLocation` objects. All objects managed by DMaaP are deployed in some `dcaeLocation` which is a unique identifier for an *OpenStack* tenant purposed for a *dcaeLayer* (ecomp or edge).",
+ response = DcaeLocation.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DcaeLocation.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getDcaeLocations() {
+ List<DcaeLocation> locs = locationService.getAllDcaeLocations();
+
+ GenericEntity<List<DcaeLocation>> list = new GenericEntity<List<DcaeLocation>>(locs) {};
+ return responseBuilder.success(list);
+ }
+
+ @POST
+ @ApiOperation( value = "return dcaeLocation details",
+ notes = "Create some `dcaeLocation` which is a unique identifier for an *OpenStack* tenant purposed for a *dcaeLayer* (ecomp or edge).",
+ response = DcaeLocation.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DcaeLocation.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addDcaeLocation(DcaeLocation location) {
+
+ if ( locationService.getDcaeLocation(location.getDcaeLocationName()) != null ) {
+ return responseBuilder.error(new ApiError(Status.CONFLICT.getStatusCode(),
+ "dcaeLocation already exists", "dcaeLocation"));
+ }
+ DcaeLocation loc = locationService.addDcaeLocation(location);
+ return responseBuilder.success(Status.CREATED.getStatusCode(), loc);
+ }
+
+ @PUT
+ @ApiOperation( value = "return dcaeLocation details",
+ notes = "update the openStackAvailabilityZone of a dcaeLocation",
+ response = DcaeLocation.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DcaeLocation.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{locationName}")
+ public Response updateDcaeLocation(
+ @PathParam("locationName") String name, DcaeLocation location) {
+
+ location.setDcaeLocationName(name);
+ if ( locationService.getDcaeLocation(location.getDcaeLocationName()) == null ) {
+ return responseBuilder.notFound();
+
+ }
+ DcaeLocation loc = locationService.updateDcaeLocation(location);
+ return responseBuilder.success(Status.CREATED.getStatusCode(), loc );
+ }
+
+ @DELETE
+ @ApiOperation( value = "return dcaeLocation details", notes = "delete a dcaeLocation", response = DcaeLocation.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = DcaeLocation.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{locationName}")
+ public Response deleteDcaeLocation(
+ @PathParam("locationName") String name
+ ){
+ locationService.removeDcaeLocation(name);
+ return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
+ }
+
+ @GET
+ @ApiOperation( value = "return dcaeLocation details", notes = "Returns a specific `dcaeLocation` object with specified tag", response = DcaeLocation.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DcaeLocation.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{locationName}")
+ public Response getDcaeLocation(
+ @PathParam("locationName") String name) {
+
+ DcaeLocation loc = locationService.getDcaeLocation( name );
+ if ( loc == null ) {
+ ApiError err = new ApiError();
+
+ err.setCode(NOT_FOUND.getStatusCode());
+ err.setMessage("dcaeLocation does not exist");
+ err.setFields("dcaeLocation");
+
+ return responseBuilder.error(err);
+ }
+
+ return responseBuilder.success(loc);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DmaapResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DmaapResource.java
new file mode 100644
index 0000000..955cab7
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/DmaapResource.java
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+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;
+
+
+@Path("/dmaap")
+@Api( value= "dmaap", description = "Endpoint for this instance of DMaaP object containing values for this OpenDCAE deployment" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class DmaapResource extends BaseLoggingClass {
+
+
+ private DmaapService dmaapService = new DmaapService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return dmaap details", notes = "returns the `dmaap` object, which contains system wide configuration settings", response = Dmaap.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Dmaap.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+
+ public Response getDmaap(@Context UriInfo uriInfo) {
+ Dmaap d = dmaapService.getDmaap();
+ return responseBuilder.success(d);
+ }
+
+ @POST
+ @ApiOperation( value = "return dmaap details", notes = "Create a new DMaaP set system wide configuration settings for the *dcaeEnvironment*. Deprecated with introduction of persistence in 1610.", response = Dmaap.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Dmaap.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addDmaap( Dmaap obj ) {
+
+ try {
+ validateRequiredFields(obj);
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ Dmaap d = dmaapService.addDmaap(obj);
+ if ( d == null ) {
+ return responseBuilder.notFound();
+
+ }
+
+ return responseBuilder.success(d);
+ }
+
+ @PUT
+ @ApiOperation( value = "return dmaap details", notes = "Update system settings for *dcaeEnvironment*.", response = Dmaap.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Dmaap.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response updateDmaap( Dmaap obj ) {
+
+ try {
+ validateRequiredFields(obj);
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ Dmaap d = dmaapService.updateDmaap(obj);
+ if ( d != null ) {
+ return responseBuilder.success(d);
+ } else {
+ return responseBuilder.notFound();
+ }
+ }
+
+ private void validateRequiredFields(Dmaap obj) throws RequiredFieldException {
+ checker.required( "dmaapName", obj.getDmaapName(), "^\\S+$" ); //no white space allowed in dmaapName
+ checker.required( "dmaapProvUrl", obj.getDrProvUrl());
+ checker.required( "topicNsRoot", obj.getTopicNsRoot());
+ checker.required( "bridgeAdminTopic", obj.getBridgeAdminTopic());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java
new file mode 100644
index 0000000..28bdb00
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java
@@ -0,0 +1,259 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.service.FeedService;
+
+
+@Path("/feeds")
+@Api( value= "Feeds", description = "Endpoint for a Data Router Feed" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class FeedResource extends BaseLoggingClass {
+
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return Feed details",
+ notes = "Returns array of `Feed` objects.",
+ response = Feed.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Feed.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getFeeds(
+ @QueryParam("feedName") String feedName,
+ @QueryParam("version") String version,
+ @QueryParam("match") String match) {
+
+ FeedService feedService = new FeedService();
+ List<Feed> nfeeds = feedService.getAllFeeds( feedName, version, match );
+ GenericEntity<List<Feed>> list = new GenericEntity<List<Feed>>(nfeeds) {
+ };
+ return responseBuilder.success(list);
+ }
+
+
+
+ @POST
+ @ApiOperation( value = "return Feed details",
+ notes = "Create a of `Feed` object.",
+ response = Feed.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Feed.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addFeed(
+ Feed feed,
+ @QueryParam("useExisting") String useExisting) {
+
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "feedName", feed.getFeedName());
+ checker.required( "feedVersion", feed.getFeedVersion());
+ checker.required( "owner", feed.getOwner());
+ checker.required( "asprClassification", feed.getAsprClassification());
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+
+ FeedService feedService = new FeedService();
+ Feed nfeed = feedService.getFeedByName( feed.getFeedName(), feed.getFeedVersion(), apiError);
+ if ( nfeed == null ) {
+ nfeed = feedService.addFeed(feed, apiError);
+ if ( nfeed != null ) {
+ return responseBuilder.success(nfeed);
+ } else {
+ logger.error( "Unable to create: " + feed.getFeedName() + ":" + feed.getFeedVersion());
+
+ return responseBuilder.error(apiError);
+ }
+ } else if ( nfeed.getStatus() == DmaapObject_Status.DELETED ) {
+ feed.setFeedId( nfeed.getFeedId());
+ nfeed = feedService.updateFeed(feed, apiError);
+ if ( nfeed != null ) {
+ return responseBuilder.success(nfeed);
+ } else {
+ logger.info( "Unable to update: " + feed.getFeedName() + ":" + feed.getFeedVersion());
+
+ return responseBuilder.error(apiError);
+ }
+ } else if ( (useExisting != null) && ("true".compareToIgnoreCase( useExisting ) == 0)) {
+ return responseBuilder.success(nfeed);
+ }
+
+ apiError.setCode(Status.CONFLICT.getStatusCode());
+ return responseBuilder.error(apiError);
+ }
+
+ @PUT
+ @ApiOperation( value = "return Feed details",
+ notes = "Update a `Feed` object, specified by id.",
+ response = Feed.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Feed.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{id}")
+ public Response updateFeed(
+ @PathParam("id") String id,
+ Feed feed) {
+
+ FeedService feedService = new FeedService();
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "feedId", id);
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ Feed nfeed = feedService.getFeed(id, apiError);
+ if ( nfeed == null || nfeed.getStatus() == DmaapObject_Status.DELETED ) {
+ return responseBuilder.notFound();
+ }
+
+ // 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, apiError);
+ if ( nfeed != null ) {
+ return responseBuilder.success(nfeed);
+ } else {
+ logger.info( "Unable to update: " + feed.getFeedName() + ":" + feed.getFeedVersion());
+
+ return responseBuilder.error(apiError);
+ }
+ }
+
+ @DELETE
+ @ApiOperation( value = "return Feed details",
+ notes = "Delete a `Feed` object, specified by id.",
+ response = Feed.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = Feed.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{id}")
+ public Response deleteFeed(@PathParam("id") String id){
+ ApiError apiError = new ApiError();
+
+ logger.debug( "Entry: DELETE " + id);
+ FeedService feedService = new FeedService();
+ Feed nfeed = feedService.getFeed(id, apiError);
+ if ( nfeed == null ) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ return responseBuilder.error(apiError);
+ }
+ nfeed = feedService.removeFeed(nfeed, apiError);
+ if ( nfeed == null || nfeed.getStatus() == DmaapObject_Status.DELETED ) {
+ return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
+ }
+ logger.info( "Unable to delete: " + id + ":" + nfeed.getFeedVersion());
+
+ return responseBuilder.error(apiError);
+ }
+
+ @GET
+ @ApiOperation( value = "return Feed details",
+ notes = "Retrieve a `Feed` object, specified by id.",
+ response = Feed.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = DR_Pub.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{id}")
+ public Response getFeed(@PathParam("id") String id) {
+ ApiError apiError = new ApiError();
+
+ FeedService feedService = new FeedService();
+ Feed nfeed = feedService.getFeed(id, apiError);
+ if ( nfeed == null ) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ return responseBuilder.error(apiError);
+ }
+ return responseBuilder.success(nfeed);
+ }
+
+ @PUT
+ @ApiOperation( value = "sync feeds to existing DR",
+ notes = "When Bus Controller is deployed after DR, then it is possible"
+ + "that DR has previous provisioning data that needs to be imported"
+ + "into Bus Controller.",
+ response = Feed.class )
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Feed.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path( "/sync")
+ public Response syncFeeds (@QueryParam("hard") String hardParam) {
+ ApiError error = new ApiError();
+
+ FeedService feedService = new FeedService();
+ boolean hard = false;
+ if ( hardParam != null && hardParam.equalsIgnoreCase("true")) {
+ hard = true;
+ }
+ feedService.sync( hard, error );
+ if ( error.is2xx()) {
+ List<Feed> nfeeds = feedService.getAllFeeds();
+ GenericEntity<List<Feed>> list = new GenericEntity<List<Feed>>(nfeeds) {
+ };
+ return responseBuilder.success(list);
+ }
+ return responseBuilder.error(error);
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/InfoResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/InfoResource.java
new file mode 100644
index 0000000..bcb7ed2
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/InfoResource.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+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 org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+
+
+
+@Path("/info")
+@Api( value= "info", description = "Endpoint for this instance of DBCL. Returns health info." )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class InfoResource extends BaseLoggingClass {
+
+
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+
+ @GET
+ @ApiOperation( value = "return info details", notes = "returns the `info` object", response = Dmaap.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Dmaap.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+
+ public Response getInfo(@Context UriInfo uriInfo) {
+ return responseBuilder.success(204, null);
+ }
+
+
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClientResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClientResource.java
new file mode 100644
index 0000000..80ee0a6
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClientResource.java
@@ -0,0 +1,208 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.service.MR_ClientService;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+import org.onap.dmaap.dbcapi.service.TopicService;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.util.List;
+
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+
+
+@Path("/mr_clients")
+@Api( value= "MR_Clients", description = "Endpoint for a Message Router Client that implements a Publisher or a Subscriber" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class MR_ClientResource extends BaseLoggingClass {
+
+ private MR_ClientService mr_clientService = new MR_ClientService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return MR_Client details",
+ notes = "Returns array of `MR_Client` objects.",
+ response = MR_Client.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Client.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getMr_Clients() {
+ List<MR_Client> clients = mr_clientService.getAllMr_Clients();
+
+ GenericEntity<List<MR_Client>> list = new GenericEntity<List<MR_Client>>(clients) {
+ };
+ return responseBuilder.success(list);
+ }
+
+ @POST
+ @ApiOperation( value = "Associate an MR_Client object to a Topic",
+ notes = "Create a `MR_Client` object."
+ + "The `dcaeLocation` attribute is used to match an `MR_Cluster` object with the same value, with the intent of localizing message traffic."
+ + " In legacy implementation, the `clientRole` is granted appropriate permission in AAF."
+ + " Newer implementions may instead specify an AAF Identity, which will be added to the appropriate `Topic` role.",
+ response = MR_Client.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Client.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addMr_Client(MR_Client client) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "fqtn", client.getFqtn());
+ checker.required( "dcaeLocationName", client.getDcaeLocationName());
+ String s = client.getClientRole();
+ if ( s == null ) {
+ s = client.getClientIdentity();
+ }
+ checker.required( "clientRole or clientIdentity", s);
+ checker.required( "action", client.getAction());
+
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ MR_ClusterService clusters = new MR_ClusterService();
+
+ MR_Cluster cluster = clusters.getMr_Cluster(client.getDcaeLocationName(), apiError);
+ if ( cluster == null ) {
+
+ apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+ apiError.setMessage( "MR_Cluster alias not found for dcaeLocation: " + client.getDcaeLocationName());
+ apiError.setFields("dcaeLocationName");
+ logger.warn(apiError.toString());
+ return responseBuilder.error(apiError);
+ }
+
+ TopicService topics = new TopicService();
+
+ Topic t = topics.getTopic(client.getFqtn(), apiError);
+ if ( t == null ) {
+ return responseBuilder.error(apiError);
+ }
+ MR_Client nClient = mr_clientService.addMr_Client(client, t, apiError);
+ if (apiError.is2xx()) {
+ t = topics.getTopic(client.getFqtn(), apiError);
+ topics.checkForBridge(t, apiError);
+ return responseBuilder.success(nClient);
+ }
+ else {
+ return responseBuilder.error(apiError);
+ }
+ }
+
+ @PUT
+ @ApiOperation( value = "Update an MR_Client object",
+ notes = "Update a `MR_Client` object, specified by clientId",
+ response = MR_Client.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Client.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{clientId}")
+ public Response updateMr_Client(@PathParam("clientId") String clientId, MR_Client client) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "fqtn", client.getFqtn());
+ checker.required( "dcaeLocationName", client.getDcaeLocationName());
+ checker.required( "clientRole", client.getClientRole());
+ checker.required( "action", client.getAction());
+
+ } catch ( RequiredFieldException rfe ) {
+ logger.debug( rfe.getApiError().toString() );
+ return responseBuilder.error(rfe.getApiError());
+ }
+ client.setMrClientId(clientId);
+ MR_Client nClient = mr_clientService.updateMr_Client(client, apiError);
+ if (apiError.is2xx()) {
+ return Response.ok(nClient)
+ .build();
+ }
+ return Response.status(apiError.getCode())
+ .entity(apiError)
+ .build();
+ }
+
+ @DELETE
+ @ApiOperation( value = "Delete an MR_Client object",
+ notes = "Delete a `MR_Client` object, specified by clientId",
+ response = MR_Client.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = MR_Client.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{subId}")
+ public Response deleteMr_Client(@PathParam("subId") String id){
+ ApiError apiError = new ApiError();
+
+ mr_clientService.removeMr_Client(id, true, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(NO_CONTENT.getStatusCode(), null);
+ }
+
+ return responseBuilder.error(apiError);
+ }
+
+ @GET
+ @ApiOperation( value = "return MR_Client details",
+ notes = "Retrieve a `MR_Client` object, specified by clientId",
+ response = MR_Client.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Client.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{subId}")
+ public Response getMr_Client(@PathParam("subId") String id) {
+ ApiError apiError = new ApiError();
+
+ MR_Client nClient = mr_clientService.getMr_Client(id, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(nClient);
+ }
+ return responseBuilder.error(apiError);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResource.java
new file mode 100644
index 0000000..0a361ff
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResource.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+
+
+@Path("/mr_clusters")
+@Api( value= "MR_Clusters", description = "Endpoint for a Message Router servers in a Cluster configuration" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class MR_ClusterResource extends BaseLoggingClass {
+
+ private MR_ClusterService mr_clusterService = new MR_ClusterService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+
+ @GET
+ @ApiOperation( value = "return MR_Cluster details",
+ notes = "Returns array of `MR_Cluster` objects.",
+ response = MR_Cluster.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Cluster.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getMr_Clusters() {
+ List<MR_Cluster> clusters = mr_clusterService.getAllMr_Clusters();
+
+ GenericEntity<List<MR_Cluster>> list = new GenericEntity<List<MR_Cluster>>(clusters) {
+ };
+ return responseBuilder.success(list);
+ }
+
+ @POST
+ @ApiOperation( value = "return MR_Cluster details",
+ notes = "Create an `MR_Cluster` object.",
+ response = MR_Cluster.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Cluster.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addMr_Cluster(MR_Cluster cluster) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "dcaeLocationName", cluster.getDcaeLocationName());
+ checker.required( "fqdn", cluster.getFqdn());
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+ MR_Cluster mrc = mr_clusterService.addMr_Cluster(cluster, apiError);
+ if ( mrc != null && mrc.isStatusValid() ) {
+ return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
+ }
+ return responseBuilder.error(apiError);
+
+ }
+
+ @PUT
+ @ApiOperation( value = "return MR_Cluster details",
+ notes = "Update an `MR_Cluster` object, specified by clusterId.",
+ response = MR_Cluster.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Cluster.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{clusterId}")
+ public Response updateMr_Cluster(@PathParam("clusterId") String clusterId, MR_Cluster cluster) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "fqdn", clusterId);
+ checker.required( "dcaeLocationName", cluster.getDcaeLocationName());
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+ cluster.setDcaeLocationName(clusterId);
+ MR_Cluster mrc = mr_clusterService.updateMr_Cluster(cluster, apiError);
+ if ( mrc != null && mrc.isStatusValid() ) {
+ return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @DELETE
+ @ApiOperation( value = "return MR_Cluster details",
+ notes = "Delete an `MR_Cluster` object, specified by clusterId.",
+ response = MR_Cluster.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = MR_Cluster.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{clusterId}")
+ public Response deleteMr_Cluster(@PathParam("clusterId") String id){
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "fqdn", id);
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+ mr_clusterService.removeMr_Cluster(id, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @GET
+ @ApiOperation( value = "return MR_Cluster details",
+ notes = "Retrieve an `MR_Cluster` object, specified by clusterId.",
+ response = MR_Cluster.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = MR_Cluster.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{clusterId}")
+ public Response getMR_Cluster(@PathParam("clusterId") String id) {
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "dcaeLocationName", id);
+ } catch( RequiredFieldException rfe ) {
+ return responseBuilder.error(rfe.getApiError());
+ }
+ MR_Cluster mrc = mr_clusterService.getMr_Cluster(id, apiError);
+ if ( mrc != null && mrc.isStatusValid() ) {
+ return responseBuilder.success(Status.CREATED.getStatusCode(), mrc);
+ }
+ return responseBuilder.error(apiError);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java
new file mode 100644
index 0000000..b2b98b6
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilter.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import com.att.eelf.configuration.EELFLogger;
+import java.time.Clock;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public class RequestTimeLogFilter extends BaseLoggingClass implements ContainerRequestFilter, ContainerResponseFilter {
+
+ private final EELFLogger log;
+ private Clock clock;
+
+ public RequestTimeLogFilter() {
+ this(auditLogger, Clock.systemDefaultZone());
+ }
+
+ RequestTimeLogFilter(EELFLogger logger, Clock clock) {
+ this.log = logger;
+ this.clock = clock;
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) {
+ requestContext.setProperty("start", clock.millis());
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext containerResponseContext) {
+ long startTime = (long) requestContext.getProperty("start");
+ long elapsedTime = clock.millis() - startTime;
+ log.info("Request took {} ms", elapsedTime);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java
new file mode 100644
index 0000000..52646aa
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredChecker.java
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA 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.onap.dmaap.dbcapi.resources;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+public class RequiredChecker {
+
+ public void required(String name, Object val) throws RequiredFieldException {
+ if (val == null) {
+ throw new RequiredFieldException(new ApiError(BAD_REQUEST.getStatusCode(),
+ "missing required field", name));
+ }
+ }
+
+ public void required(String name, String val, String expr) throws RequiredFieldException {
+
+ required(name, val);
+
+ if (expr != null && !expr.isEmpty()) {
+ Pattern pattern = Pattern.compile(expr);
+ Matcher matcher = pattern.matcher(val);
+ if (!matcher.find()) {
+ throw new RequiredFieldException(new ApiError(BAD_REQUEST.getStatusCode(),
+ "value '" + val + "' violates regexp check '" + expr + "'", name));
+ }
+ }
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredFieldException.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredFieldException.java
new file mode 100644
index 0000000..2968d18
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/RequiredFieldException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+public class RequiredFieldException extends Exception {
+
+ private static final long serialVersionUID = 2L;
+
+ private final ApiError apiError;
+
+ public RequiredFieldException(ApiError apiError) {
+ super();
+ this.apiError = apiError;
+ }
+
+ public ApiError getApiError() {
+ return apiError;
+ }
+
+ @Override
+ public String toString() {
+ return "RequiredFieldException{" +
+ "apiError=" + apiError +
+ '}';
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java
new file mode 100644
index 0000000..044e7c4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/ResponseBuilder.java
@@ -0,0 +1,84 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA 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.onap.dmaap.dbcapi.resources;
+
+import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_CODE;
+import static com.att.eelf.configuration.Configuration.MDC_RESPONSE_DESC;
+import static com.att.eelf.configuration.Configuration.MDC_STATUS_CODE;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
+import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
+
+import javax.ws.rs.core.Response;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.slf4j.MDC;
+
+public class ResponseBuilder extends BaseLoggingClass {
+
+ Response success(Object d) {
+ return buildSuccessResponse(d, Response.Status.OK.getStatusCode());
+ }
+
+ Response success(int code, Object d) {
+ return buildSuccessResponse(d, code);
+ }
+
+ Response error(ApiError err) {
+ return buildErrResponse(err);
+ }
+
+ Response unauthorized(String msg) {
+ return buildErrResponse(new ApiError(UNAUTHORIZED.getStatusCode(), msg, "Authorization"));
+ }
+
+ Response unavailable() {
+ return buildErrResponse(new ApiError(SERVICE_UNAVAILABLE.getStatusCode(),
+ "Request is unavailable due to unexpected condition"));
+ }
+
+ Response notFound() {
+ return buildErrResponse(new ApiError(NOT_FOUND.getStatusCode(),"Requested object not found"));
+ }
+
+ private Response buildSuccessResponse(Object d, int code) {
+ MDC.put(MDC_STATUS_CODE, "COMPLETE");
+ MDC.put(MDC_RESPONSE_DESC, "");
+ return buildResponse(d, code);
+ }
+
+ private Response buildErrResponse(ApiError err) {
+ MDC.put(MDC_STATUS_CODE, "ERROR");
+ MDC.put(MDC_RESPONSE_DESC, err.getMessage());
+
+ return buildResponse(err, err.getCode());
+ }
+
+ private Response buildResponse(Object obj, int code) {
+ MDC.put(MDC_RESPONSE_CODE, String.valueOf(code));
+
+ auditLogger.auditEvent("");
+ return Response.status(code)
+ .entity(obj)
+ .build();
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/TopicResource.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/TopicResource.java
new file mode 100644
index 0000000..01926b7
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/resources/TopicResource.java
@@ -0,0 +1,218 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.ReplicationType;
+import org.onap.dmaap.dbcapi.model.FqtnType;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.service.TopicService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import static javax.ws.rs.core.Response.Status.CREATED;
+
+@Path("/topics")
+@Api( value= "topics", description = "Endpoint for retreiving MR Topics" )
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Authorization
+public class TopicResource extends BaseLoggingClass {
+ private static FqtnType defaultTopicStyle;
+ private static String defaultPartitionCount;
+ private static String defaultReplicationCount;
+ private TopicService mr_topicService = new TopicService();
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+ private RequiredChecker checker = new RequiredChecker();
+ static final String UNSUPPORTED_PUT_MSG = "Method /PUT not supported for /topics";
+
+ public TopicResource() {
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ defaultTopicStyle = FqtnType.Validator( p.getProperty("MR.topicStyle", "FQTN_LEGACY_FORMAT"));
+ defaultPartitionCount = p.getProperty( "MR.partitionCount", "2");
+ defaultReplicationCount = p.getProperty( "MR.replicationCount", "1");
+
+ logger.info( "Setting defaultTopicStyle=" + defaultTopicStyle );
+ }
+
+ @GET
+ @ApiOperation( value = "return Topic details",
+ notes = "Returns array of `Topic` objects.",
+ response = Topic.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Topic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response getTopics() {
+ List<Topic> allTopics = mr_topicService.getAllTopics();
+
+ GenericEntity<List<Topic>> list = new GenericEntity<List<Topic>>(allTopics) {
+ };
+ return responseBuilder.success(list);
+
+ }
+
+ @POST
+ @ApiOperation( value = "Create a Topic object",
+ notes = "Create `Topic` object."
+ + "For convenience, the message body may populate the `clients` array, in which case each entry will be added as an `MR_Client`."
+ + " Beginning in ONAP Dublin Release, dbcapi will create two AAF Roles by default, one each for the publisher and subscriber per topic."
+ + " MR_Clients can then specify an AAF Identity to be added to the appropriate default Role, avoiding the need to create Role(s) in advance.",
+ response = Topic.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Topic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ public Response addTopic(Topic topic, @QueryParam("useExisting") String useExisting) {
+ logger.info( "addTopic request: " + topic + " useExisting=" + useExisting );
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "topicName", topic.getTopicName(), "^\\S+$" ); //no white space allowed in topicName
+ checker.required( "topicDescription", topic.getTopicDescription());
+ checker.required( "owner", topic.getOwner());
+ } catch( RequiredFieldException rfe ) {
+ logger.error("Error", rfe.getApiError());
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ ReplicationType t = topic.getReplicationCase();
+ if ( t == null || t == ReplicationType.REPLICATION_NOT_SPECIFIED ) {
+ topic.setReplicationCase( mr_topicService.reviewTopic(topic));
+ }
+ FqtnType ft = topic.getFqtnStyle();
+ if ( ft == null || ft == FqtnType.FQTN_NOT_SPECIFIED ) {
+ logger.info( "setting defaultTopicStyle=" + defaultTopicStyle + " for topic " + topic.getTopicName() );
+ topic.setFqtnStyle( defaultTopicStyle );
+ }
+ String pc = topic.getPartitionCount();
+ if ( pc == null ) {
+ topic.setPartitionCount(defaultPartitionCount);
+ }
+ String rc = topic.getReplicationCount();
+ if ( rc == null ) {
+ topic.setReplicationCount(defaultReplicationCount);
+ }
+ topic.setLastMod();
+ Boolean flag = false;
+ if (useExisting != null) {
+ flag = "true".compareToIgnoreCase( useExisting ) == 0;
+ }
+
+ Topic mrc = mr_topicService.addTopic(topic, apiError, flag);
+ if ( mrc != null && apiError.is2xx() ) {
+ return responseBuilder.success(CREATED.getStatusCode(), mrc);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+ @PUT
+ @ApiOperation( value = "return Topic details",
+ notes = "Update a `Topic` object, identified by topicId",
+ response = Topic.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Topic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{topicId}")
+ public Response updateTopic(@PathParam("topicId") String topicId) {
+ ApiError apiError = new ApiError();
+
+ apiError.setCode(Status.BAD_REQUEST.getStatusCode());
+ apiError.setMessage(UNSUPPORTED_PUT_MSG);
+
+ return responseBuilder.error(apiError);
+ }
+
+ @DELETE
+ @ApiOperation( value = "return Topic details",
+ notes = "Delete a `Topic` object, identified by topicId",
+ response = Topic.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 204, message = "Success", response = Topic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{topicId}")
+ public Response deleteTopic(@PathParam("topicId") String id){
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "fqtn", id);
+ } catch( RequiredFieldException rfe ) {
+ logger.error("Error", rfe.getApiError());
+ return responseBuilder.error(rfe.getApiError());
+ }
+
+ mr_topicService.removeTopic(id, apiError);
+ if (apiError.is2xx()) {
+ return responseBuilder.success(Status.NO_CONTENT.getStatusCode(), null);
+ }
+ return responseBuilder.error(apiError);
+ }
+
+
+ @GET
+ @ApiOperation( value = "return Topic details",
+ notes = "Retrieve a `Topic` object, identified by topicId",
+ response = Topic.class)
+ @ApiResponses( value = {
+ @ApiResponse( code = 200, message = "Success", response = Topic.class),
+ @ApiResponse( code = 400, message = "Error", response = ApiError.class )
+ })
+ @Path("/{topicId}")
+ public Response getTopic(@PathParam("topicId") String id) {
+ logger.info("Entry: /GET " + id);
+ ApiError apiError = new ApiError();
+
+ try {
+ checker.required( "topicName", id, "^\\S+$" ); //no white space allowed in topicName
+ } catch( RequiredFieldException rfe ) {
+ logger.error("Error", rfe.getApiError());
+ return responseBuilder.error(rfe.getApiError());
+ }
+ Topic mrc = mr_topicService.getTopic(id, apiError);
+ if ( mrc == null ) {
+ return responseBuilder.error(apiError);
+ }
+ return responseBuilder.success(mrc);
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/ApplicationConfig.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/ApplicationConfig.java
new file mode 100644
index 0000000..2244b73
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/ApplicationConfig.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.server;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.onap.dmaap.dbcapi.resources.RequestTimeLogFilter;
+import org.onap.dmaap.dbcapi.resources.AuthorizationFilter;
+
+public class ApplicationConfig extends ResourceConfig {
+
+ /*
+ * Register JAX-RS application components
+ */
+ public ApplicationConfig() {
+
+ register(AuthorizationFilter.class).
+ register(RequestTimeLogFilter.class);
+
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CadiCertificateManager.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CadiCertificateManager.java
new file mode 100644
index 0000000..1da2bc4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CadiCertificateManager.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2020 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.onap.dmaap.dbcapi.server;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.onap.aaf.cadi.PropAccess;
+
+public class CadiCertificateManager extends CertificateManager {
+ private PropAccess propAccess;
+
+ CadiCertificateManager( Properties properties ) {
+ String cadiPropsFile = properties.getProperty("cadi.properties", "etc/org.onap.dmaa-bc.props");
+ logger.info( "using cadi properties in ", cadiPropsFile);
+
+ propAccess = new PropAccess();
+ ready = true;
+ try {
+ propAccess.load( new FileInputStream( cadiPropsFile ));
+ } catch ( IOException e ) {
+ logger.error( "Failed to load props file: " + cadiPropsFile + "\n" + e.getMessage());
+ ready = false;
+ }
+ setKeyStoreType( "jks");
+ setKeyStoreFile( propAccess.getProperty("cadi_keystore") );
+ setKeyStorePassword( decryptPass( propAccess.getProperty("cadi_keystore_password_jks" ) ));
+
+ setTrustStoreType( "jks");
+ setTrustStoreFile( propAccess.getProperty("cadi_truststore" ) );
+ setTrustStorePassword( decryptPass( propAccess.getProperty("cadi_truststore_password" ) ));
+ }
+
+ private String decryptPass( String password ) {
+ String clear = null;
+ try {
+ clear = propAccess.decrypt(password, false );
+ } catch (IOException e) {
+ logger.error( "Failed to decrypt " + password + ": " + e.getMessage() );
+ }
+ return clear;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertficateManagerFactory.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertficateManagerFactory.java
new file mode 100644
index 0000000..0bffd84
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertficateManagerFactory.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2020 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.onap.dmaap.dbcapi.server;
+
+
+import java.util.Properties;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class CertficateManagerFactory extends BaseLoggingClass {
+ private final Properties dmaapConfig;
+
+ public CertficateManagerFactory() {
+ this((DmaapConfig) DmaapConfig.getConfig());
+ }
+
+ CertficateManagerFactory(Properties params) {
+ this.dmaapConfig = params;
+ }
+
+ public CertificateManager initCertificateManager() {
+ boolean useCadi = "cadi".equalsIgnoreCase(dmaapConfig.getProperty("CertificateManagement", "legacy"));
+ logger.info("CertificateManagerFactory: useCadi=" + useCadi);
+
+ if ( useCadi ) {
+ return new CadiCertificateManager( dmaapConfig );
+ }
+ return new LegacyCertificateManager( dmaapConfig );
+ }
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertificateManager.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertificateManager.java
new file mode 100644
index 0000000..2772b92
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/CertificateManager.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2020 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.onap.dmaap.dbcapi.server;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public abstract class CertificateManager extends BaseLoggingClass{
+
+ class cmAttribute {
+ private String type;
+ private String file;
+ private String password;
+
+ private String getType() {
+ return type;
+ }
+ private void setType(String certificateType) {
+ this.type = certificateType;
+ }
+ private String getFile() {
+ return file;
+ }
+ private void setFile(String keyStoreFile) {
+ this.file = keyStoreFile;
+ }
+ private void setPassword( String pwd ) {
+ this.password = pwd;
+ }
+ private String getPassword() {
+ return password;
+ }
+ }
+
+ private cmAttribute keyStore;
+ private cmAttribute trustStore;
+ protected boolean ready;
+
+ CertificateManager() {
+ keyStore = new cmAttribute();
+ trustStore = new cmAttribute();
+ ready = false;
+ }
+
+ public boolean isReady() {
+ return ready;
+ }
+
+ public String getKeyStoreType() {
+ return keyStore.getType();
+ }
+ public void setKeyStoreType(String certificateType) {
+ this.keyStore.setType( certificateType) ;
+ }
+ public String getKeyStoreFile() {
+ return keyStore.getFile();
+ }
+ public void setKeyStoreFile(String keyStoreFile) {
+ this.keyStore.setFile(keyStoreFile);
+ }
+
+ public String getKeyStorePassword() {
+ return keyStore.getPassword();
+ }
+ public void setKeyStorePassword(String keyStorePassword) {
+ this.keyStore.setPassword(keyStorePassword);
+ }
+ public String getTrustStoreType() {
+ return trustStore.getType();
+ }
+ public void setTrustStoreType( String type ) {
+ this.trustStore.setType(type);
+ }
+ public String getTrustStoreFile() {
+ return trustStore.getFile();
+ }
+ public void setTrustStoreFile(String trustStoreFile) {
+ this.trustStore.setFile(trustStoreFile);
+ }
+ public String getTrustStorePassword() {
+ return trustStore.getPassword();
+ }
+ public void setTrustStorePassword(String trustStorePassword) {
+ this.trustStore.setPassword(trustStorePassword);
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/JettyServer.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/JettyServer.java
new file mode 100644
index 0000000..52d7570
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/JettyServer.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.server;
+
+import com.google.common.collect.Sets;
+import java.util.Properties;
+import javax.servlet.DispatcherType;
+import org.eclipse.jetty.http.HttpVersion;
+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;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+/**
+ * A Jetty server which supports:
+ * - http and https (simultaneously for dev env)
+ * - REST API context
+ * - static html pages (for documentation).
+ */
+public class JettyServer extends BaseLoggingClass {
+
+ private static final CertificateManager certificateManager =
+ new CertficateManagerFactory(DmaapConfig.getConfig()).initCertificateManager();
+ private final Server server;
+
+
+ public Server getServer() {
+ return server;
+ }
+
+ public static CertificateManager getCertificateManager() {
+ return certificateManager;
+ }
+
+ public JettyServer(Properties params) {
+
+ server = new Server();
+ int httpPort = Integer.parseInt(params.getProperty("IntHttpPort", "80"));
+ int sslPort = Integer.parseInt(params.getProperty("IntHttpsPort", "443"));
+ boolean allowHttp = Boolean.parseBoolean(params.getProperty("HttpAllowed", "false"));
+ serverLogger.info("port params: http=" + httpPort + " https=" + sslPort);
+ serverLogger.info("allowHttp=" + allowHttp);
+
+ // HTTP Server
+ HttpConfiguration httpConfig = new HttpConfiguration();
+ httpConfig.setSecureScheme("https");
+ httpConfig.setSecurePort(sslPort);
+ httpConfig.setOutputBufferSize(32768);
+
+ try (ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig))) {
+ httpConnector.setPort(httpPort);
+ httpConnector.setIdleTimeout(30000);
+
+ // HTTPS Server
+ HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
+ httpsConfig.addCustomizer(new SecureRequestCustomizer());
+ SslContextFactory sslContextFactory = new SslContextFactory.Server();
+ sslContextFactory.setWantClientAuth(true);
+
+ if ( ! certificateManager.isReady()) {
+ serverLogger.error("CertificateManager is not ready. NOT starting https!");
+ } else {
+ setUpKeystore(sslContextFactory);
+ setUpTrustStore(sslContextFactory);
+
+
+ if (sslPort != 0) {
+ try (ServerConnector sslConnector = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+ new HttpConnectionFactory(httpsConfig))) {
+ sslConnector.setPort(sslPort);
+ server.addConnector(sslConnector);
+ serverLogger.info("Starting sslConnector on port " + sslPort + " for https");
+ }
+ } else {
+ serverLogger.info("NOT starting sslConnector because InHttpsPort param is " + sslPort );
+ }
+ }
+ if (allowHttp) {
+ serverLogger.info("Starting httpConnector on port " + httpPort);
+ server.addConnector(httpConnector);
+ } else {
+ serverLogger.info("NOT starting httpConnector because HttpAllowed param is " + allowHttp);
+ }
+ }
+
+ // 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.onap.dmaap.dbcapi.resources");
+ jerseyServlet.setInitParameter("javax.ws.rs.Application", "org.onap.dmaap.dbcapi.server.ApplicationConfig");
+
+ // also serve up some static pages...
+ ServletHolder staticServlet = context.addServlet(DefaultServlet.class, "/*");
+ staticServlet.setInitParameter("resourceBase", "www");
+ staticServlet.setInitParameter("pathInfoOnly", "true");
+
+ registerAuthFilters(context);
+
+ try {
+
+ serverLogger.info("Starting jetty server");
+ String unitTest = params.getProperty("UnitTest", "No");
+ serverLogger.info("UnitTest=" + unitTest);
+ if (unitTest.equals("No")) {
+ server.start();
+ server.dumpStdErr();
+ server.join();
+ }
+ } catch (Exception e) {
+ errorLogger.error("Exception " + e);
+ } finally {
+ server.destroy();
+ }
+
+ }
+
+ private void registerAuthFilters(ServletContextHandler context) {
+ context.addFilter("org.onap.dmaap.dbcapi.resources.AAFAuthenticationFilter", "/webapi/*",
+ Sets.newEnumSet(Sets.newHashSet(DispatcherType.FORWARD, DispatcherType.REQUEST), DispatcherType.class));
+ context.addFilter("org.onap.dmaap.dbcapi.resources.AAFAuthorizationFilter", "/webapi/*",
+ Sets.newEnumSet(Sets.newHashSet(DispatcherType.FORWARD, DispatcherType.REQUEST), DispatcherType.class));
+ }
+
+ private void setUpKeystore(SslContextFactory sslContextFactory) {
+ String keystore = JettyServer.certificateManager.getKeyStoreFile();
+ logger.info("https Server using keystore at " + keystore);
+ sslContextFactory.setKeyStorePath(keystore);
+ sslContextFactory.setKeyStoreType(JettyServer.certificateManager.getKeyStoreType());
+ sslContextFactory.setKeyStorePassword(JettyServer.certificateManager.getKeyStorePassword());
+ sslContextFactory.setKeyManagerPassword(JettyServer.certificateManager.getKeyStorePassword());
+ }
+
+ private void setUpTrustStore(SslContextFactory sslContextFactory) {
+ String truststore = JettyServer.certificateManager.getTrustStoreFile();
+ logger.info("https Server using truststore at " + truststore);
+ sslContextFactory.setTrustStorePath(truststore);
+ sslContextFactory.setTrustStoreType(JettyServer.certificateManager.getTrustStoreType());
+ sslContextFactory.setTrustStorePassword(JettyServer.certificateManager.getTrustStorePassword());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/LegacyCertificateManager.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/LegacyCertificateManager.java
new file mode 100644
index 0000000..bd54003
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/LegacyCertificateManager.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2020 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.onap.dmaap.dbcapi.server;
+
+import java.util.Properties;
+
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class LegacyCertificateManager extends CertificateManager {
+
+ public LegacyCertificateManager(Properties properties ) {
+ setKeyStoreType( properties.getProperty("KeyStoreType", "jks") );
+ setKeyStoreFile( properties.getProperty("KeyStoreFile", "etc/keystore") );
+ setKeyStorePassword( properties.getProperty("KeyStorePassword", "changeit") );
+
+ setTrustStoreFile( properties.getProperty("TrustStoreFile", "etc/org.onap.dmaap-bc.trust.jks") );
+ setTrustStoreType( properties.getProperty("TrustStoreType", "jks") );
+ setTrustStorePassword( properties.getProperty("TrustStorePassword", "changeit") );
+ ready = true;
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/Main.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/Main.java
new file mode 100644
index 0000000..942fe6c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/server/Main.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.server;
+import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
+import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
+import static com.att.eelf.configuration.Configuration.MDC_TARGET_ENTITY;
+
+import java.net.InetAddress;
+import java.util.Properties;
+import java.util.UUID;
+import org.onap.dmaap.dbcapi.authentication.ApiPerms;
+import org.onap.dmaap.dbcapi.authentication.ApiPolicy;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.Singleton;
+import org.slf4j.MDC;
+
+public class Main extends BaseLoggingClass {
+
+ 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) {
+ (new Main()).main();
+ }
+
+ private void main() {
+
+ MDC.clear();
+
+ MDC.put(MDC_SERVICE_INSTANCE_ID, "");
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ } catch (Exception e) {
+ errorLogger.error("Error while getting hostname or address", e);
+ }
+ MDC.put(MDC_INSTANCE_UUID, UUID.randomUUID().toString());
+ MDC.put(MDC_ALERT_SEVERITY, "0");
+ MDC.put(MDC_TARGET_ENTITY, "DCAE");
+
+ appLogger.info("Started.");
+ Properties parameters = DmaapConfig.getConfig();
+ setProvFQDN( parameters.getProperty("ProvFQDN", "ProvFQDN.notset.com"));
+
+ // for fresh installs, we may come up with no dmaap name so need to have a way for Controller to talk to us
+ Singleton<Dmaap> dmaapholder = DatabaseClass.getDmaap();
+ String name = dmaapholder.get().getDmaapName();
+ ApiPolicy apiPolicy = new ApiPolicy();
+ if ( apiPolicy.isPermissionClassSet() && (name == null || name.isEmpty())) {
+ ApiPerms p = new ApiPerms();
+ p.setBootMap();
+ }
+
+ try {
+ new JettyServer(parameters);
+ } catch (Exception e) {
+ errorLogger.error("Unable to start Jetty " + DmaapConfig.getConfigFileName(), e);
+ System.exit(1);
+ }
+
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafPermissionService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafPermissionService.java
new file mode 100644
index 0000000..1997633
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafPermissionService.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.AafUserRole;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+
+import static java.lang.String.format;
+
+class AafPermissionService extends BaseLoggingClass {
+
+ private static final String INSTANCE_PREFIX = ":topic.";
+ private final AafService aafService;
+ private final DmaapService dmaapService;
+
+ AafPermissionService(AafService aafService, DmaapService dmaapService) {
+ this.aafService = aafService;
+ this.dmaapService = dmaapService;
+ }
+
+ ApiError assignClientToRole(MR_Client client, String role) {
+ AafUserRole ur = new AafUserRole(client.getClientIdentity(), role);
+ int rc = aafService.addUserRole(ur);
+ if (rc != 201 && rc != 409) {
+ return handleErrorStatus(rc, client,
+ format("Failed to add user %s to role %s", client.getClientIdentity(), role));
+ }
+ return handleOkStatus(client);
+ }
+
+ ApiError grantClientRolePerms(MR_Client client) {
+ return forEachClientAction(client, this::grantPermForClientRole);
+ }
+
+ private ApiError forEachClientAction(MR_Client client, PermissionUpdate permissionUpdate) {
+ try {
+ String instance = INSTANCE_PREFIX + client.getFqtn();
+
+ for (String action : client.getAction()) {
+ permissionUpdate.execute(client.getClientRole(), instance, action);
+ }
+
+ } catch (PermissionServiceException e) {
+ return handleErrorStatus(e.getCode(), client, e.getMessage());
+ }
+ return handleOkStatus(client);
+ }
+
+ private void grantPermForClientRole(String clientRole, String instance, String action) throws PermissionServiceException {
+ if (clientRole != null) {
+ DmaapPerm perm = new DmaapPerm(dmaapService.getTopicPerm(), instance, action);
+ DmaapGrant g = new DmaapGrant(perm, clientRole);
+ int code = aafService.addGrant(g);
+ if (code != 201 && code != 409) {
+ throw new PermissionServiceException(code, format("Grant of %s|%s|%s failed for %s",
+ dmaapService.getTopicPerm(), instance, action, clientRole));
+ }
+ } else {
+ logger.warn("No Grant of {}|{}|{} because role is null ", dmaapService.getTopicPerm(), instance, action);
+ }
+ }
+
+ private ApiError handleErrorStatus(int code, MR_Client client, String message) {
+ ApiError apiError = new ApiError(code, message);
+ client.setStatus(DmaapObject_Status.INVALID);
+ logger.warn(apiError.getMessage());
+ return apiError;
+ }
+
+ private ApiError handleOkStatus(MR_Client client) {
+ client.setStatus(DmaapObject_Status.VALID);
+ return new ApiError(200, "OK");
+ }
+
+ private class PermissionServiceException extends Exception {
+ private final int code;
+ private final String message;
+
+ PermissionServiceException(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+ }
+
+ @FunctionalInterface
+ interface PermissionUpdate {
+ void execute(String clientRole, String instance, String action) throws PermissionServiceException;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafTopicSetupService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafTopicSetupService.java
new file mode 100644
index 0000000..16ffa08
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/AafTopicSetupService.java
@@ -0,0 +1,218 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.aaf.AafNamespace;
+import org.onap.dmaap.dbcapi.aaf.AafRole;
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import static java.lang.String.format;
+import static org.apache.commons.lang3.StringUtils.isNumeric;
+
+class AafTopicSetupService extends BaseLoggingClass {
+
+ private final AafService aafService;
+ private final DmaapService dmaapService;
+ private final DmaapConfig dmaapConfig;
+
+ AafTopicSetupService(AafService aafService, DmaapService dmaapService, DmaapConfig dmaapConfig) {
+ this.aafService = aafService;
+ this.dmaapService = dmaapService;
+ this.dmaapConfig = dmaapConfig;
+ }
+
+ ApiError aafTopicSetup(Topic topic) {
+
+ try {
+ String instance = ":topic." + topic.getFqtn();
+ String topicPerm = dmaapService.getTopicPerm();
+ DmaapPerm pubPerm = createPermission(topicPerm, instance, "pub");
+ DmaapPerm subPerm = createPermission(topicPerm, instance, "sub");
+ DmaapPerm viewPerm = createPermission(topicPerm, instance, "view");
+
+ // creating Topic Roles was not an original feature.
+ // For backwards compatibility, only do this if the feature is enabled.
+ // Also, if the namespace of the topic is a foreign namespace, (i.e. not the same as our root ns)
+ // then we likely don't have permission to create sub-ns and Roles so don't try.
+ if (createTopicRoles() && topic.getFqtn().startsWith(getTopicsNsRoot())) {
+ createNamespace(topic);
+
+ AafRole pubRole = createRole(topic, "publisher");
+ topic.setPublisherRole(pubRole.getFullyQualifiedRole());
+
+ AafRole subRole = createRole(topic, "subscriber");
+ topic.setSubscriberRole(subRole.getFullyQualifiedRole());
+
+ grantPermToRole(pubRole, pubPerm);
+ grantPermToRole(pubRole, viewPerm);
+
+ grantPermToRole(subRole, subPerm);
+ grantPermToRole(subRole, viewPerm);
+ }
+
+ } catch (TopicSetupException ex) {
+ logger.error("Exception in topic setup {}", ex.getMessage());
+ return new ApiError(ex.getCode(), ex.getMessage(), ex.getFields());
+ }
+ return okStatus();
+ }
+
+ ApiError aafTopicCleanup(Topic topic) {
+ try {
+ if (performCleanup()) {
+ String instance = ":topic." + topic.getFqtn();
+ String topicPerm = dmaapService.getTopicPerm();
+ removePermission(topicPerm, instance, "pub");
+ removePermission(topicPerm, instance, "sub");
+ removePermission(topicPerm, instance, "view");
+
+ if (createTopicRoles() && topic.getFqtn().startsWith(getTopicsNsRoot())) {
+ removeNamespace(topic);
+ }
+ }
+ } catch (TopicSetupException ex) {
+ return new ApiError(ex.getCode(), ex.getMessage(), ex.getFields());
+ }
+ return okStatus();
+ }
+
+ private String getTopicsNsRoot() throws TopicSetupException {
+ String nsr = dmaapService.getDmaap().getTopicNsRoot();
+ if (nsr == null) {
+ throw new TopicSetupException(500,
+ "Unable to establish AAF namespace root: (check /dmaap object)", "topicNsRoot");
+ }
+ return nsr;
+ }
+
+ private DmaapPerm createPermission(String permission, String instance, String action) throws TopicSetupException {
+ DmaapPerm perm = new DmaapPerm(permission, instance, action);
+ int rc = aafService.addPerm(perm);
+ if (rc != 201 && rc != 409) {
+ throw new TopicSetupException(500,
+ format("Unexpected response from AAF: %d permission=%s instance=%s action=%s",
+ rc, perm, instance, action));
+ }
+ return perm;
+ }
+
+ private void grantPermToRole(AafRole aafRole, DmaapPerm perm) throws TopicSetupException {
+ DmaapGrant g = new DmaapGrant(perm, aafRole.getFullyQualifiedRole());
+ int rc = aafService.addGrant(g);
+ if (rc != 201 && rc != 409) {
+ String message = format("Grant of %s failed for %s", perm.toString(), aafRole.getFullyQualifiedRole());
+ logger.warn(message);
+ throw new TopicSetupException(rc, message);
+ }
+ }
+
+ private void createNamespace(Topic topic) throws TopicSetupException {
+ AafNamespace ns = new AafNamespace(topic.getFqtn(), aafService.getIdentity());
+ int rc = aafService.addNamespace(ns);
+ if (rc != 201 && rc != 409) {
+ throw new TopicSetupException(500,
+ format("Unexpected response from AAF: %d namespace=%s identity=%s",
+ rc, topic.getFqtn(), aafService.getIdentity()));
+ }
+ }
+
+ private AafRole createRole(Topic topic, String roleName) throws TopicSetupException {
+ AafRole role = new AafRole(topic.getFqtn(), roleName);
+ int rc = aafService.addRole(role);
+ if (rc != 201 && rc != 409) {
+ throw new TopicSetupException(500,
+ format("Unexpected response from AAF: %d topic=%s role=%s",
+ rc, topic.getFqtn(), roleName));
+ }
+ return role;
+ }
+
+ private void removePermission(String permission, String instance, String action) throws TopicSetupException {
+ DmaapPerm perm = new DmaapPerm(permission, instance, action);
+ int rc = aafService.delPerm(perm, true);
+ if (rc != 200 && rc != 404) {
+ throw new TopicSetupException(500,
+ format("Unexpected response from AAF: %d permission=%s instance=%s action=%s",
+ rc, perm, instance, action));
+ }
+ }
+
+ private void removeNamespace(Topic topic) throws TopicSetupException {
+ AafNamespace ns = new AafNamespace(topic.getFqtn(), aafService.getIdentity());
+ int rc = aafService.delNamespace(ns, true);
+ if (rc != 200 && rc != 404) {
+ throw new TopicSetupException(500,
+ format("Unexpected response from AAF: %d namespace=%s identity=%s",
+ rc, topic.getFqtn(), aafService.getIdentity()));
+ }
+ }
+
+ private ApiError okStatus() {
+ return new ApiError(200, "OK");
+ }
+
+ private boolean createTopicRoles() {
+ return "true".equalsIgnoreCase(dmaapConfig.getProperty("aaf.CreateTopicRoles", "true"));
+ }
+
+ private boolean performCleanup() {
+ String deleteLevel = dmaapConfig.getProperty("MR.ClientDeleteLevel", "0");
+ if (!isNumeric(deleteLevel)) {
+ return false;
+ }
+ return Integer.valueOf(deleteLevel) >= 2;
+ }
+
+ private class TopicSetupException extends Exception {
+
+ private final int code;
+ private final String message;
+ private final String fields;
+
+ TopicSetupException(int code, String message) {
+ this(code, message, "");
+ }
+
+ TopicSetupException(int code, String message, String fields) {
+ this.code = code;
+ this.message = message;
+ this.fields = fields;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ public String getFields() {
+ return fields;
+ }
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java
new file mode 100644
index 0000000..ef1e6f4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.authentication.ApiPolicy;
+import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.RandomString;
+import org.slf4j.MDC;
+
+public class ApiService extends BaseLoggingClass {
+
+ private String apiNamespace;
+ private String uri;
+ private String uriPath;
+ private String method;
+ private String authorization;
+ private String requestId;
+ private ApiError err;
+ private ApiPolicy apiPolicy;
+ private CredentialsParser credentialsParser = new CredentialsParser();
+
+ public ApiService() {
+
+ err = new ApiError();
+ requestId = (new RandomString(10)).nextString();
+
+ if (apiNamespace == null) {
+ DmaapConfig p = (DmaapConfig) DmaapConfig.getConfig();
+ apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api");
+ logger.info("config param usePE has been deprecated. Use ApiPermission.Class property instead.");
+ }
+ apiPolicy = new ApiPolicy();
+
+ logger.info("apiNamespace=" + apiNamespace);
+ }
+
+ public ApiService setAuth(String auth) {
+ this.authorization = auth;
+ logger.info("setAuth: authorization={} ", authorization);
+ return this;
+ }
+
+ private void setServiceName() {
+ String svcRequest = new String(this.method + " " + this.uriPath);
+ MDC.put(MDC_SERVICE_NAME, svcRequest);
+ }
+
+ public ApiService setHttpMethod(String httpMethod) {
+ this.method = httpMethod;
+ logger.info("setHttpMethod: method={} ", method);
+ setServiceName();
+ return this;
+ }
+
+ public ApiService setUriPath(String uriPath) {
+ this.uriPath = uriPath;
+ this.uri = setUriFromPath(uriPath);
+ logger.info("setUriPath: uriPath={} uri={}", uriPath, uri);
+ setServiceName();
+ return this;
+ }
+
+ private String setUriFromPath(String uriPath) {
+ int ch = uriPath.indexOf("/");
+ if (ch > 0) {
+ return ((String) uriPath.subSequence(0, ch));
+ } else {
+ return uriPath;
+ }
+ }
+
+ public ApiError getErr() {
+ return err;
+ }
+
+ public void checkAuthorization() throws Exception {
+
+ MDC.put(MDC_KEY_REQUEST_ID, requestId);
+
+ logger.info("request: uri={} method={} auth={}", uri, method, authorization);
+
+ if (uri == null || uri.isEmpty()) {
+ String errmsg = "No URI value provided ";
+ err.setMessage(errmsg);
+ logger.info(errmsg);
+ throw new AuthenticationErrorException();
+ }
+ if (method == null || method.isEmpty()) {
+ String errmsg = "No method value provided ";
+ err.setMessage(errmsg);
+ 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 == null || env.isEmpty()) {
+ env = "boot";
+ }
+ if (!apiPolicy.isPermissionClassSet()) {
+ return; // skip authorization if not enabled
+ }
+
+ Credentials credentials = credentialsParser.parse(authorization);
+ try {
+ DmaapPerm p = new DmaapPerm(apiNamespace + "." + uri, env, method);
+ apiPolicy.check(credentials.getId(), credentials.getPwd(), p);
+ } catch (AuthenticationErrorException ae) {
+ String errmsg =
+ "User " + credentials.getId() + " failed authentication/authorization for " + apiNamespace + "." + uriPath + " " + env
+ + " " + method;
+ logger.info(errmsg);
+ err.setMessage(errmsg);
+ throw ae;
+
+ }
+ }
+
+ public ApiService setRequestId(String requestId) {
+ if (requestId == null || requestId.isEmpty()) {
+ this.requestId = (new RandomString(10)).nextString();
+ logger.warn("X-ECOMP-RequestID not set in HTTP Header. Setting RequestId value to: " + this.requestId);
+ } else {
+ this.requestId = requestId;
+ }
+ MDC.put(MDC_KEY_REQUEST_ID, this.requestId);
+ return this;
+ }
+}
+
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/Credentials.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/Credentials.java
new file mode 100644
index 0000000..aee9b4f
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/Credentials.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+public class Credentials {
+
+ private final String id;
+ private final String pwd;
+
+ Credentials(String id, String pwd) {
+ this.id = id;
+ this.pwd = pwd;
+ }
+
+ static Credentials empty() {
+ return new Credentials("", "");
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getPwd() {
+ return pwd;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/CredentialsParser.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/CredentialsParser.java
new file mode 100644
index 0000000..4156d1b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/CredentialsParser.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import javax.xml.bind.DatatypeConverter;
+
+class CredentialsParser {
+
+ Credentials parse(String authorizationHeader) {
+ if (authorizationHeader == null || authorizationHeader.isEmpty()) {
+ return Credentials.empty();
+ }
+
+ String credentials = authorizationHeader.substring("Basic".length()).trim();
+ byte[] decoded = DatatypeConverter.parseBase64Binary(credentials);
+ String decodedString = new String(decoded);
+ String[] actualCredentials = decodedString.split(":");
+ return new Credentials(actualCredentials[0], actualCredentials[1]);
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_NodeService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_NodeService.java
new file mode 100644
index 0000000..b29beb9
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_NodeService.java
@@ -0,0 +1,273 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcae
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Response.Status;
+import org.onap.dmaap.dbcapi.client.DrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Node;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+
+public class DR_NodeService extends BaseLoggingClass {
+ private class DrProv {
+ String currentNodes;
+ String currentStaticNodes;
+
+ private String getX( String X, ApiError apiError ) {
+
+ logger.info( "templog:getX at" + " 12.10.10" );
+ DrProvConnection prov = new DrProvConnection();
+ logger.info( "templog:getX at" + " 12.10.12" );
+ prov.makeNodesConnection( X );
+ logger.info( "templog:getX at" + " 12.10.14" );
+ String resp = prov.doGetNodes( apiError );
+ logger.info( "templog:getX at" + " 12.10.16" );
+ logger.info( "rc=" + apiError.getCode() );
+ logger.info( "templog:getX at" + " 12.10.18" );
+ return resp;
+ }
+
+ private void setX( String X, String list, ApiError apiError ) {
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeNodesConnection( X, list );
+ prov.doPutNodes( apiError );
+ }
+
+ private String removeFromList( String aNode, String aList ) {
+ String[] nodeList = aList.split("\\|");
+ StringBuilder res = new StringBuilder();
+ for ( String n: nodeList ) {
+ logger.info( "compare existing node " + n + " vs " + aNode );
+ if ( ! n.equals(aNode)) {
+ if (res.length() > 0 ) {
+ res.append( "|" );
+ }
+ res.append(n);
+ }
+ }
+ logger.info( "result=" + res.toString() );
+ return res.toString();
+ }
+
+ boolean containsNode( String aNode , ApiError apiError ){
+
+ logger.info( "templog:containsNode at" + " 12.10" );
+ //DrProvConnection prov = new DrProvConnection();
+ //prov.makeNodesConnection();
+ currentNodes = getX( "NODES", apiError );
+ logger.info( "templog:containsNode at" + " 12.12" );
+ if ( ! apiError.is2xx() || currentNodes == null ) {
+ logger.info( "templog:containsNode at" + " 12.14" );
+ return false;
+ }
+ logger.info( "templog:containsNode at" + " 12.16" );
+ logger.info( "NODES now=" + currentNodes );
+ String[] nodeList = currentNodes.split("\\|");
+ logger.info( "templog:containsNode at" + " 12.17" );
+ for( String n: nodeList ) {
+ logger.info( "templog:containsNode at" + " 12.18" );
+ logger.info( "compare existing node " + n + " vs " + aNode );
+ if ( n.equals(aNode) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void addNode( String aNode, ApiError apiError ) {
+
+ currentNodes = currentNodes + "|" + aNode;
+ setX( "NODES", currentNodes, apiError );
+
+
+ }
+ void removeNode( String aNode, ApiError apiError ) {
+ currentNodes = removeFromList( aNode, currentNodes );
+ setX( "NODES", currentNodes, apiError );
+ }
+
+ public boolean containsStaticNode(String aNode, ApiError apiError) {
+
+ //DrProvConnection prov = new DrProvConnection();
+ //prov.makeNodesConnection();
+ currentStaticNodes = getX( "STATIC_ROUTING_NODES", apiError );
+ if (! apiError.is2xx() || currentStaticNodes == null ) {
+ return false;
+ }
+ logger.info( "STATIC_ROUTING_NODES now=" + currentNodes );
+ String[] nodeList = currentStaticNodes.split("\\|");
+ for( String n: nodeList ) {
+ logger.info( "compare existing node " + n + " vs " + aNode );
+ if ( n.equals(aNode) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public void addStaticNode(String aNode, ApiError apiError) {
+ currentStaticNodes = currentStaticNodes + "|" + aNode;
+ setX( "STATIC_ROUTING_NODES", currentStaticNodes, apiError );
+ }
+ void removeStaticNode( String aNode, ApiError apiError ) {
+ currentStaticNodes = removeFromList( aNode, currentStaticNodes );
+ setX( "STATIC_ROUTING_NODES", currentStaticNodes, apiError );
+ }
+ }
+
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ String unit_test = p.getProperty( "UnitTest", "No" );
+
+ private Map<String, DR_Node> dr_nodes = DatabaseClass.getDr_nodes();
+
+ public Map<String, DR_Node> getDr_Nodes() {
+ return dr_nodes;
+ }
+
+ public List<DR_Node> getAllDr_Nodes() {
+ return new ArrayList<DR_Node>(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;
+ }
+ logger.info( "templog:addDr_Node at" + " 10" );
+
+ DrProv drProv = new DrProv();
+ logger.info( "templog:addDr_Node at" + " 12" );
+
+ if ( ! drProv.containsNode( node.getFqdn(), apiError ) && apiError.is2xx() ) {
+ logger.info( "templog:addDr_Node at" + " 15" );
+ drProv.addNode( node.getFqdn(), apiError );
+ }
+ logger.info( "templog:addDr_Node at" + " 20" );
+ if ( ! apiError.is2xx() && ! unit_test.equals( "Yes" ) ) {
+ return null;
+ }
+ logger.info( "templog:addDr_Node at" + " 30" );
+ DcaeLocationService locService = new DcaeLocationService();
+ if ( locService.isEdgeLocation( node.getDcaeLocationName()) && ! drProv.containsStaticNode( node.getFqdn(), apiError ) ) {
+ if ( apiError.is2xx() ) {
+ drProv.addStaticNode( node.getFqdn(), apiError );
+ }
+ }
+ logger.info( "templog:addDr_Node at" + " 40" );
+ if ( ! apiError.is2xx() && ! unit_test.equals("Yes") ) {
+ return null;
+ }
+
+ logger.info( "templog:addDr_Node at" + " 50" );
+ node.setLastMod();
+ node.setStatus(DmaapObject_Status.VALID);
+ dr_nodes.put( node.getFqdn(), node );
+ logger.info( "templog:addDr_Node at" + " 60" );
+ apiError.setCode(200);
+ return node;
+ }
+
+ public DR_Node updateDr_Node( DR_Node node, ApiError apiError ) {
+ DR_Node old = dr_nodes.get( node.getFqdn() );
+ if ( old == null ) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ apiError.setFields( "fqdn");
+ apiError.setMessage( "Node " + node.getFqdn() + " 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;
+ }
+
+ DrProv drProv = new DrProv();
+ if ( drProv.containsNode( old.getFqdn(), apiError ) && apiError.is2xx() ) {
+ drProv.removeNode( old.getFqdn(), apiError );
+ }
+ DcaeLocationService locService = new DcaeLocationService();
+ if ( locService.isEdgeLocation( old.getDcaeLocationName()) && drProv.containsStaticNode( old.getFqdn(), apiError ) ) {
+ if ( apiError.is2xx()) {
+ drProv.removeStaticNode( old.getFqdn(), apiError );
+ }
+
+ }
+
+ apiError.setCode(200);
+ return dr_nodes.remove(nodeName);
+ }
+
+ public String getNodePatternAtLocation( String loc, boolean allowMult ) {
+ 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());
+ if ( ! allowMult ) {
+ break;
+ }
+ }
+ }
+ logger.info( "returning " + str.toString() );
+ return str.toString();
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_PubService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_PubService.java
new file mode 100644
index 0000000..352330a
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_PubService.java
@@ -0,0 +1,147 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Response.Status;
+import org.onap.dmaap.dbcapi.client.DrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+
+public class DR_PubService extends BaseLoggingClass{
+
+ private Map<String, DR_Pub> 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<String, DR_Pub> getDr_Pubs() {
+ return dr_pubs;
+ }
+
+ public List<DR_Pub> getAllDr_Pubs() {
+ return new ArrayList<DR_Pub>(dr_pubs.values());
+ }
+
+ public ArrayList<DR_Pub> getDr_PubsByFeedId( String feedId ) {
+ ArrayList<DR_Pub> somePubs = new ArrayList<DR_Pub>();
+ 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(), true );
+ 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.doXgressPost(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.info( DmaapbcLogMessageEnum.INGRESS_CREATE_ERROR, Integer.toString(rc), pub.getPubId(), pub.getFeedId(), 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 ) {
+ return removeDr_Pub( pubId, err, true );
+ }
+
+
+ public DR_Pub removeDr_Pub( String pubId, ApiError err, boolean hitDR ) {
+ 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/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java
new file mode 100644
index 0000000..0a583a0
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java
@@ -0,0 +1,228 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.client.DrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.RandomInteger;
+
+public class DR_SubService extends BaseLoggingClass {
+
+ private Map<String, DR_Sub> dr_subs = DatabaseClass.getDr_subs();
+ private DR_NodeService nodeService = new DR_NodeService();
+ private String provURL;
+ private static DrProvConnection prov;
+
+ private String unit_test;
+
+
+ public DR_SubService( ) {
+ logger.debug( "Entry: DR_SubService (with no args)" );
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ unit_test = p.getProperty( "UnitTest", "No" );
+ }
+ public DR_SubService( String subURL ) {
+ logger.debug( "Entry: DR_SubService " + subURL );
+ provURL = subURL;
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ unit_test = p.getProperty( "UnitTest", "No" );
+ }
+ public Map<String, DR_Sub> getDR_Subs() {
+ logger.debug( "enter getDR_Subs()");
+ return dr_subs;
+ }
+
+ public List<DR_Sub> getAllDr_Subs() {
+ logger.debug( "enter getAllDR_Subs()");
+ return new ArrayList<>(dr_subs.values());
+ }
+
+ public ArrayList<DR_Sub> getDr_SubsByFeedId( String pubId ) {
+ ArrayList<DR_Sub> 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.debug( "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.debug( "enter addDR_Subs()");
+ prov = new DrProvConnection();
+ prov.makeSubPostConnection( provURL );
+ String resp = prov.doPostDr_Sub( sub, apiError );
+ if ( "Yes".equals(unit_test) ) {
+ resp = simulateResp( sub, "POST" );
+ apiError.setCode(201);
+ }
+ logger.debug( "addDr_Sub resp=" + resp );
+
+ DR_Sub snew = null;
+
+ if ( resp != null ) {
+ snew = new DR_Sub( resp );
+ snew.setDcaeLocationName(sub.getDcaeLocationName());
+ snew.setLastMod();
+ addEgressRoute( snew, apiError );
+ dr_subs.put( snew.getSubId(), snew );
+ apiError.setCode(201);
+ } else {
+ apiError.setCode(400);
+ }
+
+ return snew;
+ }
+
+ private void addEgressRoute( DR_Sub sub, ApiError err ) {
+
+ String nodePattern = nodeService.getNodePatternAtLocation( sub.getDcaeLocationName(), false );
+ if ( nodePattern != null && nodePattern.length() > 0 ) {
+ logger.info( "creating egress rule: sub " + sub.getSubId() + " on feed " + sub.getFeedId() + " to " + nodePattern);
+ prov.makeEgressConnection( sub.getSubId(), nodePattern);
+ int rc = prov.doXgressPost(err);
+ logger.info( "rc=" + rc + " error code=" + err.getCode() );
+
+ if ( rc != 200 ) {
+ switch( rc ) {
+ case 403:
+ logger.error( "Not authorized for DR egress API");
+ err.setCode(500);
+ err.setMessage("API deployment/configuration error - contact support");
+ err.setFields( "PROV_AUTH_ADDRESSES");
+ break;
+
+ default:
+ logger.info( DmaapbcLogMessageEnum.EGRESS_CREATE_ERROR, Integer.toString(rc), sub.getSubId(), sub.getFeedId(), nodePattern);
+ }
+ }
+
+ }
+ }
+
+ public DR_Sub updateDr_Sub( DR_Sub obj, ApiError apiError ) {
+ logger.debug( "enter updateDR_Subs()");
+
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeSubPutConnection( obj.getSubId() );
+ String resp = prov.doPutDr_Sub( obj, apiError );
+ if ( unit_test.equals( "Yes" ) ) {
+ resp = simulateResp( obj, "PUT" );
+ apiError.setCode(200);
+ }
+ logger.debug( "resp=" + resp );
+
+ DR_Sub snew = null;
+
+ if ( resp != null ) {
+ snew = new DR_Sub( resp );
+ snew.setDcaeLocationName(obj.getDcaeLocationName());
+ snew.setLastMod();
+ dr_subs.put( snew.getSubId(), snew );
+ apiError.setCode(200);
+ } else if ( apiError.is2xx()) {
+ apiError.setCode(400);
+ apiError.setMessage("unexpected empty response from DR Prov");
+ }
+
+ return snew;
+ }
+
+ public void removeDr_Sub( String key, ApiError apiError ) {
+ removeDr_Sub( key, apiError, true );
+ return;
+ }
+
+ public void removeDr_Sub( String key, ApiError apiError, boolean hitDR ) {
+ logger.debug( "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 {
+ if ( hitDR ) {
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeSubPutConnection( key );
+ String resp = prov.doDeleteDr_Sub( sub, apiError );
+ logger.debug( "resp=" + resp );
+ } else {
+ apiError.setCode(200);
+ }
+
+ if ( apiError.is2xx() || unit_test.equals( "Yes" ) ) {
+ dr_subs.remove(key);
+ }
+ }
+
+ return;
+ }
+
+ private String simulateResp( DR_Sub sub, String action ){
+ String server = "subscriber.onap.org";
+ String subid;
+ if ( action.equals( "POST" ) ) {
+ RandomInteger ran = new RandomInteger(10000);
+ subid = Integer.toString( ran.next() );
+ } else if ( action.equals( "PUT" ) ) {
+ subid = sub.getSubId();
+ } else {
+ subid = "99";
+ }
+ String ret = String.format("{\"suspend\": false, \"delivery\": {\"url\": \"https://%s/delivery/%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": true}, \"metadataOnly\": false, \"groupid\": \"0\" , \"follow_redirect\": true, ",
+ server, subid, sub.getUsername(), sub.getUserpwd());
+ String links = String.format( "\"links\": {\"feed\": \"https://dr-prov/feedlog/%s\", \"self\": \"https://dr-prov/sub/%s\", \"log\": \"https://dr-prov/sublog/%s\" }",
+ sub.getFeedId(),
+ subid,
+ subid );
+ ret += links + "}";
+ logger.info( "DR_SubService:simulateResp=" + ret);
+
+ return ret;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DcaeLocationService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DcaeLocationService.java
new file mode 100644
index 0000000..ad6c993
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DcaeLocationService.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+public class DcaeLocationService {
+
+ private static final String DEFAULT_CENTRAL_LOCATION = "aCentralLocation"; // default value that is obvious to see is wrong
+ private final Map<String, DcaeLocation> dcaeLocations;
+
+ public DcaeLocationService() {
+ this(DatabaseClass.getDcaeLocations());
+ }
+
+ DcaeLocationService(Map<String, DcaeLocation> dcaeLocations) {
+ this.dcaeLocations = dcaeLocations;
+ }
+
+ public List<DcaeLocation> 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);
+ }
+
+ String getCentralLocation() {
+
+ Optional<DcaeLocation> firstCentralLocation =
+ dcaeLocations.values().stream().filter(DcaeLocation::isCentral).findFirst();
+
+ return firstCentralLocation.isPresent() ? firstCentralLocation.get().getDcaeLocationName() : DEFAULT_CENTRAL_LOCATION;
+ }
+
+ boolean isEdgeLocation(String aName) {
+ return dcaeLocations.get(aName) != null && !dcaeLocations.get(aName).isCentral();
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DmaapService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DmaapService.java
new file mode 100644
index 0000000..8789ac4
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/DmaapService.java
@@ -0,0 +1,310 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.AafServiceFactory;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.authentication.ApiPerms;
+import org.onap.dmaap.dbcapi.authentication.ApiPolicy;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.Singleton;
+
+public class DmaapService extends BaseLoggingClass {
+
+
+ private Singleton<Dmaap> dmaapholder = DatabaseClass.getDmaap();
+ private static String noEnvironmentPrefix;
+
+
+ String topicFactory; // = "org.openecomp.dcae.dmaap.topicFactory";
+ String topicMgrRole; // = "org.openecomp.dmaapBC.TopicMgr";
+
+ private boolean multiSite;
+
+
+ public DmaapService() {
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ topicFactory = p.getProperty("MR.TopicFactoryNS", "MR.topicFactoryNS.not.set");
+ topicMgrRole = p.getProperty("MR.TopicMgrRole", "MR.TopicMgrRole.not.set" );
+
+ multiSite = "true".equalsIgnoreCase(p.getProperty("MR.multisite", "true"));
+ noEnvironmentPrefix = p.getProperty( "AAF.NoEnvironmentPrefix", "org.onap");
+
+ logger.info( "DmaapService settings: " +
+ " topicFactory=" + topicFactory +
+ " topicMgrRole=" + topicMgrRole +
+
+ " multisite=" + multiSite +
+ " noEnvironmentPrefix=" + noEnvironmentPrefix
+ );
+
+ Dmaap dmaap = dmaapholder.get();
+ logger.info( "DmaapService object values: " +
+ " dmaapName=" + dmaap.getDmaapName() +
+ " drProvURL=" + dmaap.getDrProvUrl() +
+ " version="+ dmaap.getVersion()
+ );
+
+ }
+
+ 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 AafServiceFactory().initAafService(ServiceType.AAF_Admin);
+ ApiPolicy apiPolicy = new ApiPolicy();
+ if ( apiPolicy.isPermissionClassSet() ) {
+ ApiPerms p = new ApiPerms();
+ p.setEnvMap();
+ }
+ boolean anythingWrong = false;
+
+ if ( multiSite ) {
+ anythingWrong = setTopicMgtPerms( nd, aaf ) || createMmaTopic();
+ }
+
+ if ( anythingWrong ) {
+ dmaap.setStatus(DmaapObject_Status.INVALID);
+ }
+ else {
+ dmaap.setStatus(DmaapObject_Status.VALID);
+ }
+ dmaap.setLastMod();
+ dmaapholder.update(dmaap);
+
+ return dmaap;
+
+ }
+ else {
+ return dmaap;
+ }
+ }
+
+ public Dmaap updateDmaap( Dmaap nd ) {
+ logger.info( "entering updateDmaap()" );
+
+ boolean anythingWrong = false;
+
+ 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.
+ //dcaeTopicNs = dmaapholder.get().getTopicNsRoot();
+ ApiPolicy apiPolicy = new ApiPolicy();
+ if ( apiPolicy.isPermissionClassSet()) {
+ ApiPerms p = new ApiPerms();
+ p.setEnvMap();
+ }
+ AafService aaf = new AafServiceFactory().initAafService(ServiceType.AAF_Admin);
+ if ( multiSite ) {
+ 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();
+ String nsRoot = dmaap.getTopicNsRoot();
+ if ( nsRoot == null ) { return null; }
+
+ String t;
+ // in ONAP Casablanca, we assume no distinction of environments reflected in topic namespace
+ if ( nsRoot.startsWith(noEnvironmentPrefix) ) {
+ t = nsRoot + ".mr.topic";
+ } else {
+ t = nsRoot + "." + val + ".mr.topic";
+ }
+ return t;
+ }
+
+ public String getBridgeAdminFqtn(){
+ Dmaap dmaap = dmaapholder.get();
+ String topic = dmaap.getBridgeAdminTopic();
+
+ // check if this is already an fqtn (contains a dot)
+ // otherwise build it
+ if ( topic.indexOf('.') < 0 ) {
+ topic = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + dmaap.getBridgeAdminTopic();
+ }
+ return( topic );
+ }
+
+ private boolean setTopicMgtPerms( Dmaap nd, AafService aaf ){
+ String[] actions = { "create", "destroy" };
+ String instance = ":" + nd.getTopicNsRoot() + "." + nd.getDmaapName() + ".mr.topic:" + nd.getTopicNsRoot() + "." + 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 = nd.getTopicNsRoot() +"." + 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 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.AAF_UNEXPECTED_RESPONSE, Integer.toString(rc), "add perm", t + "|" + instance + "|" + action );
+ return true;
+ }
+
+ DmaapGrant grant = new DmaapGrant( perm, topicMgrRole );
+ rc = aaf.addGrant( grant );
+ if ( rc != 201 && rc != 409 ) {
+ errorLogger.error( DmaapbcLogMessageEnum.AAF_UNEXPECTED_RESPONSE, Integer.toString(rc), "grant to " + topicMgrRole + " perm ", topicFactory + "|" + instance + "|" + action );
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+ public boolean testCreateMmaTopic() {
+
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ String unit_test = p.getProperty( "UnitTest", "No" );
+ if ( unit_test.equals( "Yes" ) ) {
+ return createMmaTopic();
+ }
+ 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<MR_Client> clients = new ArrayList<MR_Client>();
+ 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().init();
+ mmaTopic.setTopicName(dmaap.getBridgeAdminTopic());
+ mmaTopic.setClients(clients);
+ mmaTopic.setOwner("BusController");
+ mmaTopic.setTopicDescription("topic reserved for MirrorMaker Administration");
+ mmaTopic.setTnxEnabled("false");
+ mmaTopic.setPartitionCount("1"); // a single partition should guarantee message order
+
+
+ ApiError err = new ApiError();
+ TopicService svc = new TopicService();
+ try {
+ @SuppressWarnings("unused")
+ Topic nTopic = svc.addTopic(mmaTopic, err, true);
+ if ( err.is2xx() || err.getCode() == 409 ) {
+ return false;
+ }
+ } catch ( Exception e) {
+ errorLogger.error( DmaapbcLogMessageEnum.UNEXPECTED_CONDITION, " while adding Topic: " + e.getMessage());
+ }
+ errorLogger.error( DmaapbcLogMessageEnum.TOPIC_CREATE_ERROR, dmaap.getBridgeAdminTopic(), err.getFields(), err.getFields(), err.getMessage());
+
+ return rc;
+
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java
new file mode 100644
index 0000000..19b0267
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java
@@ -0,0 +1,572 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Response.Status;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.onap.dmaap.dbcapi.client.DrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.RandomInteger;
+
+public class FeedService extends BaseLoggingClass {
+
+ private Map<String, Feed> feeds = DatabaseClass.getFeeds();
+ private Map<String, DR_Sub> dr_subs = DatabaseClass.getDr_subs();
+ private DR_PubService pubService = new DR_PubService();
+ private DR_SubService subService = new DR_SubService();
+ private DcaeLocationService dcaeLocations = new DcaeLocationService();
+ private String deleteHandling;
+ private String unit_test;
+
+ public FeedService() {
+ logger.info( "new FeedService");
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ deleteHandling = p.getProperty("Feed.deleteHandling", "DeleteOnDR");
+ unit_test = p.getProperty( "UnitTest", "No" );
+
+ }
+
+ public Map<String, Feed> getFeeds() {
+ return feeds;
+ }
+
+ private void getSubObjects( Feed f ) {
+ ArrayList<DR_Pub> pubs = pubService.getDr_PubsByFeedId( f.getFeedId() );
+ f.setPubs(pubs);
+ ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( f.getFeedId() );
+ f.setSubs(subs);
+ }
+
+ public List<Feed> getAllFeeds(){
+ return getAllFeeds(null, null, null);
+ }
+
+ public List<Feed> getAllFeeds( String name, String ver, String match ) {
+ logger.info( "getAllFeeds: name=" + name + " ver=" + ver + " match=" + match);
+ ArrayList<Feed> fatFeeds = new ArrayList<Feed>();
+ for( Feed f: feeds.values() ) {
+ boolean keep = true;
+ if ( name != null ) {
+ if ( match != null && "startsWith".equals(match) ) {
+ if ( ! f.getFeedName().startsWith( name ) ) {
+ logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't start with=" + name);
+ keep = false;
+ }
+ } else if ( match != null && match.equals("contains") ) {
+ if ( ! f.getFeedName().contains( name ) ) {
+ logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't contain=" + name);
+ keep = false;
+ }
+ } else {
+ if ( ! f.getFeedName().equals( name ) ) {
+ logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't equal=" + name);
+ keep = false;
+ }
+ }
+
+ }
+ if ( keep && ver != null ) {
+ if ( ! f.getFeedVersion().equals(ver)) {
+ logger.info( "getAllFeeds: feedVersion=" + f.getFeedName() + " doesn't match " + ver);
+ keep = false;
+ } else {
+ logger.info( "getAllFeeds: feedVersion=" + f.getFeedName() + " matches " + ver);
+ }
+ }
+
+ if (keep){
+ getSubObjects(f);
+ fatFeeds.add(f);
+ }
+ }
+ return fatFeeds;
+ }
+
+
+ private Feed _getFeed( String key, ApiError err, boolean flag ) {
+ Feed f = feeds.get( key );
+ if ( f != null && ( flag || f.getStatus() != DmaapObject_Status.DELETED ) ) {
+ getSubObjects( f );
+ } else {
+ err.setCode(Status.NOT_FOUND.getStatusCode());
+ err.setMessage("feed not found");
+ err.setFields("feedId=" + key );
+ return null;
+ }
+ err.setCode(200);
+ return f;
+ }
+ public Feed getFeed( String key, ApiError err ) {
+ return _getFeed( key, err, false );
+ }
+ public Feed getFeedPure( String key, ApiError err ) {
+ return _getFeed( key, err, true );
+ }
+
+ public Feed getFeedByName( String name, String ver, ApiError err ) {
+ for( Feed f: feeds.values() ) {
+ if ( f.getFeedName().equals( name ) && f.getFeedVersion().equals(ver) ) {
+ getSubObjects(f);
+ return f;
+ }
+
+ }
+ err.setCode(Status.NOT_FOUND.getStatusCode());
+ err.setMessage("feed not found");
+ err.setFields("feedName=" + name + " and ver=" + ver );
+ return null;
+
+ }
+
+ 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<DR_Pub> reqPubs = req.getPubs();
+ ArrayList<DR_Pub> newPubs = fnew.getPubs();
+
+
+
+ int nSize = newPubs.size();
+ int rSize = reqPubs.size();
+ logger.info( "reqPubs size=" + rSize + " newPubs size=" + nSize );
+ if ( nSize != rSize ) {
+ errorLogger.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("notSpecified");
+ }
+ 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<DR_Sub> subs = req.getSubs();
+ if ( subs == null || 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<DR_Pub> pubs = new ArrayList<DR_Pub>();
+ pubs.add( new DR_Pub( dcaeLocations.getCentralLocation())
+ .setRandomUserName()
+ .setRandomPassword());
+ req.setPubs(pubs);
+ }
+
+
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeFeedConnection();
+ String resp = prov.doPostFeed( req, err );
+ if ( unit_test.equals( "Yes" ) ) {
+ // assume resp is null, so need to simulate it
+ resp = simulateResp( req, "POST" );
+ }
+ 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 ) {
+
+ // 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<DR_Pub> pubs = new ArrayList<DR_Pub>();
+ pubs.add( new DR_Pub( dcaeLocations.getCentralLocation())
+ .setRandomUserName()
+ .setRandomPassword());
+ req.setPubs(pubs);
+ }
+
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeFeedConnection( req.getFeedId() );
+ String resp = prov.doPutFeed( req, err );
+ if ( unit_test.equals( "Yes" ) ) {
+ // assume resp is null, so need to simulate it
+ resp = simulateResp( req, "PUT" );
+ err.setCode(200);
+ }
+ 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;
+ }
+
+
+ //
+ // DR does not actually delete a feed, so we provide two behaviors:
+ // 1) clean up the feed by removing all subs and pubs, mark it here as DELETED.
+ // then client can add it back if desired.
+ // 2) Call the DR Delete function. Feed with the same name and version can never be added again
+ //
+ public Feed removeFeed( Feed req, ApiError err ) {
+ return removeFeed( req, err, true );
+ }
+
+ public Feed removeFeed( Feed req, ApiError err, boolean hitDR ) {
+
+ // strip pubs and subs from feed first no matter what
+ ArrayList<DR_Pub> pubs = pubService.getDr_PubsByFeedId( req.getFeedId() );
+ for( DR_Pub pub: pubs ) {
+ pubService.removeDr_Pub(pub.getPubId(), err, hitDR);
+ if ( ! err.is2xx()) {
+ return req;
+ }
+ }
+ ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( req.getFeedId() );
+ for ( DR_Sub sub: subs ) {
+ subService.removeDr_Sub(sub.getSubId(), err, hitDR);
+ if ( ! err.is2xx()) {
+ return req;
+ }
+ }
+
+ if ( ! hitDR ) {
+ return feeds.remove(req.getFeedId());
+ }
+
+ if ( deleteHandling.equalsIgnoreCase("DeleteOnDR")) {
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeFeedConnection( req.getFeedId() );
+ String resp = prov.doDeleteFeed( req, err );
+ if ( unit_test.equals( "Yes" ) ) {
+ // assume resp is null, so need to simulate it
+ resp = simulateDelResp( req );
+ }
+ 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 req; // return back the requested feed - implies it wasn't removed
+ }
+ return feeds.remove(req.getFeedId());
+ } else {
+
+ logger.info( "Disable pubs for deleted feed - creating tmp pub");
+ ArrayList<DR_Pub> tmppub = new ArrayList<DR_Pub>();
+ tmppub.add( new DR_Pub( dcaeLocations.getCentralLocation())
+ .setRandomUserName()
+ .setRandomPassword());
+ req.setPubs(tmppub);
+ req.setSubs(null);
+ Feed fnew = updateFeed( req, err );
+ if ( ! err.is2xx()) {
+ return req;
+ }
+ fnew.setStatus(DmaapObject_Status.DELETED);
+ feeds.put( fnew.getFeedId(), fnew );
+ return null;
+ }
+
+
+ }
+
+
+ /*
+ * sync will retrieve current config from DR and add it to the DB
+ * when hard = true, then first git rid of current DR provisioning data (from the DB)
+ */
+ public void sync( boolean hard, ApiError err ) {
+
+ if ( hard ) {
+
+ ArrayList<Feed> flist = new ArrayList<Feed>(this.getAllFeeds());
+ for ( Iterator<Feed> it = flist.iterator(); it.hasNext(); ) {
+ Feed f = it.next();
+
+ @SuppressWarnings("unused")
+ Feed old = removeFeed( f, err, false );
+ if (! err.is2xx()) {
+ return;
+ }
+ }
+ }
+
+ DrProvConnection prov = new DrProvConnection();
+ prov.makeDumpConnection();
+ String resp = prov.doGetDump( err );
+ if (! err.is2xx()) {
+ return;
+ }
+ logger.debug("sync: resp from DR is: " + resp);
+
+ JSONParser parser = new JSONParser();
+ JSONObject jsonObj;
+ try {
+ jsonObj = (JSONObject) parser.parse( resp );
+ } catch ( ParseException pe ) {
+ logger.error( "Error parsing provisioning data: " + resp );
+ err.setCode(500);
+ return;
+ }
+
+ int i;
+
+ JSONArray feedsArray = (JSONArray) jsonObj.get( "feeds");
+ for( i = 0; i < feedsArray.size(); i++ ) {
+ JSONObject entry = (JSONObject) feedsArray.get(i);
+ Feed fnew = new Feed( entry.toJSONString() );
+
+ logger.info( "fnew status is:" + fnew.getStatus() );
+ if ( ! fnew.isStatusValid()) {
+ err.setCode(500);
+ err.setMessage( "Unexpected response from DR backend" );
+ err.setFields("response");
+ return;
+ }
+
+ if ( ! savePubs( fnew ) ) {
+ err.setCode(Status.BAD_REQUEST.getStatusCode());
+ err.setMessage("Unable to save Pub or Sub objects");
+ return;
+ }
+ fnew.setFormatUuid(fnew.getFormatUuid());
+ fnew.setLastMod();
+ feeds.put( fnew.getFeedId(), fnew );
+
+ }
+
+ JSONArray subArray = (JSONArray) jsonObj.get( "subscriptions");
+ for( i = 0; i < subArray.size(); i++ ) {
+ JSONObject entry = (JSONObject) subArray.get(i);
+ DR_Sub snew = new DR_Sub( entry.toJSONString() );
+
+ logger.info( "snew status is:" + snew.getStatus() );
+ if ( ! snew.isStatusValid()) {
+ err.setCode(500);
+ err.setMessage( "Unexpected response from DR backend" );
+ err.setFields("response");
+ return;
+ }
+
+ dr_subs.put( snew.getSubId(), snew );
+
+ }
+ err.setCode(200);
+ return;
+
+ }
+
+ private String simulateResp( Feed f, String action ){
+ String server = "localhost";
+ String feedid;
+ if ( action.equals( "POST" ) ) {
+ RandomInteger ran = new RandomInteger(10000);
+ feedid = Integer.toString( ran.next() );
+ } else if ( action.equals( "PUT" ) ) {
+ feedid = f.getFeedId();
+ } else {
+ feedid = "99";
+ }
+ String ret = String.format(
+"{\"suspend\":false,\"groupid\":0,\"description\":\"%s\",\"version\":\"1.0\",\"authorization\":",
+ f.getFeedDescription() );
+
+ String endpoints = "{\"endpoint_addrs\":[],\"classification\":\"unclassified\",\"endpoint_ids\":[";
+ String sep = "";
+ for( DR_Pub pub: f.getPubs()) {
+ endpoints += String.format( "%s{\"password\":\"%s\",\"id\":\"%s\"}",
+ sep, pub.getUserpwd(), pub.getUsername() );
+ sep = ",";
+
+ }
+ endpoints += "]},";
+ ret += endpoints;
+
+ ret += String.format(
+ "\"name\":\"%s\",\"business_description\":\"\",\"publisher\":\"sim\",\"links\":{\"subscribe\":\"https://%s/subscribe/%s\",\"log\":\"https://%s/feedlog/%s\",\"publish\":\"https://%s/publish/%s\",\"self\":\"https://%s/feed/%s\"}}",
+
+ f.getFeedName(),
+ server, feedid,
+ server, feedid,
+ server, feedid,
+ server, feedid
+ );
+ logger.info( "simulateResp ret=" + ret );
+ return ret;
+ }
+ private String simulateDelResp( Feed f ){
+ String server = "localhost";
+ String feedid = f.getFeedId();
+ String ret = String.format(
+"{\"suspend\":true,\"groupid\":0,\"description\":\"%s\",\"version\":\"1.0\",\"authorization\":{\"endpoint_addrs\":[],\"classification\":\"unclassified\",\"endpoint_ids\":[{\"password\":\"topSecret123\",\"id\":\"sim\"}]},\"name\":\"%s\",\"business_description\":\"\",\"publisher\":\"sim\",\"links\":{\"subscribe\":\"https://%s/subscribe/%s\",\"log\":\"https://%s/feedlog/%s\",\"publish\":\"https://%s/publish/%s\",\"self\":\"https://%s/feed/%s\"}}",
+ f.getFeedDescription(),
+ f.getFeedName(),
+ server, feedid,
+ server, feedid,
+ server, feedid,
+ server, feedid
+
+ );
+ return ret;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClientService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClientService.java
new file mode 100644
index 0000000..bcf5408
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClientService.java
@@ -0,0 +1,234 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.aaf.AafServiceFactory;
+import org.onap.dmaap.dbcapi.client.MrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import javax.ws.rs.core.Response.Status;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class MR_ClientService extends BaseLoggingClass {
+
+ private static final String MR_CLIENT_ID = "mrClientId";
+ private int deleteLevel;
+ private Map<String, MR_Client> mr_clients = DatabaseClass.getMr_clients();
+ private Map<String, MR_Cluster> clusters = DatabaseClass.getMr_clusters();
+ private Map<String, DcaeLocation> locations = DatabaseClass.getDcaeLocations();
+ private DmaapService dmaap = new DmaapService();
+ private AafPermissionService aafPermissionService =
+ new AafPermissionService(new AafServiceFactory().initAafService(ServiceType.AAF_TopicMgr), dmaap);
+ private String centralCname;
+
+ public MR_ClientService() {
+ DmaapConfig p = (DmaapConfig) DmaapConfig.getConfig();
+
+ centralCname = p.getProperty("MR.CentralCname", "MRcname.not.set");
+ deleteLevel = Integer.valueOf(p.getProperty("MR.ClientDeleteLevel", "0"));
+ }
+
+ public List<MR_Client> getAllMr_Clients() {
+ return new ArrayList<>(mr_clients.values());
+ }
+
+ List<MR_Client> getAllMrClients(String fqtn) {
+ ArrayList<MR_Client> results = new ArrayList<>();
+ for (Map.Entry<String, MR_Client> entry : mr_clients.entrySet()) {
+ MR_Client client = entry.getValue();
+ if (fqtn.equals(client.getFqtn())) {
+ results.add(client);
+ }
+ }
+ return results;
+ }
+
+ List<MR_Client> getClientsByLocation(String location) {
+ List<MR_Client> results = new ArrayList<>();
+ for (Map.Entry<String, MR_Client> entry : mr_clients.entrySet()) {
+ MR_Client client = entry.getValue();
+ if (location.equals(client.getDcaeLocationName())) {
+ 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(MR_CLIENT_ID);
+ apiError.setMessage(MR_CLIENT_ID + " " + 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.info("Client dcaeLocation that doesn't exist or not specified");
+ return null;
+ }
+ // original style: clients specified Role. This has precedence for backwards
+ // compatibility.
+ // ONAP style: clients specify Identity to be assigned to generated Role
+ String role = client.getClientRole();
+ if (role != null) {
+ updateApiError(err, aafPermissionService.grantClientRolePerms(client));
+ } else if (client.hasClientIdentity()) {
+ if (client.isSubscriber()) {
+ role = topic.getSubscriberRole();
+ updateApiError(err, aafPermissionService.assignClientToRole(client, role));
+ }
+ if (client.isPublisher()) {
+ role = topic.getPublisherRole();
+ updateApiError(err, aafPermissionService.assignClientToRole(client, role));
+ }
+ }
+ if (!client.isStatusValid()) {
+ return null;
+ }
+ String centralFqdn = null;
+ DcaeLocation candidate = locations.get(client.getDcaeLocationName());
+
+ MR_Cluster cluster = clusters.get(client.getDcaeLocationName());
+ if (cluster != null && candidate != null) {
+ if (candidate.isCentral() && !topic.getReplicationCase().involvesFQDN()) {
+ centralFqdn = centralCname;
+ }
+ client.setTopicURL(cluster.genTopicURL(centralFqdn, client.getFqtn()));
+ if (centralFqdn == null) {
+ client.setStatus(addTopicToCluster(cluster, topic, err));
+ if (!err.is2xx() && err.getCode() != 409) {
+ topic.setFqtn(err.getMessage());
+ return null;
+ }
+
+ } else {
+ MR_ClusterService clusters = new MR_ClusterService();
+ // MM should only exist for edge-to-central
+ // we use a cname for the central target (default resiliency with no replicationGroup set)
+ // but still need to provision topics on all central MRs
+ for (MR_Cluster central : clusters.getCentralClusters()) {
+ client.setStatus(addTopicToCluster(central, topic, err));
+ if (!err.is2xx() && err.getCode() != 409) {
+ topic.setFqtn(err.getMessage());
+ return null;
+ }
+ }
+ }
+
+ } else {
+ logger.warn("Client references a dcaeLocation that doesn't exist:" + client.getDcaeLocationName());
+ client.setStatus(DmaapObject_Status.STAGED);
+ }
+
+ mr_clients.put(client.getMrClientId(), client);
+
+ err.setCode(200);
+
+ return client;
+ }
+
+ private DmaapObject_Status addTopicToCluster(MR_Cluster cluster, Topic topic, ApiError err) {
+
+ MrProvConnection prov = new MrProvConnection();
+ logger.info("POST topic " + topic.getFqtn() + " to cluster " + cluster.getFqdn() + " in loc " + cluster.getDcaeLocationName());
+ if (prov.makeTopicConnection(cluster)) {
+ prov.doPostTopic(topic, err);
+ logger.info("response code: " + err.getCode());
+ if (err.is2xx() || err.getCode() == 409) {
+ return DmaapObject_Status.VALID;
+ }
+ }
+ return DmaapObject_Status.INVALID;
+ }
+
+ 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(MR_CLIENT_ID);
+ apiError.setMessage("mrClientId " + client.getMrClientId() + " not found");
+ } else {
+ apiError.setCode(200);
+ }
+ mr_clients.put(client.getMrClientId(), client);
+ return client;
+ }
+
+ public void removeMr_Client(String key, boolean updateTopicView, ApiError apiError) {
+ MR_Client client = mr_clients.get(key);
+ if (client == null) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ apiError.setFields(MR_CLIENT_ID);
+ apiError.setMessage("mrClientId " + key + " not found");
+ return;
+ } else {
+ apiError.setCode(200);
+ }
+
+ if (updateTopicView) {
+
+ TopicService topics = new TopicService();
+
+ Topic t = topics.getTopic(client.getFqtn(), apiError);
+ if (t != null) {
+ List<MR_Client> tc = t.getClients();
+ for (MR_Client c : tc) {
+ if (c.getMrClientId().equals(client.getMrClientId())) {
+ tc.remove(c);
+ break;
+ }
+ }
+ t.setClients(tc);
+ topics.updateTopic(t, apiError);
+ }
+
+ }
+
+ // remove from DB
+ if (deleteLevel >= 1) {
+ mr_clients.remove(key);
+ }
+ }
+
+ private void updateApiError(ApiError err, ApiError permissionServiceError) {
+ err.setCode(permissionServiceError.getCode());
+ err.setMessage(permissionServiceError.getMessage());
+ err.setFields(permissionServiceError.getFields());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClusterService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClusterService.java
new file mode 100644
index 0000000..db6389e
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MR_ClusterService.java
@@ -0,0 +1,205 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.dmaap.dbcapi.client.MrProvConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.service.DcaeLocationService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+public class MR_ClusterService extends BaseLoggingClass {
+
+ private Map<String, MR_Cluster> mr_clusters = DatabaseClass.getMr_clusters();
+ private boolean multiSite;
+
+ public MR_ClusterService() {
+ logger.info( "new ClusterService");
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ multiSite = "true".equalsIgnoreCase(p.getProperty("MR.multisite", "true"));
+
+ }
+
+ public Map<String, MR_Cluster> getMR_Clusters() {
+ return mr_clusters;
+ }
+
+ public List<MR_Cluster> getAllMr_Clusters() {
+ return new ArrayList<MR_Cluster>(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 getMr_ClusterByLoc( String loc ) {
+ return mr_clusters.get( loc );
+ }
+
+ public List<MR_Cluster> getCentralClusters() {
+ DcaeLocationService locations = new DcaeLocationService();
+ List<MR_Cluster> result = new ArrayList<MR_Cluster>();
+ for( MR_Cluster c: mr_clusters.values() ) {
+ try {
+ if ( locations.getDcaeLocation(c.getDcaeLocationName()).isCentral() ) {
+ result.add(c);
+ }
+ } catch ( NullPointerException npe ) {
+ logger.warn( "Failed test isCentral for location:" + c.getDcaeLocationName() );
+ }
+ }
+ return result;
+ }
+
+ // builds the set of unique cluster groups
+ public Set<String> getGroups() {
+ Set<String> result = new HashSet<String>();
+ for( MR_Cluster c: mr_clusters.values() ) {
+ try {
+ result.add(c.getReplicationGroup());
+ } catch ( NullPointerException npe ) {
+ logger.warn( "Failed to add Group for cluster:" + c.getDcaeLocationName() );
+ }
+ }
+ return result;
+ }
+
+
+ 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( addTopicsToCluster( cluster, apiError ) );
+ mr_clusters.put( cluster.getDcaeLocationName(), cluster );
+ DcaeLocationService svc = new DcaeLocationService();
+ DcaeLocation loc = svc.getDcaeLocation( cluster.getDcaeLocationName() );
+ if ( loc != null && loc.isCentral() && multiSite ) {
+ 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();
+ cluster.setStatus( addTopicsToCluster( cluster, apiError ) );
+ mr_clusters.put( cluster.getDcaeLocationName(), cluster );
+ DcaeLocationService svc = new DcaeLocationService();
+ DcaeLocation loc = svc.getDcaeLocation( cluster.getDcaeLocationName() );
+ if ( loc == null ) {
+ logger.error( "DcaeLocation not found for cluster in " + cluster.getDcaeLocationName() );
+ cluster.setLastMod();
+ cluster.setStatus(DmaapObject_Status.INVALID);
+ mr_clusters.put( cluster.getDcaeLocationName(), cluster );
+ } else if ( loc.isCentral() && multiSite ) {
+ 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);
+ }
+
+ private DmaapObject_Status addTopicsToCluster( MR_Cluster cluster, ApiError err ){
+
+ TopicService ts = new TopicService();
+ MrProvConnection prov = new MrProvConnection();
+ List<Topic> topics = ts.getAllTopicsWithoutClients();
+ for( Topic topic: topics ) {
+ logger.info( "POST topic " + topic.getFqtn() + " to cluster " + cluster.getFqdn() + " in loc " + cluster.getDcaeLocationName());
+ if ( prov.makeTopicConnection(cluster)) {
+ String resp = prov.doPostTopic(topic, err);
+ logger.info( "response code: " + err.getCode() );
+ if ( ! err.is2xx() && ! (err.getCode() == 409) ) {
+ return DmaapObject_Status.INVALID;
+ }
+ }
+ }
+
+ return DmaapObject_Status.VALID;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MirrorMakerService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MirrorMakerService.java
new file mode 100644
index 0000000..7c4b2ce
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/MirrorMakerService.java
@@ -0,0 +1,255 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+
+
+
+
+
+
+
+//import org.openecomp.dmaapbc.aaf.AndrewDecryptor;
+import org.onap.dmaap.dbcapi.aaf.AafDecrypt;
+import org.onap.dmaap.dbcapi.client.MrTopicConnection;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.MirrorMaker;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.RandomInteger;
+
+public class MirrorMakerService extends BaseLoggingClass {
+
+ private Map<String, MirrorMaker> mirrors = DatabaseClass.getMirrorMakers();
+ private static MrTopicConnection prov;
+ private static AafDecrypt decryptor;
+
+ static final String PROV_USER_PROPERTY = "MM.ProvUserMechId";
+ static final String PROV_PWD_PROPERTY = "MM.ProvUserPwd";
+ static final String PROV_PWD_DEFAULT = "pwdNotSet";
+ static final String SOURCE_REPLICATION_PORT_PROPERTY = "MR.SourceReplicationPort";
+ static final String SOURCE_REPLICATION_PORT_DEFAULT = "9092";
+ static final String TARGET_REPLICATION_PORT_PROPERTY = "MR.TargetReplicationPort";
+ static final String TARGET_REPLICATION_PORT_DEFAULT = "2181";
+
+ private static String provUser;
+ private static String provUserPwd;
+ private static String defaultProducerPort;
+ private static String defaultConsumerPort;
+ private static String centralFqdn;
+ private int maxTopicsPerMM;
+ private boolean mmPerMR;
+
+ public MirrorMakerService() {
+ super();
+ decryptor = new AafDecrypt();
+ DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
+ provUser = p.getProperty(PROV_USER_PROPERTY);
+ provUserPwd = decryptor.decrypt(p.getProperty( PROV_PWD_PROPERTY, PROV_PWD_DEFAULT ));
+ defaultProducerPort = p.getProperty( SOURCE_REPLICATION_PORT_PROPERTY, SOURCE_REPLICATION_PORT_DEFAULT );
+ defaultConsumerPort = p.getProperty( TARGET_REPLICATION_PORT_PROPERTY, TARGET_REPLICATION_PORT_DEFAULT );
+ centralFqdn = p.getProperty("MR.CentralCname", "notSet");
+ maxTopicsPerMM = Integer.valueOf( p.getProperty( "MaxTopicsPerMM", "5"));
+ mmPerMR = "true".equalsIgnoreCase(p.getProperty("MirrorMakerPerMR", "true"));
+ }
+
+ // 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");
+
+ prov = new MrTopicConnection( provUser, provUserPwd );
+
+ DmaapService dmaap = new DmaapService();
+ MR_ClusterService clusters = new MR_ClusterService();
+ MR_Cluster target_cluster = null;
+ String override = null;
+
+ if ( ! mmPerMR ) {
+ // in ECOMP, MM Agent is only deployed at central, so this case is needed for backwards compatibility
+ // we use a cname for the central MR cluster that is active, and provision on agent topic on that target
+ // but only send 1 message so MM Agents can read it relying on kafka delivery
+ for( MR_Cluster cluster: clusters.getCentralClusters() ) {
+
+ target_cluster = cluster;
+ override = centralFqdn;
+ // we only want to send one message even if there are multiple central clusters
+ break;
+
+ }
+ } else {
+ // In ONAP deployment architecture, the MM Agent is deployed with each target MR
+ target_cluster = clusters.getMr_ClusterByFQDN(mm.getTargetCluster());
+ override = null;
+ }
+
+ prov.makeTopicConnection(target_cluster, dmaap.getBridgeAdminFqtn(), override );
+ ApiError resp = prov.doPostMessage(mm.createMirrorMaker( defaultConsumerPort, defaultProducerPort ));
+ if ( ! resp.is2xx() ) {
+
+ errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR, "create MM", Integer.toString(resp.getCode()), resp.getMessage());
+ mm.setStatus(DmaapObject_Status.INVALID);
+ } else {
+ prov.makeTopicConnection(target_cluster, dmaap.getBridgeAdminFqtn(), override );
+ resp = prov.doPostMessage(mm.getWhitelistUpdateJSON());
+ if ( ! resp.is2xx()) {
+ errorLogger.error( DmaapbcLogMessageEnum.MM_PUBLISH_ERROR,"MR Bridge", Integer.toString(resp.getCode()), resp.getMessage());
+ mm.setStatus(DmaapObject_Status.INVALID);
+ } else {
+ mm.setStatus(DmaapObject_Status.VALID);
+ }
+ }
+
+ mm.setLastMod();
+ return mirrors.put( mm.getMmName(), mm);
+ }
+ public MirrorMaker getMirrorMaker( String part1, String part2, int index ) {
+ String targetPart;
+
+ // original mm names did not have any index, so leave off index 0 for
+ // backwards compatibility
+ if ( index == 0 ) {
+ targetPart = part2;
+ } else {
+ targetPart = part2 + "_" + index;
+ }
+ logger.info( "getMirrorMaker using " + part1 + " and " + targetPart );
+ return mirrors.get(MirrorMaker.genKey(part1, targetPart));
+ }
+ 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 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<String> getAllMirrorMakers() {
+ List<String> ret = new ArrayList<String>();
+ for( String key: mirrors.keySet()) {
+ ret.add( key );
+ }
+
+ return ret;
+ }
+
+ public MirrorMaker findNextMM( String source, String target, String fqtn ) {
+ int i = 0;
+ MirrorMaker mm = null;
+ while( mm == null ) {
+
+ mm = this.getMirrorMaker( source, target, i);
+ if ( mm == null ) {
+ mm = new MirrorMaker(source, target, i);
+ }
+ if ( mm.getTopics().contains(fqtn) ) {
+ break;
+ }
+ if ( mm.getTopicCount() >= maxTopicsPerMM ) {
+ logger.info( "getNextMM: MM " + mm.getMmName() + " has " + mm.getTopicCount() + " topics. Moving to next MM");
+ i++;
+ mm = null;
+ }
+ }
+
+
+ return mm;
+ }
+
+ public MirrorMaker splitMM( MirrorMaker orig ) {
+
+ String source = orig.getSourceCluster();
+ String target = orig.getTargetCluster();
+
+
+ ArrayList<String> whitelist = orig.getTopics();
+ while( whitelist.size() > maxTopicsPerMM ) {
+
+ int last = whitelist.size() - 1;
+ String topic = whitelist.get(last);
+ whitelist.remove(last);
+ MirrorMaker mm = this.findNextMM( source, target, "aValueThatShouldNotMatchAnything" );
+ mm.addTopic(topic);
+ this.updateMirrorMaker(mm);
+ }
+
+ orig.setTopics(whitelist);
+
+ return orig;
+
+ }
+
+ public static String getProvUser() {
+ return provUser;
+ }
+
+ public static void setProvUser(String provUser) {
+ MirrorMakerService.provUser = provUser;
+ }
+
+ public static String getProvUserPwd() {
+ return provUserPwd;
+ }
+
+ public static void setProvUserPwd(String provUserPwd) {
+ MirrorMakerService.provUserPwd = provUserPwd;
+ }
+
+ public static String getDefaultProducerPort() {
+ return defaultProducerPort;
+ }
+
+ public static void setDefaultProducerPort(String defaultProducerPort) {
+ MirrorMakerService.defaultProducerPort = defaultProducerPort;
+ }
+
+ public static String getDefaultConsumerPort() {
+ return defaultConsumerPort;
+ }
+
+ public static void setDefaultConsumerPort(String defaultConsumerPort) {
+ MirrorMakerService.defaultConsumerPort = defaultConsumerPort;
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java
new file mode 100644
index 0000000..009b745
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java
@@ -0,0 +1,526 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.aaf.AafServiceFactory;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.logging.DmaapbcLogMessageEnum;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.MirrorMaker;
+import org.onap.dmaap.dbcapi.model.ReplicationType;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.Fqdn;
+import org.onap.dmaap.dbcapi.util.Graph;
+
+import javax.ws.rs.core.Response.Status;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class TopicService extends BaseLoggingClass {
+
+
+ // REF: https://wiki.web.att.com/pages/viewpage.action?pageId=519703122
+ private static String defaultGlobalMrHost;
+
+ private Map<String, Topic> mr_topics;
+
+ private static DmaapService dmaapSvc = new DmaapService();
+ private MR_ClientService clientService;
+ private MR_ClusterService clusters;
+ private DcaeLocationService locations;
+ private MirrorMakerService bridge;
+ private AafTopicSetupService aafTopicSetupService;
+
+ private static String centralCname;
+ private boolean strictGraph = true;
+ private boolean mmPerMR;
+
+
+ public TopicService() {
+ this(DatabaseClass.getTopics(), new MR_ClientService(), (DmaapConfig) DmaapConfig.getConfig(),
+ new MR_ClusterService(), new DcaeLocationService(), new MirrorMakerService(),
+ new AafTopicSetupService(
+ new AafServiceFactory().initAafService(ServiceType.AAF_TopicMgr),
+ dmaapSvc, (DmaapConfig) DmaapConfig.getConfig()));
+ }
+
+ TopicService(Map<String, Topic> mr_topics, MR_ClientService clientService, DmaapConfig p,
+ MR_ClusterService clusters, DcaeLocationService locations, MirrorMakerService bridge, AafTopicSetupService aafTopicSetupService) {
+ this.mr_topics = mr_topics;
+ this.clientService = clientService;
+ defaultGlobalMrHost = p.getProperty("MR.globalHost", "global.host.not.set");
+ centralCname = p.getProperty("MR.CentralCname");
+ String unit_test = p.getProperty("UnitTest", "No");
+ if ("Yes".equals(unit_test)) {
+ strictGraph = false;
+ }
+ mmPerMR = "true".equalsIgnoreCase(p.getProperty("MirrorMakerPerMR", "true"));
+ logger.info("TopicService properties: CentralCname=" + centralCname +
+ " defaultGlobarlMrHost=" + defaultGlobalMrHost +
+ " mmPerMR=" + mmPerMR);
+ this.clusters = clusters;
+ this.locations = locations;
+ this.bridge = bridge;
+ this.aafTopicSetupService = aafTopicSetupService;
+ }
+
+ public Map<String, Topic> getTopics() {
+ return mr_topics;
+ }
+
+ public List<Topic> getAllTopics() {
+ return getAllTopics(true);
+ }
+
+ public List<Topic> getAllTopicsWithoutClients() {
+ return getAllTopics(false);
+ }
+
+ private List<Topic> getAllTopics(Boolean withClients) {
+ ArrayList<Topic> topics = new ArrayList<>(mr_topics.values());
+ if (withClients) {
+ 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, Boolean useExisting) {
+ logger.info("Entry: addTopic");
+ logger.info("Topic name=" + topic.getTopicName() + " fqtnStyle=" + topic.getFqtnStyle());
+ String nFqtn = topic.genFqtn();
+ logger.info("FQTN=" + nFqtn);
+ Topic pTopic = getTopic(nFqtn, err);
+ if (pTopic != null) {
+ String t = "topic already exists: " + nFqtn;
+ logger.info(t);
+ if (useExisting) {
+ err.setCode(Status.OK.getStatusCode());
+ return pTopic;
+ }
+ err.setMessage(t);
+ err.setFields("fqtn");
+ err.setCode(Status.CONFLICT.getStatusCode());
+ return null;
+ }
+ err.reset(); // err filled with NOT_FOUND is expected case, but don't want to litter...
+
+ topic.setFqtn(nFqtn);
+
+ ApiError topicSetupError = aafTopicSetupService.aafTopicSetup(topic);
+ updateApiError(err, topicSetupError);
+ if (err.getCode() >= 400) {
+ return null;
+ }
+
+ if (topic.getReplicationCase().involvesGlobal()) {
+ if (topic.getGlobalMrURL() == null) {
+ topic.setGlobalMrURL(defaultGlobalMrHost);
+ }
+ if (!Fqdn.isValid(topic.getGlobalMrURL())) {
+ logger.error("GlobalMR FQDN not valid: " + topic.getGlobalMrURL());
+ topic.setStatus(DmaapObject_Status.INVALID);
+ err.setCode(500);
+ err.setMessage("Value is not a valid FQDN:" + topic.getGlobalMrURL());
+ err.setFields("globalMrURL");
+
+ return null;
+ }
+ }
+
+
+ if (topic.getNumClients() > 0) {
+ ArrayList<MR_Client> clients = new ArrayList<MR_Client>(topic.getClients());
+
+
+ ArrayList<MR_Client> clients2 = new ArrayList<MR_Client>();
+ for (Iterator<MR_Client> 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());
+ nc.setClientIdentity(c.getClientIdentity());
+ 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);
+ }
+
+ Topic ntopic = checkForBridge(topic, err);
+ if (ntopic == null) {
+ topic.setStatus(DmaapObject_Status.INVALID);
+ if (!err.is2xx()) {
+ return null;
+ }
+ }
+
+
+ mr_topics.put(nFqtn, ntopic);
+
+ err.setCode(Status.OK.getStatusCode());
+ return ntopic;
+ }
+
+
+ public Topic updateTopic(Topic topic, ApiError err) {
+ logger.info("updateTopic: entry");
+ logger.info("updateTopic: topic=" + topic);
+ logger.info("updateTopic: fqtn=" + topic.getFqtn());
+ if (topic.getFqtn().isEmpty()) {
+ return null;
+ }
+ logger.info("updateTopic: call checkForBridge");
+ Topic ntopic = checkForBridge(topic, err);
+ if (ntopic == null) {
+ topic.setStatus(DmaapObject_Status.INVALID);
+ if (!err.is2xx()) {
+ return null;
+ }
+ }
+ if (ntopic != null) {
+ logger.info("updateTopic: call put");
+ mr_topics.put(ntopic.getFqtn(), ntopic);
+ }
+ err.setCode(Status.OK.getStatusCode());
+ return ntopic;
+ }
+
+ public Topic removeTopic(String pubId, ApiError apiError) {
+ Topic topic = mr_topics.get(pubId);
+ if (topic == null) {
+ apiError.setCode(Status.NOT_FOUND.getStatusCode());
+ apiError.setMessage("Topic " + pubId + " does not exist");
+ apiError.setFields("fqtn");
+ return null;
+ }
+
+ ApiError topicSetupError = aafTopicSetupService.aafTopicCleanup(topic);
+ updateApiError(apiError, topicSetupError);
+ if (apiError.getCode() >= 400) {
+ return null;
+ }
+
+ ArrayList<MR_Client> clients = new ArrayList<MR_Client>(clientService.getAllMrClients(pubId));
+ for (Iterator<MR_Client> it = clients.iterator(); it.hasNext(); ) {
+ MR_Client c = it.next();
+ clientService.removeMr_Client(c.getMrClientId(), false, apiError);
+ if (!apiError.is2xx()) {
+ 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().init();
+ bridgeAdminTopic.setTopicName(dmaapSvc.getBridgeAdminFqtn());
+ bridgeAdminTopic.setTopicDescription("RESERVED topic for MirroMaker Provisioning");
+ bridgeAdminTopic.setOwner("DBC");
+
+ ArrayList<MR_Client> clients = new ArrayList<MR_Client>();
+ 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, true);
+
+ if (err.is2xx() || err.getCode() == 409) {
+ err.setCode(200);
+ return err;
+ }
+
+ errorLogger.error(DmaapbcLogMessageEnum.TOPIC_CREATE_ERROR, bridgeAdminTopic.getFqtn(), Integer.toString(err.getCode()), err.getFields(), err.getMessage());
+ return err;
+ }
+
+
+ public Topic checkForBridge(Topic topic, ApiError err) {
+ logger.info("checkForBridge: entry");
+ logger.info("fqtn=" + topic.getFqtn() + " replicatonType=" + topic.getReplicationCase());
+ if (topic.getReplicationCase() == ReplicationType.REPLICATION_NONE) {
+ topic.setStatus(DmaapObject_Status.VALID);
+ return topic;
+ }
+
+ boolean anythingWrong = false;
+
+ Set<String> groups = clusters.getGroups();
+ for (String g : groups) {
+ logger.info("buildBridge for " + topic.getFqtn() + " on group" + g);
+ anythingWrong |= buildBridge(topic, err, g);
+ }
+ if (anythingWrong) {
+ topic.setStatus(DmaapObject_Status.INVALID);
+ if (!err.is2xx()) {
+ return null;
+ }
+ } else {
+ topic.setStatus(DmaapObject_Status.VALID);
+ }
+ return topic;
+ }
+
+ private boolean buildBridge(Topic topic, ApiError err, String group) {
+ logger.info("buildBridge: entry");
+ boolean anythingWrong = false;
+ Graph graph;
+ logger.info("buildBridge: strictGraph=" + strictGraph);
+ if (group == null || group.isEmpty()) {
+ graph = new Graph(topic.getClients(), strictGraph);
+ } else {
+ graph = new Graph(topic.getClients(), strictGraph, group);
+ }
+ logger.info("buildBridge: graph=" + graph);
+ MR_Cluster groupCentralCluster = null;
+
+
+ if (graph.isEmpty()) {
+ logger.info("buildBridge: graph is empty. return false");
+ return false;
+ } else if (group == null && topic.getReplicationCase().involvesFQDN()) {
+ logger.info("buildBridge: group is null and replicationCaseInvolvesFQDN. return false");
+ return false;
+ } else if (!graph.hasCentral()) {
+ logger.warn("Topic " + topic.getFqtn() + " wants to be " + topic.getReplicationCase() + " but has no central clients");
+ return true;
+ } else {
+ groupCentralCluster = clusters.getMr_ClusterByLoc(graph.getCentralLoc());
+ }
+ Collection<String> clientLocations = graph.getKeys();
+ for (String loc : clientLocations) {
+ logger.info("loc=" + loc);
+ DcaeLocation location = locations.getDcaeLocation(loc);
+ MR_Cluster cluster = clusters.getMr_ClusterByLoc(loc);
+ logger.info("cluster=" + cluster + " at " + cluster.getDcaeLocationName());
+ logger.info("location.isCentral()=" + location.isCentral() + " getCentralLoc()=" + graph.getCentralLoc());
+
+
+ String source = null;
+ String target = null;
+
+ /*
+ * Provision Edge to Central bridges...
+ */
+ if (!location.isCentral() && !graph.getCentralLoc().equals(cluster.getDcaeLocationName())) {
+ switch (topic.getReplicationCase()) {
+ case REPLICATION_EDGE_TO_CENTRAL:
+ case REPLICATION_EDGE_TO_CENTRAL_TO_GLOBAL: // NOTE: this is for E2C portion only
+ source = cluster.getFqdn();
+ target = (mmPerMR) ? groupCentralCluster.getFqdn() : centralCname;
+ logger.info("REPLICATION_EDGE_TO_CENTRAL: source=" + source + " target=" + target);
+ break;
+ case REPLICATION_CENTRAL_TO_EDGE:
+ case REPLICATION_GLOBAL_TO_CENTRAL_TO_EDGE: // NOTE: this is for C2E portion only
+ source = (mmPerMR) ? groupCentralCluster.getFqdn() : centralCname;
+ target = cluster.getFqdn();
+ break;
+ case REPLICATION_CENTRAL_TO_GLOBAL:
+ case REPLICATION_GLOBAL_TO_CENTRAL:
+ case REPLICATION_FQDN_TO_GLOBAL:
+ case REPLICATION_GLOBAL_TO_FQDN:
+ break;
+
+ case REPLICATION_EDGE_TO_FQDN:
+ case REPLICATION_EDGE_TO_FQDN_TO_GLOBAL: // NOTE: this is for E2C portion only
+ source = cluster.getFqdn();
+ target = groupCentralCluster.getFqdn();
+ break;
+ case REPLICATION_FQDN_TO_EDGE:
+ case REPLICATION_GLOBAL_TO_FQDN_TO_EDGE: // NOTE: this is for F2E portion only
+ source = groupCentralCluster.getFqdn();
+ target = cluster.getFqdn();
+ break;
+
+ default:
+ logger.error("Unexpected value for ReplicationType (" + topic.getReplicationCase() + ") for topic " + topic.getFqtn());
+ anythingWrong = true;
+ err.setCode(400);
+ err.setFields("topic=" + topic.genFqtn() + " replicationCase="
+ + topic.getReplicationCase());
+ err.setMessage("Unexpected value for ReplicationType");
+ continue;
+ }
+
+ } else if (location.isCentral() && graph.getCentralLoc().equals(cluster.getDcaeLocationName())) {
+ /*
+ * Provision Central to Global bridges
+ */
+ switch (topic.getReplicationCase()) {
+
+ case REPLICATION_CENTRAL_TO_GLOBAL:
+ case REPLICATION_EDGE_TO_CENTRAL_TO_GLOBAL:
+ source = centralCname;
+ target = topic.getGlobalMrURL();
+ break;
+ case REPLICATION_GLOBAL_TO_CENTRAL:
+ case REPLICATION_GLOBAL_TO_CENTRAL_TO_EDGE: // NOTE: this is for G2C portion only
+ source = topic.getGlobalMrURL();
+ target = centralCname;
+ break;
+
+ case REPLICATION_EDGE_TO_FQDN_TO_GLOBAL: // NOTE: this is for E2F portion only
+ source = groupCentralCluster.getFqdn();
+ target = topic.getGlobalMrURL();
+ break;
+
+ case REPLICATION_FQDN_TO_GLOBAL:
+ source = groupCentralCluster.getFqdn();
+ target = topic.getGlobalMrURL();
+ break;
+
+ case REPLICATION_GLOBAL_TO_FQDN:
+ case REPLICATION_GLOBAL_TO_FQDN_TO_EDGE: // NOTE: this is for G2F portion only
+ source = topic.getGlobalMrURL();
+ target = groupCentralCluster.getFqdn();
+ break;
+
+ case REPLICATION_FQDN_TO_EDGE:
+ case REPLICATION_EDGE_TO_FQDN:
+ case REPLICATION_EDGE_TO_CENTRAL:
+ case REPLICATION_CENTRAL_TO_EDGE:
+ break;
+ default:
+ logger.error("Unexpected value for ReplicationType (" + topic.getReplicationCase() + ") for topic " + topic.getFqtn());
+ anythingWrong = true;
+ err.setCode(400);
+ err.setFields("topic=" + topic.genFqtn() + " replicationCase="
+ + topic.getReplicationCase());
+ err.setMessage("Unexpected value for ReplicationType");
+ continue;
+ }
+ } else {
+ logger.warn("dcaeLocation " + loc + " is neither Edge nor Central so no mmagent provisioning was done");
+ anythingWrong = true;
+ continue;
+ }
+ if (source != null && target != null) {
+ try {
+ logger.info("Create a MM from " + source + " to " + target);
+ MirrorMaker mm = bridge.findNextMM(source, target, topic.getFqtn());
+ 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;
+ }
+ }
+
+
+ }
+ return anythingWrong;
+
+ }
+
+
+ /*
+ * Prior to 1707, we only supported EDGE_TO_CENTRAL replication.
+ * This was determined automatically based on presence of edge publishers and central subscribers.
+ * The following method is a modification of that original logic, to preserve some backwards compatibility,
+ * i.e. to be used when no ReplicationType is specified.
+ */
+
+ public ReplicationType reviewTopic(Topic topic) {
+
+
+ if (topic.getNumClients() > 1) {
+ Graph graph = new Graph(topic.getClients(), false);
+
+ String centralFqdn = new String();
+ if (graph.hasCentral()) {
+ DmaapConfig p = (DmaapConfig) DmaapConfig.getConfig();
+ centralFqdn = p.getProperty("MR.CentralCname");
+ }
+
+ Collection<String> locations = graph.getKeys();
+ for (String loc : locations) {
+ logger.info("loc=" + loc);
+ MR_Cluster cluster = clusters.getMr_ClusterByLoc(loc);
+ if (cluster == null) {
+ logger.info("No MR cluster for location " + loc);
+ continue;
+ }
+ if (graph.hasCentral() && !graph.getCentralLoc().equals(cluster.getDcaeLocationName())) {
+ logger.info("Detected case for EDGE_TO_CENTRAL from " + cluster.getFqdn() + " to " + centralFqdn);
+ return ReplicationType.REPLICATION_EDGE_TO_CENTRAL;
+
+ }
+
+ }
+ }
+
+ return ReplicationType.REPLICATION_NONE;
+ }
+
+ private void updateApiError(ApiError err, ApiError topicSetupError) {
+ err.setCode(topicSetupError.getCode());
+ err.setMessage(topicSetupError.getMessage());
+ err.setFields(topicSetupError.getFields());
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapConfig.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapConfig.java
new file mode 100644
index 0000000..e95ebab
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapConfig.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.util;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.io.*;
+import java.security.KeyStore;
+import java.util.*;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import org.onap.dmaap.dbcapi.server.CertificateManager;
+import org.onap.dmaap.dbcapi.server.JettyServer;
+
+public class DmaapConfig extends Properties {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(DmaapConfig.class);
+ private static final long serialVersionUID = 1L;
+ private static final String CONFIG_FILE_NAME = System.getProperty("ConfigFile", "/opt/app/config/conf/dmaapbc.properties");
+ private static final Properties config = new DmaapConfig();
+
+ public static Properties getConfig() {
+ return(config);
+ }
+ public static String getConfigFileName() {
+ return(CONFIG_FILE_NAME);
+ }
+ private DmaapConfig() {
+ try (InputStream is = new FileInputStream(CONFIG_FILE_NAME)){
+ load(is);
+ } catch (Exception e) {
+ logger.error("Unable to load configuration file " + CONFIG_FILE_NAME);
+ System.exit(1);
+ }
+ }
+
+ public static SSLSocketFactory getSSLSocketFactory() {
+ SSLSocketFactory factory = null;
+ try {
+ CertificateManager cm = JettyServer.getCertificateManager();
+ String truststore = cm.getTrustStoreFile();
+ KeyStore ts = KeyStore.getInstance(cm.getTrustStoreType());
+ try (InputStream in = new FileInputStream(truststore)) {
+ ts.load(in, cm.getTrustStorePassword().toCharArray());
+ }
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+ TrustManager[] tm = tmf.getTrustManagers();
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, tm, null);
+ factory = sslContext.getSocketFactory();
+ } catch (Exception e) {
+ logger.error("Exception thrown trying to get SSLSocketFactory: ", e);
+ }
+ return factory;
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapTimestamp.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapTimestamp.java
new file mode 100644
index 0000000..f36df1c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/DmaapTimestamp.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.util;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Date;
+
+@XmlRootElement
+public class DmaapTimestamp {
+ private Date stamp;
+
+ public DmaapTimestamp() {
+ this(new Date());
+ }
+
+ DmaapTimestamp(Date stamp) {
+ this.stamp = new Date(stamp.getTime());
+ }
+
+ public void mark() {
+ stamp = new Date();
+ }
+
+ public Date getVal() {
+ return new Date(stamp.getTime());
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java
new file mode 100644
index 0000000..37715d3
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.util;
+
+import java.util.regex.Pattern;
+
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public class Fqdn extends BaseLoggingClass {
+ // regexp value sourced from https://www.regextester.com/23
+ static String regexp = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$";
+
+
+ public static boolean isValid( String s ) {
+ appLogger.info( "Fqdn testing: " + s );
+ boolean b = false;
+ if ( s != null ) {
+ b = Pattern.matches( regexp, s);
+ }
+ appLogger.info( "Fqdn isValid=" + b );
+ return b;
+ }
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Graph.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Graph.java
new file mode 100644
index 0000000..ab40765
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Graph.java
@@ -0,0 +1,132 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.util;
+
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class Graph {
+ private HashMap<String, String> graph;
+ private boolean hasCentral;
+
+ private Map<String, DcaeLocation> locations = DatabaseClass.getDcaeLocations();
+
+ //TODO add to properties file
+ private static String centralDcaeLayerName = "central";
+
+
+ public Graph(HashMap<String, String> graph) {
+ super();
+ this.graph = graph;
+ }
+
+ public Graph( List<MR_Client> clients, boolean strict ) {
+ if ( clients == null )
+ return;
+ initGraph( clients, strict, "" );
+
+ }
+ public Graph( List<MR_Client> clients, boolean strict, String group ) {
+ if ( clients == null )
+ return;
+ initGraph( clients, strict, group );
+ }
+
+ private void initGraph(List<MR_Client> clients, boolean strict, String group ) {
+ MR_ClusterService clusters = new MR_ClusterService();
+ this.graph = new HashMap<>();
+ this.hasCentral = false;
+ for( MR_Client client: clients ) {
+ if ( ! strict || client.isStatusValid()) {
+ String loc = client.getDcaeLocationName();
+ DcaeLocation dcaeLoc = locations.get(loc);
+ if ( dcaeLoc == null ) continue;
+ MR_Cluster c = clusters.getMr_ClusterByLoc(loc);
+ if ( group != null && ! group.isEmpty() && ! group.equals(c.getReplicationGroup())) continue;
+
+ for( String action : client.getAction() ){
+ if ( ! action.equals("view") && dcaeLoc != null ) {
+ String layer = dcaeLoc.getDcaeLayer();
+ if ( layer != null && layer.contains(centralDcaeLayerName) ) {
+ this.hasCentral = true;
+ }
+ graph.put(loc, layer);
+ }
+ }
+
+ }
+ }
+ }
+
+ public HashMap<String, String> getGraph() {
+ return graph;
+ }
+
+ public void setGraph(HashMap<String, String> 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<String> getKeys() {
+ return graph.keySet();
+ }
+ public boolean hasCentral() {
+ 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;
+ }
+ public boolean isEmpty() {
+ return graph.isEmpty();
+ }
+
+
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java
new file mode 100644
index 0000000..d1f6b2b
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/PermissionBuilder.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.util;
+
+import javax.servlet.http.HttpServletRequest;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+public class PermissionBuilder {
+
+ static final String API_NS_PROP = "ApiNamespace";
+ static final String DEFAULT_API_NS = "org.onap.dmaap-bc.api";
+ static final String BOOT_INSTANCE = "boot";
+ private static final String PERM_SEPARATOR = "|";
+ private static final String NS_SEPARATOR = ".";
+ private DmaapConfig dmaapConfig;
+ private DmaapService dmaapService;
+ private String instance;
+ private String apiNamespace;
+
+ public PermissionBuilder(DmaapConfig dmaapConfig, DmaapService dmaapService) {
+ this.dmaapConfig = dmaapConfig;
+ this.dmaapService = dmaapService;
+ initFields();
+ }
+
+ public synchronized void updateDmaapInstance() {
+ if(instance == null || instance.isEmpty() || instance.equalsIgnoreCase(BOOT_INSTANCE)) {
+ String dmaapName = getDmaapName();
+ instance = (dmaapName == null || dmaapName.isEmpty()) ? BOOT_INSTANCE : dmaapName;
+ }
+ }
+
+ public String buildPermission(HttpServletRequest httpRequest) {
+
+ StringBuilder sb = new StringBuilder(apiNamespace);
+ sb.append(NS_SEPARATOR)
+ .append(getPermissionType(httpRequest.getPathInfo()))
+ .append(PERM_SEPARATOR)
+ .append(instance)
+ .append(PERM_SEPARATOR)
+ .append(httpRequest.getMethod());
+ return sb.toString();
+ }
+
+
+ private void initFields() {
+ apiNamespace = dmaapConfig.getProperty(API_NS_PROP, DEFAULT_API_NS);
+ updateDmaapInstance();
+ }
+
+ private String getDmaapName() {
+ Dmaap dmaap = dmaapService.getDmaap();
+ return ( dmaap != null ) ? dmaap.getDmaapName() : BOOT_INSTANCE;
+ }
+
+ private String getPermissionType(String pathInfo) {
+ char pathSeparator = '/';
+ String[] pathSlices = pathInfo.split(String.valueOf(pathSeparator));
+ return pathSlices[1];
+ }
+
+ String getInstance() {
+ return instance;
+ }
+}
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomInteger.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomInteger.java
new file mode 100644
index 0000000..1c9bc11
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomInteger.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.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);
+ }
+
+}
+
diff --git a/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomString.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomString.java
new file mode 100644
index 0000000..b889c1c
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/RandomString.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.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/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Singleton.java b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Singleton.java
new file mode 100644
index 0000000..3ef6a3d
--- /dev/null
+++ b/dmaap-bc/src/main/java/org/onap/dmaap/dbcapi/util/Singleton.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.util;
+
+public interface Singleton<T> {
+ public T get();
+ public void init(T val);
+ public void update(T val);
+ public void remove();
+}
diff --git a/dmaap-bc/src/main/resources/docker-compose.yml b/dmaap-bc/src/main/resources/docker-compose.yml
deleted file mode 100644
index 41bc473..0000000
--- a/dmaap-bc/src/main/resources/docker-compose.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-version: '2'
-services:
- dbc-pg-primary:
- image: crunchydata/crunchy-postgres:centos7-10.4-2.0.0
- ports:
- - "5432:5432"
- environment:
- - PG_MODE=master
- - PG_PRIMARY_USER="dmaap_admin"
- - PG_PRIMARY_PASSWORD=onapdemodb
- - PG_USER="dmaap_admin"
- - PG_PASSWORD=onapdemodb
- - PG_ROOT_PASSWORD=onapdemodb
- - PG_DATABASE="dmaap"
- - PG_PRIMARY_PORT=5432
-
- dmaap-bc:
- image: nexus3.onap.org:10001/onap/dmaap/buscontroller:latest
- ports:
- - "30241:8080"
- - "30242:8443"
- volumes:
- - /var/tmp/docker-databus-controller.conf:/opt/app/config/conf
- depends_on:
- - dbc-pg-primary
diff --git a/dmaap-bc/src/main/resources/docker-databus-controller.conf b/dmaap-bc/src/main/resources/docker-databus-controller.conf
deleted file mode 100644
index 7214adf..0000000
--- a/dmaap-bc/src/main/resources/docker-databus-controller.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-DMAAPBC_WAIT_TO_EXIT=Y
-DMAAPBC_PG_ENABLED=true
-DMAAPBC_PGHOST=dbc-pg-primary
-DMAAPBC_PGDBNAME=dmaap
-DMAAPBC_PGCRED=onapdemodb
-DMAAPBC_PGUSER=dmaap_admin
-DMAAPBC_MR_CNAME=message-router
-DMAAPBC_AAF_URL=https://aaf-authz/
-DMAAPBC_TOPICMGR_USER=m23456@dmaapbc.onap.org
-DMAAPBC_TOPICMGR_PWD=onapdemo
-DMAAPBC_ADMIN_USER=m12345@dmaapbc.onap.org
-DMAAPBC_ADMIN_PWD=onapdemo \ No newline at end of file
diff --git a/dmaap-bc/src/main/resources/Dockerfile b/dmaap-bc/src/main/resources/docker/Dockerfile
index 0f9e6a6..a801896 100644
--- a/dmaap-bc/src/main/resources/Dockerfile
+++ b/dmaap-bc/src/main/resources/docker/Dockerfile
@@ -4,6 +4,7 @@
# ===========================================================================
# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
# Modifications Copyright (C) 2018 Nokia. All rights reserved.
+# Modifications Copyright (C) 2021 Nordix Foundation.
# ===========================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,40 +18,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ============LICENSE_END====================================================
-#
-FROM library/maven:3.6-jdk-11
-MAINTAINER DMAAP Team
+FROM nexus3.onap.org:10001/onap/integration-java11:8.0.0
-COPY /opt /opt
+MAINTAINER DMAAP Team
WORKDIR /opt/app/dmaapbc
-RUN apt-get update && \
- apt-get install -y \
- curl \
- jq \
- openssl \
- net-tools \
- wget \
- procps \
- bash
-
-#prepare certificate location for cadi
-RUN mkdir -p /opt/app/osaaf
+COPY /opt /opt
+USER root
+RUN apk add --no-cache curl jq net-tools wget procps \
-RUN chmod +x bin/* && \
+&& mkdir -p /opt/app/osaaf && \
+ chmod +x bin/* && \
mkdir logs && \
- mkdir www && \
mkdir doc && \
- mkdir config
-
-VOLUME /opt/app/dmaapbc/log
-
-RUN addgroup --system -gid 1001 onap \
- && adduser --ingroup onap --system --disabled-password --no-create-home --uid 1000 dbc \
- && chown -R dbc:onap /opt/
+ mkdir config && \
+ chown -R onap:onap /opt/
-USER dbc
+USER onap
-ENTRYPOINT ["sh", "./bin/dmaapbc", "deploy"]
+ENTRYPOINT ["sh", "bin/dmaapbc", "deploy"]
diff --git a/dmaap-bc/src/main/resources/misc/LocalKey b/dmaap-bc/src/main/resources/misc/LocalKey
new file mode 100644
index 0000000..38ede55
--- /dev/null
+++ b/dmaap-bc/src/main/resources/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/dmaap-bc/src/main/resources/misc/PolicyEngineApi.properties.tmpl b/dmaap-bc/src/main/resources/misc/PolicyEngineApi.properties.tmpl
new file mode 100644
index 0000000..248b288
--- /dev/null
+++ b/dmaap-bc/src/main/resources/misc/PolicyEngineApi.properties.tmpl
@@ -0,0 +1,36 @@
+#
+# ============LICENSE_START==========================================
+# org.onap.dmaap
+# ===================================================================
+# Copyright © 2018 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 is a trademark and service mark of AT&T Intellectual Property.
+#
+#
+
+cat <<!EOF
+#PDP URLs to which will be used by the Policy Engine API to take Decisions. There are multiple to support redundancy.
+#Format: PDP_URL{PriorityNumber} = URL, id, password.
+PDP_URL1 = ${DMAAPBC_PDP1_URL:-https://host1.domain.notset.com:8081/pdp/} , ${DMAAPBC_PDP1_USER:-testpdp} , ${DMAAPBC_PDP1_PWD:-alpha123}
+PDP_URL2 = ${DMAAPBC_PDP2_URL:-https://host2.domain.notset.com:8082/pdp/} , ${DMAAPBC_PDP2_USER:-testpdp} , ${DMAAPBC_PDP2_PWD:-alpha456}
+PAP_URL = ${DMAAPBC_PAP_URL:-https://host3.domain.notset.com:9091/pap/} , ${DMAAPBC_PAP_USER:-testpap} , ${DMAAPBC_PAP_PWD:-alpha123}
+
+
+
+CLIENT_ID=${DMAAPBC_TOPICMGR_USER:-mechIdNotSet@namespaceNotSet}
+ENVIRONMENT=${DMAAPBC_PE_AAF_ENV:-DEVL}
+
+
+!EOF
diff --git a/dmaap-bc/misc/dmaapbc b/dmaap-bc/src/main/resources/misc/dmaapbc
index 15f2fd2..963d2d1 100644
--- a/dmaap-bc/misc/dmaapbc
+++ b/dmaap-bc/src/main/resources/misc/dmaapbc
@@ -4,6 +4,7 @@
# org.onap.dmaap
# ===================================================================
# Copyright © 2018 AT&T Intellectual Property. All rights reserved.
+# Modifications copyright (C) 2021 Nordix Foundation.
# ===================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,24 +20,23 @@
# ============LICENSE_END============================================
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-#
umask 0022
TZ=GMT0
COMPONENT=dmaapbc
APP_ROOT=/opt/app/$COMPONENT
-USER=dbc
+USER=onap
GROUP=onap
export TZ
-PATH=/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+PATH=/opt/java/openjdk/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
-CLASSPATH=`echo $APP_ROOT/etc $APP_ROOT/lib/*.jar | tr ' ' ':'`
+CLASSPATH=`echo $APP_ROOT/etc $APP_ROOT/lib/*.jar | tr ' ' ':'`
export CLASSPATH
CONFIGMAP_ROOT=${CONFIGMAP_ROOT:-/opt/app/config}
CONFIGMAP_PROPS=${CONFIGMAP_PROPS:-$CONFIGMAP_ROOT/conf/dmaapbc.properties}
CONTAINER_CONFIG=$CONFIGMAP_ROOT/conf/buscontroller.env
-MAIN=org.onap.dmaap.dbcapi.server.Main
+MAIN=org.onap.dmaap.dbcapi.server.Main
authcheck() {
set -x
@@ -75,8 +75,8 @@ config() {
then
echo "WARNING: Expected env file $CONTAINER_CONFIG not found. Default behaviors in effect"
find $CONTAINER_ROOT -type f
- else
- . $CONTAINER_CONFIG
+ else
+ . $CONTAINER_CONFIG
fi
if [ "$DMAAPBC_WAIT_TO_EXIT" != "Y" ]
@@ -85,27 +85,8 @@ config() {
> $APP_ROOT/ok_to_exit
else
echo "Not creating $APP_ROOT/ok_to_exit"
- fi
-
- #. misc/havecert.tmpl > etc/havecert
- #chmod +x etc/havecert
- echo Check for certificate
- TZ=GMT0
- cd /opt/app/dmaapbc;
- KEYSTORE=${DMAAPBC_KSTOREFILE:-etc/keystore}
- echo "KEYSTORE=$KEYSTORE"
- d=`dirname $KEYSTORE`
- ls -l $d
- if [ -f ${KEYSTORE} ]
- then
- echo "Goodness: Found ${KEYSTORE}"
- else
- EMSG="`date '+%F %T,000'` WARN Certificate file $KEYSTORE is missing"
- echo $EMSG
- echo $EMSG >>${DMAAPBC_LOGS:-logs}/dmaapbc.log
fi
-
# These files might be better provided in kubernetes configmaps
# so if they are there, use them
if [ -f $CONFIGMAP_PROPS ]
@@ -117,7 +98,7 @@ config() {
fi
if [ ! -f config/PolicyEngineApi.properties ]
then
- . misc/PolicyEngineApi.properties.tmpl > config/PolicyEngineApi.properties
+ . misc/PolicyEngineApi.properties.tmpl > config/PolicyEngineApi.properties
fi
set +x
}
@@ -129,13 +110,6 @@ start() {
cd $APP_ROOT
pwd
- if [ -f "$KEYSTORE" ]
- then
- echo >/dev/null
- else
- echo No certificate file available. Cannot start
- exit 0
- fi
PIDS=`pids`
if [ "$PIDS" != "" ]
then
@@ -144,11 +118,11 @@ start() {
fi
rm -f $APP_ROOT/etc/SHUTDOWN
+ java -classpath $CLASSPATH $MAIN
+ dmaapjar="$APP_ROOT/lib/dmaap-bc.jar"
# JVM flags
-#old line from Dockerfile...keep for reference only
- FLAGS="-cp etc:lib/* -Dlog4j.configuration=etc/log4j.properties -DConfigFile=$PROPS -Dlogback.configurationFile=etc/logback.xml -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
- #nohup java $FLAGS $MAIN </dev/null >/dev/null 2>&1 &
- nohup java $FLAGS $MAIN </dev/null &
+ FLAGS="-cp etc:lib/* -DConfigFile=$PROPS -Dlogback.configurationFile=etc/logback.xml -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
+ nohup java $FLAGS -jar $dmaapjar </dev/null &
sleep 5
PIDS=`pids`
set +x
@@ -181,46 +155,11 @@ status() {
fi
}
-init() {
- echo "ENTER init"
- if [ ! -d $CONFIGMAP_ROOT ]
- then
- echo $CONFIGMAP_ROOT does not exist
- return
- fi
-
- #loop on get /dmaap until we get a good response to indicate other provisioning can continue
- rc=999
- while [ $rc != "200" ]
- do
- sleep 10
- rc=`curl -s -o /dev/null -I -w "%{http_code}" -X GET -H "Content-Type: application/json" http://dmaap-bc:8080/webapi/dmaap`
- echo "get dmaap response=${rc}"
- done
-
- cd $CONFIGMAP_ROOT
- pwd
- # order is important in this next list
- for uri in dmaap dcaeLocations mr_clusters topics feeds
- do
- if [ -d ${uri} ]
- then
- for j in `ls ${uri}/*.json`
- do
- echo "POST $j to $uri"
- rc=`curl -v -X POST -w "%{http_code}" -H "Content-Type: application/json" -d @${j} http://dmaap-bc:8080/webapi/${uri}`
- echo "response=$rc"
- done
- fi
- done
-}
-
set -x
case "$1" in
'deploy')
config
start
- #init
wait
;;
'start')
@@ -244,11 +183,11 @@ case "$1" in
esac
ls -l $APP_ROOT/logs/ONAP
echo "------------ tail -100 error.log ---------------"
- tail -100 $APP_ROOT/logs/ONAP/error.log
+ tail -n 1000 $APP_ROOT/logs/ONAP/error.log
echo "------------ tail -100 server.log ---------------"
- tail -100 $APP_ROOT/logs/ONAP/server.log
+ tail -n 1000 $APP_ROOT/logs/ONAP/server.log
echo "------------ tail -100 application.log ---------------"
- tail -100 $APP_ROOT/logs/ONAP/application.log
+ tail -n 1000 $APP_ROOT/logs/ONAP/application.log
echo "Check $APP_ROOT/ok_to_exit"
while [ ! -f $APP_ROOT/ok_to_exit ]
diff --git a/dmaap-bc/src/main/resources/misc/dmaapbc.properties.tmpl b/dmaap-bc/src/main/resources/misc/dmaapbc.properties.tmpl
new file mode 100755
index 0000000..d013ca3
--- /dev/null
+++ b/dmaap-bc/src/main/resources/misc/dmaapbc.properties.tmpl
@@ -0,0 +1,222 @@
+cat <<!EOF
+#
+# ============LICENSE_START==========================================
+# org.onap.dmaap
+# ===================================================================
+# Copyright © 2018 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 is a trademark and service mark of AT&T Intellectual Property.
+#
+#
+#
+# Configuration parameters fixed at startup for the DMaaP Bus Controller
+#
+# CSIT TESTING
+csit: ${DMAAPBC_CSIT:-No}
+
+#
+# URI to retrieve dynamic DR configuration
+#
+ProvisioningURI: ${DMAAPBC_INTURI:-/internal/prov}
+#
+# Allow http access to API
+#
+HttpAllowed: ${DMAAPBC_HTTPALLOWED:-true}
+#
+# The port number for http as seen within the server
+#
+IntHttpPort: ${DMAAPBC_INT_HTTP_PORT:-8080}
+#
+# The port number for https as seen within the server
+# Set to 0 if no certificate is available yet...
+#
+IntHttpsPort: ${DMAAPBC_INT_HTTPS_PORT:-8443}
+#
+# The external port number for https taking port mapping into account
+#
+ExtHttpsPort: ${DMAAPBC_EXT_HTTPS_PORT:-443}
+#
+# The type of keystore for https
+#
+KeyStoreType: jks
+#
+# The path to the keystore for https
+#
+KeyStoreFile: ${DMAAPBC_KSTOREFILE:-etc/keystore}
+#
+# The password for the https keystore (remember to put password in "" and escape $ characters)
+#
+KeyStorePassword: ${DMAAPBC_KSTOREPASS:-"Y@Y5f&gm?PAz,CVQL,lk[VAF"}
+#
+# The password for the private key in the https keystore (remember to put password in "" and escape $ characters)
+#
+KeyPassword: ${DMAAPBC_PVTKEYPASS:-"Y@Y5f&gm?PAz,CVQL,lk[VAF"}
+#
+# The type of truststore for https
+#
+TrustStoreType: jks
+#
+# The path to the truststore for https
+#
+TrustStoreFile: ${DMAAPBC_TSTOREFILE:-etc/org.onap.dmaap-bc.trust.jks}
+#
+# The password for the https truststore (remember to put password in "" and escape $ characters)
+#
+TrustStorePassword: ${DMAAPBC_TSTOREPASS:-"8b&R5%l\$l:@jSWz@FCs;rhY*"}
+#
+# The path to the file used to trigger an orderly shutdown
+#
+QuiesceFile: etc/SHUTDOWN
+#
+# Enable postgress
+#
+UsePGSQL: ${DMAAPBC_PG_ENABLED:-false}
+#
+# The host for postgres access
+#
+DB.host: ${DMAAPBC_PGHOST:-HostNotSet}
+#
+# For postgres access
+#
+DB.cred: ${DMAAPBC_PGCRED:-ValueNotSet}
+#
+# Name of this environment
+#
+DmaapName: ${DMAAPBC_INSTANCE_NAME:-demo}
+#
+# Name of DR prov server
+#
+DR.provhost: ${DMAAPBC_DRPROV_FQDN:-dcae-drps.domain.notset.com}
+#
+# handling of feed delete
+# DeleteOnDR - means use the DR API to DELETE a feed. (default for backwards compatibility)
+# SimulateDelete - means preserve the feed on DR (after cleaning it up), and mark as DELETED in DBCL. Better for cfy environments
+Feed.deleteHandling: ${DMAAPBC_FEED_DELETE:-DeleteOnDR}
+
+################################################################################
+# MR Related Properties:
+#
+# ONAP Beijing and Casablanca are a single site deployment.
+MR.multisite: false
+#
+# Value of the CNAME DNS entry which resolves to the primary central MR cluster (when there are more than one central clusters).
+# if there is only one MR cluster in an environment, set this to the DNS name for that cluster
+#
+MR.CentralCname: ${DMAAPBC_MR_CNAME:-message-router}
+#
+# MR Client Delete Level thoroughness:
+# 0 = don't delete
+# 1 = delete from persistent store
+# 2 = delete from persistent store (DB) and authorization store (AAF)
+MR.ClientDeleteLevel: 1
+#
+# MR Topic Factory Namespace
+#
+MR.TopicFactoryNS: org.onap.dcae.dmaap.topicFactory
+#
+# MR TopicMgr Role
+MR.TopicMgrRole: org.onap.dmaap-bc-topic-mgr.client
+
+# MR topic name style
+MR.topicStyle: FQTN_LEGACY_FORMAT
+
+# MR topic ProjectID
+MR.projectID: 23456
+#
+# end of MR Related Properties
+################################################################################
+
+#
+# The Role and credentials of the MirrorMaker Provisioner. This is used by DMaaP Bus Controller to pub to the provisioning topic
+# Not part of 1701
+#
+MM.ProvRole: ${DMAAPBC_MMPROV_ROLE:-org.onap.dmaap-bc-mm-prov.prov}
+MM.ProvUserMechId: ${DMAAPBC_MMPROV_ID:-dmaap-bc-mm-prov@dmaap-bc-mm-prov.onap.org}
+MM.ProvUserPwd: ${DMAAPBC_MMPROV_PWD:-demo123456!}
+#
+# The Role of the MirrorMaker Agent. This is used by MM to sub to provisioning topic
+#
+MM.AgentRole: ${DMAAPBC_MMAGENT_ROLE:-org.onap.dmaap-bc-mm-prov.agent}
+#################
+#
+# CADI settings
+#
+# flag indication if CADI filtering is used
+enableCADI: ${DMAAPBC_ENABLE_CADI:-false}
+#
+# path to CADI properties
+cadi.properties: /opt/app/osaaf/local/org.onap.dmaap-bc.props
+
+#################
+# AAF Properties:
+UseAAF: ${DMAAPBC_USEAAF:-false}
+#
+# regarding password encryption:
+# In the dependencies that Maven retrieves (e.g., under dcae_dmaapbc/target/deps/ is a jar file cadi-core-version.jar. Generate the key file with:
+#
+# java \u2013jar wherever/cadi-core-*.jar keygen keyfilename
+# chmod 400 keyfilename
+#
+# To encrypt a key:
+#
+# java \u2013jar wherever/cadi-core-*.jar digest password-to-encrypt keyfilename
+#
+# This will generate a string. Put \u201Cenc:\u201D on the front of the string, and put the result in this properties file.
+#
+# Location of the Codec Keyfile which is used to decrypt passwords in this properties file before they are passed to AAF
+#
+# REF: https://wiki.domain.notset.com/display/cadi/CADI+Deployment
+#
+CredentialCodecKeyfile: ${DMAAPBC_CODEC_KEYFILE:-etc/LocalKey}
+#
+# This overrides the Class used for Decryption.
+# This allows for a plugin encryption/decryption method if needed.
+# Call this Class for decryption at runtime.
+#AafDecryption.Class: com.company.proprietaryDecryptor
+
+#
+# This overrides the Class used for API Permission check.
+# This allows for a plugin policy check, if needed
+ApiPermission.Class: org.onap.dmaap.dbcapi.authentication.AllowAll
+
+# Namespace for URI values for API used to create AAF permissions
+# e.g. if ApiNamespace is X.Y..dmaapBC.api then for URI /topics we create an AAF perm X.Y..dmaapBC.api.topics
+ApiNamespace: ${DMAAPBC_API_NAMESPACE:-org.onap.dmaap-bc.api}
+#
+# URL of AAF environment to use.
+#
+aaf.URL: ${DMAAPBC_AAF_URL:-https://aaf-onap-test.osaaf.org:8100}
+#
+# TopicMgr mechid@namespace
+#
+aaf.TopicMgrUser: ${DMAAPBC_TOPICMGR_USER:-dmaap-bc-topic-mgr@dmaap-bc-topic-mgr.onap.org}
+#
+# TopicMgr password
+#
+aaf.TopicMgrPassword: ${DMAAPBC_TOPICMGR_PWD:-enc:l0ScEojNQiiKbbkuM6U1mtnrme69q960}
+#
+# Bus Controller Namespace Admin mechid@namespace
+#
+aaf.AdminUser: ${DMAAPBC_ADMIN_USER:-aaf_admin@people.osaag.org}
+#
+# Bus Controller Namespace Admin password
+#
+aaf.AdminPassword: ${DMAAPBC_ADMIN_PWD:-demo123456!}
+
+
+#
+# endof AAF Properties
+#################
+!EOF
diff --git a/dmaap-bc/misc/log4j.properties.tmpl b/dmaap-bc/src/main/resources/misc/havecert.tmpl
index 2a30bf5..3d23c7b 100644
--- a/dmaap-bc/misc/log4j.properties.tmpl
+++ b/dmaap-bc/src/main/resources/misc/havecert.tmpl
@@ -1,3 +1,4 @@
+#!/bin/bash
#
# ============LICENSE_START==========================================
# org.onap.dmaap
@@ -20,13 +21,20 @@
#
#
cat <<!EOF
-log4j.debug=FALSE
-log4j.rootLogger=INFO,Root
-
-log4j.appender.Root=org.apache.log4j.DailyRollingFileAppender
-log4j.appender.Root.file=${DMAAPBC_LOGS:-logs}/buscontroller.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
+echo Check for certificate
+TZ=GMT0
+cd /opt/app/dmaapbc;
+KEYSTORE=${DMAAPBC_KSTOREFILE:-etc/keystore}
+echo "KEYSTORE=$KEYSTORE"
+d=`dirname $KEYSTORE`
+ls -l $d
+if [ -f ${KEYSTORE} ]
+then
+ echo "Goodness: Found ${KEYSTORE}"
+ exit 0
+fi
+EMSG="`date '+%F %T,000'` WARN Certificate file $KEYSTORE is missing"
+echo $EMSG
+echo $EMSG >>${DMAAPBC_LOGS:-logs}/dmaapbc.log
+exit 1
!EOF
diff --git a/dmaap-bc/misc/logback.xml b/dmaap-bc/src/main/resources/misc/logback.xml
index 2af00f1..37a3af8 100644
--- a/dmaap-bc/misc/logback.xml
+++ b/dmaap-bc/src/main/resources/misc/logback.xml
@@ -19,19 +19,13 @@
============LICENSE_END============================================
ECOMP is a trademark and service mark of AT&T Intellectual Property.
-->
-
-
+
<configuration scan="true" scanPeriod="3 seconds">
<!--<jmxConfigurator /> -->
<!-- directory path for all other type logs -->
<property name="logDir" value="logs" />
-
- <!-- directory path for debugging type logs -->
- <property name="debugDir" value="logs" />
-
- <!-- specify the component name
- <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC" -->
- <property name="componentName" value="ONAP"></property>
+ <!-- specify the component name -->
+ <property name="componentName" value="ONAP"/>
<!-- log file names -->
<property name="generalLogName" value="application" />
@@ -52,8 +46,6 @@
<property name="debugLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}|%thread|%msg%n" />
<property name="logDirectory" value="${logDir}/${componentName}" />
- <property name="debugLogDirectory" value="${debugDir}/${componentName}" />
-
<!-- Example evaluator filter applied against console appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
@@ -287,10 +279,10 @@
<appender name="EELFDebug"
class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>${debugLogDirectory}/${debugLogName}.log</file>
+ <file>${logDirectory}/${debugLogName}.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+ <fileNamePattern>${logDirectory}/${debugLogName}.%i.log.zip
</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>9</maxIndex>
@@ -337,8 +329,8 @@
<logger name="com.att.eelf.metrics" level="info" additivity="false">
<appender-ref ref="asyncEELFMetrics" />
</logger>
-
-
+
+
<logger name="com.att.eelf.error" level="error" additivity="false">
<appender-ref ref="asyncEELFError" />
</logger>
@@ -346,11 +338,9 @@
<logger name="com.att.eelf.debug" level="debug" additivity="false">
<appender-ref ref="asyncEELFDebug" />
</logger>
-
-
-
- <root level="INFO">
+
+ <root level="TRACE">
<appender-ref ref="asyncEELF" />
</root>
diff --git a/dmaap-bc/src/main/resources/misc/schema_all.sql b/dmaap-bc/src/main/resources/misc/schema_all.sql
new file mode 100644
index 0000000..c294b09
--- /dev/null
+++ b/dmaap-bc/src/main/resources/misc/schema_all.sql
@@ -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=========================================================
+---
+
+CREATE TABLE IF NOT EXISTS dcae_location (
+ dcae_location_name VARCHAR(100),
+ clli VARCHAR(100),
+ dcae_layer VARCHAR(100),
+ open_stack_availability_zone VARCHAR(100),
+ last_mod TIMESTAMP,
+ subnet VARCHAR(100),
+ status VARCHAR(100),
+ PRIMARY KEY(dcae_location_name)
+);
+CREATE TABLE IF NOT EXISTS 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)
+);
+CREATE TABLE IF NOT EXISTS dr_node (
+ fqdn VARCHAR(100),
+ dcae_location_name VARCHAR(100),
+ host_name VARCHAR(100),
+ version VARCHAR(100),
+ last_mod TIMESTAMP,
+ status VARCHAR(100),
+ PRIMARY KEY(fqdn)
+);
+CREATE TABLE IF NOT EXISTS dr_pub (
+ dcae_location_name VARCHAR(100),
+ username VARCHAR(100),
+ userpwd VARCHAR(100),
+ feed_id VARCHAR(100),
+ pub_id VARCHAR(100),
+ status VARCHAR(100),
+ last_mod TIMESTAMP,
+ PRIMARY KEY(pub_id)
+);
+CREATE TABLE IF NOT EXISTS 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),
+ last_mod TIMESTAMP,
+ guaranteed_delivery BOOLEAN,
+ guaranteed_sequence BOOLEAN,
+ privileged_subscriber BOOLEAN,
+ decompress BOOLEAN,
+ PRIMARY KEY(sub_id)
+);
+CREATE TABLE IF NOT EXISTS 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,
+ client_identity varchar(100),
+ PRIMARY KEY(mr_client_id)
+);
+CREATE TABLE IF NOT EXISTS mr_cluster (
+ last_mod TIMESTAMP,
+ dcae_location_name VARCHAR(100),
+ fqdn VARCHAR(100),
+ topic_protocol VARCHAR(100),
+ topic_port VARCHAR(100),
+ status VARCHAR(100),
+ replication_group VARCHAR(100),
+ PRIMARY KEY(dcae_location_name)
+);
+CREATE TABLE IF NOT EXISTS 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),
+ last_mod TIMESTAMP,
+ format_uuid VARCHAR(100),
+ PRIMARY KEY(feed_id)
+);
+CREATE TABLE IF NOT EXISTS 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),
+ format_uuid VARCHAR(100),
+ replication_case INT,
+ global_mr_u_r_l VARCHAR(200),
+ partition_count VARCHAR(10) DEFAULT 2,
+ replication_count VARCHAR(10) DEFAULT 1,
+ publisher_role VARCHAR(100),
+ subscriber_role VARCHAR(100),
+ PRIMARY KEY(fqtn)
+);
+CREATE TABLE IF NOT EXISTS mirror_maker (
+ mm_name VARCHAR(100),
+ source_cluster VARCHAR(100),
+ target_cluster VARCHAR(100),
+ last_mod TIMESTAMP,
+ status VARCHAR(100),
+ topics TEXT,
+ PRIMARY KEY(mm_name)
+);
diff --git a/dmaap-bc/src/main/webapp/HelloJetty.html b/dmaap-bc/src/main/webapp/HelloJetty.html
deleted file mode 100644
index 4d61636..0000000
--- a/dmaap-bc/src/main/webapp/HelloJetty.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<!--
- ============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=========================================================
- -->
-
-<html>
-<head>
-<meta charset="ISO-8859-1">
-<title>Index</title>
-</head>
-<body>
-Hello Jetty!
-</body>
-</html>
diff --git a/dmaap-bc/src/main/webapp/WEB-INF/log4j2.xml b/dmaap-bc/src/main/webapp/WEB-INF/log4j2.xml
deleted file mode 100644
index bd7e9c5..0000000
--- a/dmaap-bc/src/main/webapp/WEB-INF/log4j2.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ============LICENSE_START=======================================================
- Copyright (C) 2021 Nordix Foundation.
- ================================================================================
- 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.
-
- SPDX-License-Identifier: Apache-2.0
- ============LICENSE_END=========================================================
- -->
-
-<Configuration status="WARN">
- <Appenders>
- <!-- Console Appender -->
- <Console name="STDOUT" target="SYSTEM_OUT">
- <PatternLayout pattern="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
- </Console>
-
- <!-- Rolling File Appender -->
- <RollingFile name="rollingFile">
- <FileName>dmaapBC.log</FileName>
- <FilePattern>${date:yyyy-MM}/dmaapBC-%d{yyyy-MM-dd}-%i.log.gz</FilePattern>
- <PatternLayout>
- <Pattern>[%d{HH:mm:ss:SSS}] - %-6p - %c.%M() - %m%n</Pattern>
- </PatternLayout>
- <Policies>
- <SizeBasedTriggeringPolicy size="1000 KB"/>
- </Policies>
- <DefaultRolloverStrategy max="3"/>
- </RollingFile>
- </Appenders>
- <Loggers>
- <Logger name="org.openecomp.dcae.dmaapBC" level="debug" additivity="false">
- <AppenderRef ref="rollingFile"/>
- </Logger>
- <Root level="ALL">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration> \ No newline at end of file
diff --git a/dmaap-bc/src/main/webapp/WEB-INF/web.xml b/dmaap-bc/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 055fbf0..0000000
--- a/dmaap-bc/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ============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=========================================================
- -->
-
-<!-- This web.xml file is not required when using Servlet 3.0 container,
- see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
- <servlet>
- <servlet-name>Jersey Web Application</servlet-name>
- <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
- <init-param>
- <param-name>jersey.config.server.provider.packages</param-name>
- <param-value>org.openecomp.dmaapBC</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>Jersey Web Application</servlet-name>
- <url-pattern>/webapi/*</url-pattern>
- </servlet-mapping>
-</web-app>
diff --git a/dmaap-bc/src/main/webapp/index.jsp b/dmaap-bc/src/main/webapp/index.jsp
deleted file mode 100644
index 3c20e06..0000000
--- a/dmaap-bc/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,28 +0,0 @@
-<%--
- ============LICENSE_START=======================================================
- org.onap.dcae
- ================================================================================
- 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=========================================================
- --%>
-
-<html>
-<body>
- <h2>Jersey RESTful Web Application!</h2>
- <p><a href="webapi/dmaap">Jersey resource</a>
- <p>Visit <a href="http://jersey.java.net">Project Jersey website</a>
- for more information on Jersey!
-</body>
-</html>
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java
new file mode 100644
index 0000000..c53d8c6
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafRoleTest.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright 2019 IBM
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AafRoleTest {
+
+ AafRole aafRole;
+
+ @Before
+ public void setUp() {
+ aafRole = new AafRole("testNs", "testRole");
+ }
+
+ @Test
+ public void testAafRole() {
+ aafRole.setNamespace("namespace");
+ aafRole.setRole("role");
+ assertEquals("namespace", aafRole.getNamespace());
+ assertEquals("role", aafRole.getRole());
+ assertEquals("namespace.role", aafRole.getFullyQualifiedRole());
+ assertNotNull(aafRole.toJSON());
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactoryTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactoryTest.java
new file mode 100644
index 0000000..45ff2b1
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceFactoryTest.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.aaf;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.aaf.AafService.ServiceType;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AafServiceFactoryTest {
+
+ private static final String USE_AAF = "true";
+ private static final String AAF_URL = "https://aaf.url/api";
+ private static final String ADMIN_USER = "admin_user";
+ private static final String TOPIC_MANAGER = "topic_manager";
+ private static final String ADMIN_PASS = "admin_pass";
+ private static final String MANAGER_PASS = "manager_pass";
+ @Mock
+ private DmaapConfig dmaapConfig;
+ private AafServiceFactory aafServiceFactory;
+
+ @Before
+ public void setUp() throws Exception {
+ aafServiceFactory = new AafServiceFactory(dmaapConfig);
+ }
+
+ @Test
+ public void shouldBuildAafServiceForAafAdmin() {
+ givenDmaapConfig();
+
+ AafServiceImpl aafService = (AafServiceImpl) aafServiceFactory.initAafService(ServiceType.AAF_Admin);
+
+ assertEquals(ADMIN_USER, aafService.getIdentity());
+ assertEquals(AAF_URL, aafService.getAafUrl());
+ assertTrue(aafService.isUseAAF());
+ }
+
+ @Test
+ public void shouldBuildAafServiceForTopicManager() {
+ givenDmaapConfig();
+
+ AafServiceImpl aafService = (AafServiceImpl) aafServiceFactory.initAafService(ServiceType.AAF_TopicMgr);
+
+ assertEquals(TOPIC_MANAGER, aafService.getIdentity());
+ assertEquals(AAF_URL, aafService.getAafUrl());
+ assertTrue(aafService.isUseAAF());
+ }
+
+ @Test
+ public void shouldCorrectlyCreateCredentialsForAafAdmin() {
+ givenDmaapConfig();
+
+ AafServiceFactory.AafCred cred = aafServiceFactory.getCred(ServiceType.AAF_Admin);
+
+ assertEquals(ADMIN_USER, cred.getIdentity());
+ assertEquals(ADMIN_USER + ":" + new AafDecrypt().decrypt(ADMIN_PASS), cred.toString());
+ }
+
+ @Test
+ public void shouldCorrectlyCreateCredentialsForTopicManager() {
+ givenDmaapConfig();
+
+ AafServiceFactory.AafCred cred = aafServiceFactory.getCred(ServiceType.AAF_TopicMgr);
+
+ assertEquals(TOPIC_MANAGER, cred.getIdentity());
+ assertEquals(TOPIC_MANAGER + ":" + new AafDecrypt().decrypt(MANAGER_PASS), cred.toString());
+ }
+
+ private void givenDmaapConfig() {
+ given(dmaapConfig.getProperty("UseAAF", "false")).willReturn(USE_AAF);
+ given(dmaapConfig.getProperty("aaf.URL", "https://authentication.domain.netset.com:8100/proxy/")).willReturn(AAF_URL);
+ given(dmaapConfig.getProperty("aaf.AdminUser", "noMechId@domain.netset.com")).willReturn(ADMIN_USER);
+ given(dmaapConfig.getProperty("aaf.TopicMgrUser", "noMechId@domain.netset.com")).willReturn(TOPIC_MANAGER);
+ given(dmaapConfig.getProperty("aaf.AdminPassword", "notSet")).willReturn(ADMIN_PASS);
+ given(dmaapConfig.getProperty("aaf.TopicMgrPassword", "notSet")).willReturn(MANAGER_PASS);
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceImplTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceImplTest.java
new file mode 100644
index 0000000..ffd130e
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafServiceImplTest.java
@@ -0,0 +1,208 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.aaf;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(JUnitParamsRunner.class)
+public class AafServiceImplTest {
+
+ private static final String AAF_URL = "https://aaf.url/";
+ private static final String IDENTITY = "dmaap-bc@onap.org";
+ private static final boolean USE_AAF = true;
+ private static final int CREATED = 201;
+ private static final int OK = 200;
+ @Mock
+ private AafConnection aafConnection;
+ private AafServiceImpl aafService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ given(aafConnection.postAaf(any(AafObject.class), anyString())).willReturn(CREATED);
+ given(aafConnection.delAaf(any(AafObject.class), anyString())).willReturn(OK);
+ aafService = new AafServiceImpl(USE_AAF, AAF_URL, IDENTITY, aafConnection);
+ }
+
+ @Test
+ public void shouldReturnCorrectIdentity() {
+
+ assertEquals(IDENTITY, aafService.getIdentity());
+ }
+
+ @Test
+ public void shouldAddPermission() {
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.addPerm(perm);
+
+ then(aafConnection).should().postAaf(perm, AAF_URL + "authz/perm");
+ assertEquals(CREATED, status);
+ }
+
+
+ @Test
+ public void shouldAddDmaapGrant() {
+ DmaapGrant grant = new DmaapGrant(new DmaapPerm("perm", "type", "action"), "roles");
+
+ int status = aafService.addGrant(grant);
+
+ then(aafConnection).should().postAaf(grant, AAF_URL + "authz/role/perm");
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ public void shouldAddUserRole() {
+ AafUserRole userRole = new AafUserRole("ident", "role");
+
+ int status = aafService.addUserRole(userRole);
+
+ then(aafConnection).should().postAaf(userRole, AAF_URL + "authz/userRole");
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ public void shouldAddRole() {
+ AafRole role = new AafRole("ns", "role");
+
+ int status = aafService.addRole(role);
+
+ then(aafConnection).should().postAaf(role, AAF_URL + "authz/role");
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ public void shouldAddNamespace() {
+ AafNamespace ns = new AafNamespace("ns", "ident");
+
+ int status = aafService.addNamespace(ns);
+
+ then(aafConnection).should().postAaf(ns, AAF_URL + "authz/ns");
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ public void shouldNotConnectToAafDuringCreate() {
+ aafService = new AafServiceImpl(false, AAF_URL, IDENTITY, aafConnection);
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.addPerm(perm);
+
+ verifyZeroInteractions(aafConnection);
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ @Parameters({"401", "403", "409", "200", "500"})
+ public void shouldHandleErrorDuringCreate(int aafServiceReturnedCode) {
+ given(aafConnection.postAaf(any(AafObject.class), anyString())).willReturn(aafServiceReturnedCode);
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.addPerm(perm);
+
+ assertEquals(aafServiceReturnedCode, status);
+ }
+
+ @Test
+ @Parameters({"401", "403", "404", "200", "500"})
+ public void shouldHandleErrorDuringDelete(int aafServiceReturnedCode) {
+ given(aafConnection.delAaf(any(AafObject.class), anyString())).willReturn(aafServiceReturnedCode);
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.delPerm(perm, false);
+
+ assertEquals(aafServiceReturnedCode, status);
+ }
+
+ @Test
+ public void shouldDeletePermission() {
+ DmaapPerm perm = new DmaapPerm("permName", "type", "action");
+
+ int status = aafService.delPerm(perm, false);
+
+ then(aafConnection).should().delAaf(any(AafEmpty.class), eq(AAF_URL + "authz/perm/permName/type/action"));
+ assertEquals(OK, status);
+ }
+
+ @Test
+ public void shouldDeletePermissionWithForce() {
+ DmaapPerm perm = new DmaapPerm("permName", "type", "action");
+
+ int status = aafService.delPerm(perm, true);
+
+ then(aafConnection).should().delAaf(any(AafEmpty.class), eq(AAF_URL + "authz/perm/permName/type/action?force=true"));
+ assertEquals(OK, status);
+ }
+
+ @Test
+ public void shouldDeleteNamespace() {
+ AafNamespace ns = new AafNamespace("nsName", "ident");
+
+ int status = aafService.delNamespace(ns, false);
+
+ then(aafConnection).should().delAaf(any(AafEmpty.class), eq(AAF_URL + "authz/ns/nsName"));
+ assertEquals(OK, status);
+ }
+
+ @Test
+ public void shouldDeleteNamespaceWithForce() {
+ AafNamespace ns = new AafNamespace("nsName", "ident");
+
+ int status = aafService.delNamespace(ns, true);
+
+ then(aafConnection).should().delAaf(any(AafEmpty.class), eq(AAF_URL + "authz/ns/nsName?force=true"));
+ assertEquals(OK, status);
+ }
+
+ @Test
+ public void shouldReturnExpectedCodeDuringPostWhenUseAffIsSetToFalse() {
+ aafService = new AafServiceImpl(false, AAF_URL, IDENTITY, aafConnection);
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.addPerm(perm);
+
+ assertEquals(CREATED, status);
+ }
+
+ @Test
+ public void shouldReturnExpectedCodeDuringDeleteWhenUseAffIsSetToFalse() {
+ aafService = new AafServiceImpl(false, AAF_URL, IDENTITY, aafConnection);
+ DmaapPerm perm = new DmaapPerm("perm", "type", "action");
+
+ int status = aafService.delPerm(perm, false);
+
+ assertEquals(OK, status);
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafUserRoleTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafUserRoleTest.java
new file mode 100644
index 0000000..88fff87
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/aaf/AafUserRoleTest.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 IBM Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
+ * 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.onap.dmaap.dbcapi.aaf;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AafUserRoleTest {
+
+ AafUserRole aafUserRole;
+
+ @Before
+ public void setUp() {
+ aafUserRole = new AafUserRole("xyz", "admin");
+ }
+
+ @Test
+ public void testGetIdentity() {
+ aafUserRole.setIdentity("xyz");
+ assertEquals("xyz", aafUserRole.getIdentity());
+ }
+
+ @Test
+ public void testGetRole() {
+ aafUserRole.setRole("admin");
+ assertEquals("admin", aafUserRole.getRole());
+ }
+
+ @Test
+ public void toJSON() {
+ AafUserRole role = new AafUserRole("test", "admin");
+ assertThat(role.toJSON(), is(" { \"user\": \"test\", \"role\": \"admin\" }"));
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFishTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFishTest.java
new file mode 100644
index 0000000..af6aba4
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AafLurAndFishTest.java
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Application;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AafLurAndFishTest extends JerseyTest {
+
+ @Before
+ public void setUp() throws Exception {
+ System.setProperty("ConfigFile", "src/test/resources/dmaapbc.properties");
+ }
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig()
+ .register( AafLurAndFish.class );
+ }
+
+ @Test
+ public void constructorTest() {
+ try {
+ AafLurAndFish p = new AafLurAndFish();
+ } catch ( AuthenticationErrorException err ) {
+
+ }
+
+ assertTrue( true );
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AllowAllTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AllowAllTest.java
new file mode 100644
index 0000000..9b6ee01
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/AllowAllTest.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.authentication;
+
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class AllowAllTest {
+
+ private AllowAll allowAll = new AllowAll();
+
+ @Test
+ public void check_shouldPassValidationForAllPerms() {
+ try {
+ allowAll.check(null, null, null);
+ } catch (Exception e) {
+ fail("No exception should be thrown");
+ }
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPermsTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPermsTest.java
new file mode 100644
index 0000000..ea749ce
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPermsTest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.authentication;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.core.Application;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import org.onap.dmaap.dbcapi.authentication.ApiPerms;
+
+
+public class ApiPermsTest extends JerseyTest {
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig()
+ .register( ApiPerms.class );
+ }
+
+ @Test
+ public void bootTest() {
+ ApiPerms p = new ApiPerms();
+
+ p.setBootMap();
+
+ p.setEnvMap();
+
+
+ assertTrue( true );
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPolicyTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPolicyTest.java
new file mode 100644
index 0000000..7b9fbb3
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/authentication/ApiPolicyTest.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.authentication;
+
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+
+import java.util.Properties;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ApiPolicyTest {
+
+ private Properties properties = new Properties();
+ private ApiPolicy apiPolicy;
+
+ @Test
+ public void check_shouldExecuteAuthorizationApi() throws Exception {
+ properties.put("ApiPermission.Class", "org.onap.dmaap.dbcapi.authentication.ApiPolicyTest$DummyApiAuthorization");
+ apiPolicy = new ApiPolicy(properties);
+
+ apiPolicy.check("mechId", "pwd", new DmaapPerm("api.perm", "*", "GET"));
+
+ assertTrue(((DummyApiAuthorization) apiPolicy.getPerm()).isCheckExecuted());
+ }
+
+ @Test
+ public void isPermissionClassSet_shouldReturnTrueForValidApiPermClass() {
+ properties.put("ApiPermission.Class", "org.onap.dmaap.dbcapi.authentication.ApiPolicyTest$DummyApiAuthorization");
+ apiPolicy = new ApiPolicy(properties);
+
+ assertTrue(apiPolicy.isPermissionClassSet());
+ }
+
+ @Test
+ public void isPermissionClassSet_shouldReturnFalseWhenPropertyIsNotSet() {
+ apiPolicy = new ApiPolicy(properties);
+
+ assertFalse(apiPolicy.isPermissionClassSet());
+ }
+
+ @Test
+ public void isPermissionClassSet_shouldReturnFalseWhenWrongClassIsSet() {
+ properties.put("ApiPermission.Class", "org.onap.dmaap.dbcapi.authentication.NotExisting");
+ apiPolicy = new ApiPolicy(properties);
+
+ assertFalse(apiPolicy.isPermissionClassSet());
+ }
+
+ public static class DummyApiAuthorization implements ApiAuthorizationCheckInterface {
+
+ private boolean checkExecuted = false;
+
+ @Override
+ public void check(String mechid, String pwd, DmaapPerm p) {
+ checkExecuted = true;
+ }
+
+ boolean isCheckExecuted() {
+ return checkExecuted;
+ }
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/DrProvConnectionTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/DrProvConnectionTest.java
new file mode 100644
index 0000000..4c44e0a
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/DrProvConnectionTest.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.client;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.service.DcaeLocationService;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+import org.onap.dmaap.dbcapi.service.TopicService;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class DrProvConnectionTest {
+
+ private static final String fmt = "%24s: %s%n";
+ private static DmaapObjectFactory factory = new DmaapObjectFactory();
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ DrProvConnection ns;
+ MR_ClusterService mcs;
+ TopicService ts;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new DrProvConnection();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.DrProvConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.DrProvConnection", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = factory.genDcaeLocation( "central" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+ String[] hl = { "host1", "host2", "host3" };
+ ns.makeFeedConnection( );
+ ns.makeFeedConnection( "01" );
+ ns.makeSubPostConnection( "part0/part1/part2/part3/part4" );
+ ns.makeSubPutConnection( "44" );
+ ns.makeIngressConnection( "01", "aUser", "10.10.10.10", "aNode" );
+ ns.makeEgressConnection( "01", "aNode" );
+ ns.makeNodesConnection( "someVar" );
+ Feed feed = new Feed( "dgl feed 1" ,
+ "v1.0",
+ "dgl feed 1 for testing",
+ "TEST",
+ "unclassified"
+ );
+ ArrayList<DR_Pub> pubs = new ArrayList<DR_Pub>();
+ pubs.add( new DR_Pub( "central-demo" ) );
+ feed.setPubs(pubs);
+
+ String resp = ns.doPostFeed( feed, err );
+ resp = ns.doPutFeed( feed, err );
+ resp = ns.doDeleteFeed( feed, err );
+
+ int i = ns.doXgressPost( err );
+
+ DR_Sub sub = factory.genDrSub( "central", feed.getFeedId() );
+ assertTrue( sub != null );
+ String sr = ns.doPostDr_Sub( sub, err );
+ /*
+ * TODO:
+ - create a new DR_Sub based on a simulated response
+ - update using ns.doPutDr_Sub( sub, err );
+ */
+ }
+
+ @Test
+ public void test4() {
+ ApiError err = new ApiError();
+ String resp = ns.doGetNodes( err );
+ ns.makeNodesConnection( "someVar", "host1|host2" );
+ resp = ns.doPutNodes( err );
+ try {
+ InputStream is = new FileInputStream(new File("/src/test/resources/dmaapbc.properties"));
+ String body = ns.bodyToString( is );
+ } catch ( FileNotFoundException fnfe ) {
+ }
+ }
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrProvConnectionTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrProvConnectionTest.java
new file mode 100644
index 0000000..0614cf9
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrProvConnectionTest.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.client;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.service.DcaeLocationService;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+import org.onap.dmaap.dbcapi.service.TopicService;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class MrProvConnectionTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ MrProvConnection ns;
+ MR_ClusterService mcs;
+ TopicService ts;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new MrProvConnection();
+ ts = new TopicService();
+ mcs = new MR_ClusterService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrProvConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrProvConnection", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = new DcaeLocation( "CLLI1234", "central-onap", locname, "aZone", "10.10.10.0/24" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+
+ MR_Cluster cluster = new MR_Cluster( locname, "localhost", "http", "3904" );
+ mcs.addMr_Cluster( cluster, err );
+ ns.makeTopicConnection( cluster );
+ Topic topic = new Topic();
+ topic.setTopicName( "test5" );
+ String resp = ns.doPostTopic( topic, err );
+
+ try {
+ InputStream is = new FileInputStream(new File("/src/test/resources/dmaapbc.properties"));
+ String body = ns.bodyToString( is );
+ } catch ( FileNotFoundException fnfe ) {
+ }
+
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrTopicConnectionTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrTopicConnectionTest.java
new file mode 100644
index 0000000..af33ec6
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/client/MrTopicConnectionTest.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.client;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.service.DcaeLocationService;
+import org.onap.dmaap.dbcapi.service.MR_ClusterService;
+import org.onap.dmaap.dbcapi.service.TopicService;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class MrTopicConnectionTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ MrTopicConnection ns;
+ MR_ClusterService mcs;
+ TopicService ts;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new MrTopicConnection( "aUser", "aPwd" );
+ ts = new TopicService();
+ mcs = new MR_ClusterService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = new DcaeLocation( "CLLI1234", "central-onap", locname, "aZone", "10.10.10.0/24" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+
+ MR_Cluster cluster = new MR_Cluster( locname, "localhost", "http", "3904");
+ mcs.addMr_Cluster( cluster, err );
+ ns.makeTopicConnection( cluster, "org.onap.dmaap.anInterestingTopic", "" );
+ String msg = "{ 'key': '1234', 'val': 'hello world' }";
+ ApiError e2 = ns.doPostMessage( msg );
+
+ try {
+ InputStream is = new FileInputStream(new File("/src/test/resources/dmaapbc.properties"));
+ String body = ns.bodyToString( is );
+ } catch ( FileNotFoundException fnfe ) {
+ }
+
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBFieldHandlerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBFieldHandlerTest.java
new file mode 100644
index 0000000..f68b9ed
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBFieldHandlerTest.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
+ * 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.onap.dmaap.dbcapi.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+import org.onap.dmaap.dbcapi.model.ReplicationType;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class DBFieldHandlerTest extends BaseLoggingClass {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
+ public Object get(ResultSet rs, int index) throws Exception {
+ int val = rs.getInt(index);
+
+ return (ReplicationType.valueOf(val));
+ }
+
+ public void set(PreparedStatement ps, int index, Object val) throws Exception {
+ if (val == null) {
+ ps.setInt(index, 0);
+ return;
+ }
+ @SuppressWarnings("unchecked")
+ ReplicationType rep = (ReplicationType) val;
+ ps.setInt(index, rep.getValue());
+ }
+ }
+
+ @Test
+ public void test1() {
+ // rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get",
+ // "idNotSet@namespaceNotSet:pwdNotSet" );
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ // rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
+ }
+
+ @Test
+ public void test3() {
+ try {
+ DBFieldHandler fh = new DBFieldHandler(String.class, "aString", 1);
+ } catch (Exception e) {
+ errorLogger.error("Error", e);
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ DBFieldHandler fh = new DBFieldHandler(String.class, "aString", 1, null);
+ } catch (Exception e) {
+ errorLogger.error("Error", e);
+ }
+ }
+
+ @Test
+ public void testfesc() {
+ String sampleString = "@xyz,ww;,";
+ String finalString = DBFieldHandler.fesc(sampleString);
+ assertEquals("@axyz@cww@s@c", finalString);
+ }
+
+ @Test
+ public void testfunesc() {
+ String sampleString = "@axyz@cww@s@c";
+ String convertedString = DBFieldHandler.funesc(sampleString);
+ assertEquals("@xyz,ww;,", convertedString);
+ }
+
+ @Test
+ public void testfescWithNull() {
+ String sampleString1 = DBFieldHandler.fesc(null);
+ String sampleString2 = DBFieldHandler.funesc(null);
+ assertNull(null, sampleString1);
+ assertNull(null, sampleString2);
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBMapTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBMapTest.java
new file mode 100644
index 0000000..abd4aee
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBMapTest.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.database;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+import org.onap.dmaap.dbcapi.util.Singleton;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.*;
+
+public class DBMapTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+
+ private static Singleton<Dmaap> dmaap;
+ private static Map<String, DcaeLocation> dcaeLocations;
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ try {
+ dmaap = new DBSingleton<Dmaap>(Dmaap.class, "dmaap");
+ Dmaap nd = new Dmaap.DmaapBuilder().createDmaap();
+ dmaap.update(nd);
+ } catch (Exception e ) {
+ }
+ try {
+ dcaeLocations = new DBMap<DcaeLocation>(DcaeLocation.class, "dcae_location", "dcae_location_name");
+ } catch (Exception e ) {
+ }
+
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBSingletonTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBSingletonTest.java
new file mode 100644
index 0000000..003f250
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/DBSingletonTest.java
@@ -0,0 +1,67 @@
+
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.database;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DBSingletonTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+
+ @Test
+ public void test3() {
+
+ try {
+ DBSingleton<Dmaap> dmaap = new DBSingleton<Dmaap>(Dmaap.class, "dmaap");
+ Dmaap d = new Dmaap.DmaapBuilder().createDmaap();
+ dmaap.init( d );
+ d = dmaap.get();
+ d.setDmaapName( "foo" );
+ dmaap.update( d );
+ dmaap.remove();
+ } catch (Exception e ) {
+ }
+
+ }
+
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/LoadSchemaTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/LoadSchemaTest.java
new file mode 100644
index 0000000..99065d3
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/LoadSchemaTest.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.database;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class LoadSchemaTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ LoadSchema ls;
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.database.LoadSchema", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.database.LoadSchema", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ LoadSchema.loadSchema();
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/TableHandlerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/TableHandlerTest.java
new file mode 100644
index 0000000..978f3ad
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/database/TableHandlerTest.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.database;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.sql.*;
+
+public class TableHandlerTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ private static class TopicReplicationTypeHandler implements DBFieldHandler.SqlOp {
+ public Object get(ResultSet rs, int index) throws Exception {
+ int val = rs.getInt(index);
+
+ return (ReplicationType.valueOf(val));
+ }
+ public void set(PreparedStatement ps, int index, Object val) throws Exception {
+ if (val == null) {
+ ps.setInt(index, 0);
+ return;
+ }
+ @SuppressWarnings("unchecked")
+ ReplicationType rep = (ReplicationType) val;
+ ps.setInt(index, rep.getValue());
+ }
+ }
+
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ //rh.reflect( "org.onap.dmaap.dbcapi.aaf.client.MrTopicConnection", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ DBFieldHandler.SqlOp trth = new TopicReplicationTypeHandler();
+ TableHandler.setSpecialCase("topic", "replication_case", trth);
+
+ try {
+ ConnectionFactory cf = new ConnectionFactory();
+ TableHandler th = new TableHandler( cf, TopicReplicationTypeHandler.class, "foo", "bar" );
+ DBFieldHandler.SqlOp t = th.getSpecialCase( "foo", "bar" );
+ assert( trth == t );
+ } catch (Exception e ) {
+ }
+ try {
+
+ TableHandler th = new TableHandler( TopicReplicationTypeHandler.class, "foo", "bar" );
+ DBFieldHandler.SqlOp t = th.getSpecialCase( "foo", "bar" );
+ assert( trth == t );
+ } catch (Exception e ) {
+ }
+
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java
new file mode 100644
index 0000000..11e7c85
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/BrTopicTest.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright 2019 IBM
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class BrTopicTest {
+
+ BrTopic brTopic;
+
+ @Before
+ public void setUp() {
+ brTopic = new BrTopic();
+ }
+
+ @Test
+ public void testGetBrSource() {
+ brTopic.setBrSource("brSource");
+ assertEquals("brSource", brTopic.getBrSource());
+ }
+
+ @Test
+ public void testGetBrTarget() {
+ brTopic.setBrTarget("brTarget");
+ assertEquals("brTarget", brTopic.getBrTarget());
+ }
+
+ @Test
+ public void testGetTopicCount() {
+ brTopic.setTopicCount(1);
+ assertEquals(1, brTopic.getTopicCount());
+ }
+
+ @Test
+ public void testGetMmAgentName() {
+ brTopic.setMmAgentName("Test");
+ assertEquals("Test", brTopic.getMmAgentName());
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRNodeTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRNodeTest.java
new file mode 100644
index 0000000..ce23656
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRNodeTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+public class DRNodeTest {
+ String f, d, h, v;
+
+ @Before
+ public void setUp() throws Exception {
+ v = "1";
+ f = "node01.onap.org";
+ h = "zlpdrns01.cloud.onap.org";
+ d = "central-onap";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testDRNodeClassDefaultConstructor() {
+
+ DR_Node t = new DR_Node();
+
+ assertTrue( t.getFqdn() == null );
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getHostName() == null );
+ assertTrue( t.getVersion() == null );
+
+ }
+
+ @Test
+ public void testDRNodeClassConstructor() {
+
+ DR_Node t = new DR_Node( f, d, h, v );
+
+ assertTrue( f.equals( t.getFqdn() ));
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ assertTrue( h.equals( t.getHostName() ));
+ assertTrue( v.equals( t.getVersion() ));
+
+ }
+
+ @Test
+ public void testDRNodeClassSetters() {
+
+ DR_Node t = new DR_Node();
+
+ t.setFqdn( f );
+ assertTrue( f.equals( t.getFqdn() ));
+ t.setDcaeLocationName( d );
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ t.setHostName( h );
+ assertTrue( h.equals( t.getHostName() ));
+ t.setVersion( v );
+ assertTrue( v.equals( t.getVersion() ));
+
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRPubTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRPubTest.java
new file mode 100644
index 0000000..191f364
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRPubTest.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+public class DRPubTest {
+ String d, un, up, f, p;
+
+ @Before
+ public void setUp() throws Exception {
+ d = "central-onap";
+ un = "user1";
+ up = "secretW0rd";
+ f = "234";
+ p = "678";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testDRPubClassDefaultConstructor() {
+
+ DR_Pub t = new DR_Pub();
+
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getUsername() == null );
+ assertTrue( t.getUserpwd() == null );
+ assertTrue( t.getFeedId() == null );
+ assertTrue( t.getPubId() == null );
+
+ }
+
+ @Test
+ public void testDRPubClassConstructor() {
+
+ DR_Pub t = new DR_Pub( d, un, up, f, p );
+
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ assertTrue( un.equals( t.getUsername() ));
+ assertTrue( up.equals( t.getUserpwd() ));
+ assertTrue( f.equals( t.getFeedId() ));
+ assertTrue( p.equals( t.getPubId() ));
+ }
+
+ @Test
+ public void testDRPubClassSetters() {
+
+ DR_Pub t = new DR_Pub();
+
+ t.setDcaeLocationName( d );
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ t.setUsername( un );
+ assertTrue( un.equals( t.getUsername() ));
+ t.setUserpwd( up );
+ assertTrue( up.equals( t.getUserpwd() ));
+ t.setFeedId( f );
+ assertTrue( f.equals( t.getFeedId() ));
+ t.setPubId( p );
+ assertTrue( p.equals( t.getPubId() ));
+
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRSubTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRSubTest.java
new file mode 100644
index 0000000..95cf9c9
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DRSubTest.java
@@ -0,0 +1,155 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+public class DRSubTest {
+ String d, un, up, f, du, lu, s, o;
+ Boolean u100, susp;
+
+ @Before
+ public void setUp() throws Exception {
+ d = "central-onap";
+ un = "user1";
+ up = "secretW0rd";
+ f = "22";
+ s = "sub123";
+ du = "sub.server.onap.org:8443/deliver/here";
+ lu = "https://drps.onap.org:8443/sublog/123";
+ u100 = true;
+ susp = false;
+ o = "joe";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testDRSubClassDefaultConstructor() {
+
+ DR_Sub t = new DR_Sub();
+
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getUsername() == null );
+ assertTrue( t.getUserpwd() == null );
+ assertTrue( t.getFeedId() == null );
+ assertTrue( t.getDeliveryURL() == null );
+ assertTrue( t.getLogURL() == null );
+ assertTrue( t.getSubId() == null );
+ assertTrue( ! t.isUse100() );
+ assertTrue( ! t.isSuspended() );
+ assertTrue( t.getOwner() == null );
+ assertTrue( t.isGuaranteedDelivery() == false );
+ assertTrue( t.isGuaranteedSequence() == false );
+ assertTrue( t.isPrivilegedSubscriber() == false );
+ assertTrue( t.isDecompress() == false );
+ }
+
+ @Test
+ public void testDRSubClassConstructor() {
+
+ DR_Sub t = new DR_Sub( d, un, up, f, du, lu, u100 );
+
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ assertTrue( un.equals( t.getUsername() ));
+ assertTrue( up.equals( t.getUserpwd() ));
+ assertTrue( f.equals( t.getFeedId() ));
+ assertTrue( du.equals( t.getDeliveryURL() ) );
+ assertTrue( lu.equals( t.getLogURL() ) );
+ assertTrue( t.isUse100() );
+ assertTrue( ! t.isSuspended() );
+ }
+
+ @Test
+ public void testDRSubClassSetters() {
+
+ DR_Sub t = new DR_Sub();
+
+ t.setDcaeLocationName( d );
+ assertTrue( d.equals( t.getDcaeLocationName() ));
+ t.setUsername( un );
+ assertTrue( un.equals( t.getUsername() ));
+ t.setUserpwd( up );
+ assertTrue( up.equals( t.getUserpwd() ));
+ t.setFeedId( f );
+ assertTrue( f.equals( t.getFeedId() ));
+ t.setSubId( s );
+ assertTrue( s.equals( t.getSubId() ));
+ t.setDeliveryURL( du );
+ assertTrue( du.equals( t.getDeliveryURL() ) );
+ t.setLogURL( lu );
+ assertTrue( lu.equals( t.getLogURL() ) );
+ boolean v = true;
+ t.setGuaranteedDelivery( v );
+ assertTrue( t.isGuaranteedDelivery() == v );
+ t.setGuaranteedSequence(v);
+ assertTrue( t.isGuaranteedSequence() == v );
+ t.setPrivilegedSubscriber(v);
+ assertTrue( t.isPrivilegedSubscriber() == v );
+ t.setDecompress(v);
+ assertTrue( t.isDecompress() == v );
+ }
+
+ @Test
+ public void testJSONfromONAP() {
+
+
+ DR_Sub s = new DR_Sub( d, un, up, f, du, lu, u100 );
+ String j = s.toProvJSON();
+
+ DR_Sub t = new DR_Sub( j );
+
+ assertTrue( un.equals( t.getUsername() ));
+ assertTrue( up.equals( t.getUserpwd() ));
+ //assertTrue( f.equals( t.getFeedId() ));
+ assertTrue( du.equals( t.getDeliveryURL() ) );
+ //assertTrue( lu.equals( t.getLogURL() ) );
+ assertTrue( ! t.isSuspended() );
+
+ }
+
+ @Test
+ public void testJSONfromATT() {
+
+
+ DR_Sub s = new DR_Sub( d, un, up, f, du, lu, u100 );
+
+ DR_Sub t = new DR_Sub( s.toProvJSONforATT() );
+
+ assertTrue( un.equals( t.getUsername() ));
+ assertTrue( up.equals( t.getUserpwd() ));
+ //assertTrue( f.equals( t.getFeedId() ));
+ assertTrue( du.equals( t.getDeliveryURL() ) );
+ // assertTrue( lu.equals( t.getLogURL() ) );
+ assertTrue( ! t.isSuspended() );
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DcaeLocationTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DcaeLocationTest.java
new file mode 100644
index 0000000..6652bb0
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DcaeLocationTest.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+public class DcaeLocationTest {
+ String c, dl, dln, osz, s, edge;
+
+ @Before
+ public void setUp() throws Exception {
+ c = "ABCDE888NJ";
+ dl = "central-node";
+ edge = "local-node";
+ dln = "hollywood";
+ osz = "california";
+ s = "10.10.10.1";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testDcaeLocationDefaultConstructor() {
+
+ DcaeLocation t = new DcaeLocation();
+
+ assertTrue( t.getClli() == null );
+ assertTrue( t.getDcaeLayer() == null );
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getOpenStackAvailabilityZone() == null );
+ assertTrue( t.getSubnet() == null );
+
+ }
+
+ @Test
+ public void testDcaeLocationClassConstructor() {
+
+ DcaeLocation t = new DcaeLocation( c, dl, dln, osz, s );
+
+ assertTrue( c.equals( t.getClli() ));
+ assertTrue( dl.equals( t.getDcaeLayer() ));
+ assertTrue( dln.equals( t.getDcaeLocationName() ));
+ assertTrue( osz.equals( t.getOpenStackAvailabilityZone() ));
+ assertTrue( s.equals( t.getSubnet() ));
+ }
+
+ @Test
+ public void testDmaapClassSetters() {
+
+ DcaeLocation t = new DcaeLocation();
+
+ t.setClli( c );
+ assertTrue( c.equals( t.getClli() ));
+ t.setDcaeLayer( dl );
+ assertTrue( dl.equals( t.getDcaeLayer() ));
+ assertTrue( t.isCentral() );
+ t.setDcaeLayer( edge );
+ assertTrue( edge.equals( t.getDcaeLayer() ));
+ assertTrue( t.isLocal() );
+ t.setDcaeLocationName( dln );
+ assertTrue( dln.equals( t.getDcaeLocationName() ));
+ t.setOpenStackAvailabilityZone( osz );
+ assertTrue( osz.equals( t.getOpenStackAvailabilityZone() ));
+ t.setSubnet( s );
+ assertTrue( s.equals( t.getSubnet() ));
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DmaapTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DmaapTest.java
new file mode 100644
index 0000000..cb0c22f
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/DmaapTest.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DmaapTest {
+ private String ver, tnr, dn, dpu, lu, bat, nk, ako;
+
+ @Before
+ public void setUp() throws Exception {
+ ver = "1";
+ tnr = "org.onap.dmaap";
+ dn = "onap";
+ dpu = "https://drps.dmaap.onap.org:8081";
+ lu = "http://drps.dmaap.onap.org:8080/feedlog";
+ bat = "org.onap.dcae.dmaap.MM_AGENT_TOPIC";
+ nk = "foo";
+ ako = "bar";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testDmaapClassDefaultConstructor() {
+
+ Dmaap t = new Dmaap.DmaapBuilder().createDmaap();
+
+ assertTrue( t.getVersion() == null );
+ assertTrue( t.getTopicNsRoot() == null );
+ assertTrue( t.getDmaapName() == null );
+ assertTrue( t.getDrProvUrl() == null );
+ assertTrue( t.getLoggingUrl() == null );
+ assertTrue( t.getBridgeAdminTopic() == null );
+ assertTrue( t.getNodeKey() == null );
+ assertTrue( t.getAccessKeyOwner() == null );
+
+ }
+
+ @Test
+ public void testDmaapClassConstructor() {
+
+ Dmaap t = new Dmaap.DmaapBuilder().setVer(ver).setTnr(tnr).setDn(dn).setDpu(dpu).setLu(lu).setBat(bat).setNk(nk).setAko(ako).createDmaap();
+
+ assertTrue( ver.equals( t.getVersion() ));
+ assertTrue( tnr.equals( t.getTopicNsRoot() ));
+ assertTrue( dn.equals( t.getDmaapName() ));
+ assertTrue( dpu.equals( t.getDrProvUrl() ));
+ assertTrue( lu.equals( t.getLoggingUrl() ));
+ assertTrue( bat.equals( t.getBridgeAdminTopic() ));
+ assertTrue( nk.equals( t.getNodeKey() ));
+ assertTrue( ako.equals( t.getAccessKeyOwner() ));
+
+ }
+
+ @Test
+ public void testDmaapClassSetters() {
+
+ Dmaap t = new Dmaap.DmaapBuilder().createDmaap();
+
+ t.setVersion( ver );
+ assertTrue( ver.equals( t.getVersion() ));
+ t.setTopicNsRoot( tnr );
+ assertTrue( tnr.equals( t.getTopicNsRoot() ));
+ t.setDmaapName( dn );
+ assertTrue( dn.equals( t.getDmaapName() ));
+ t.setDrProvUrl( dpu );
+ assertTrue( dpu.equals( t.getDrProvUrl() ));
+ t.setLoggingUrl( lu );
+ assertTrue( lu.equals( t.getLoggingUrl() ));
+ t.setBridgeAdminTopic( bat );
+ assertTrue( bat.equals( t.getBridgeAdminTopic() ));
+ t.setNodeKey( nk );
+ assertTrue( nk.equals( t.getNodeKey() ));
+ t.setAccessKeyOwner( ako );
+ assertTrue( ako.equals( t.getAccessKeyOwner() ));
+
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/FeedTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/FeedTest.java
new file mode 100644
index 0000000..4fdc9a1
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/FeedTest.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import java.util.ArrayList;
+
+
+public class FeedTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ String n, v, d, o, a;
+
+ @Before
+ public void setUp() throws Exception {
+ System.setProperty("ConfigFile", "src/test/resources/dmaapbc.properties");
+ n = "Chicken Feed";
+ v = "1.0";
+ d = "A daily helping of chicken eating metrics";
+ o = "ab123";
+ a = "Unrestricted";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.model.Feed", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ Feed t = new Feed( n, v, d, o, a );
+
+ ArrayList<DR_Sub> subs = new ArrayList<DR_Sub>();
+ DR_Sub sub = new DR_Sub( "central", "user", "pwd", "22", "server.onap.org/deliv", "log.onap.org/logs", true );
+ subs.add( sub );
+ t.setSubs( subs );
+
+ assertTrue( n.equals( t.getFeedName() ));
+ assertTrue( v.equals( t.getFeedVersion() ));
+ assertTrue( d.equals( t.getFeedDescription() ));
+ assertTrue( o.equals( t.getOwner() ));
+ assertTrue( a.equals( t.getAsprClassification() ) );
+ assertTrue( ! t.isSuspended() );
+ }
+
+ @Test
+ public void test3() {
+
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.model.Feed", "set", v );
+ }
+
+ @Test
+ public void test4() {
+ String s = String.format( "{ \"%s\": \"%s\", \"%s\": \"%s\", \"%s\": \"%s\", \"%s\": \"%s\", \"%s\": false, \"%s\": { \"%s\": \"%s\", \"%s\": \"%s\", \"%s\": \"%s\" }, \"%s\": { \"%s\": \"%s\", \"%s\": [ { \"%s\": \"%s\", \"%s\": \"%s\" } ] } }",
+ "name", n,
+ "version", v,
+ "description", d,
+ "publisher", a,
+ "suspend",
+ "links",
+ "publish", "https://feed.onap.org/publish/22",
+ "subscribe" , Feed.getSubProvURL( "22" ),
+ "log" , "https://feed.onap.org/log/22",
+ "authorization",
+ "classification", a,
+ "endpoint_ids" , "id", "king", "password", "henry" );
+
+
+ Feed t = new Feed( s );
+
+ assertTrue( n.equals( t.getFeedName() ));
+ assertTrue( v.equals( t.getFeedVersion() ));
+ assertTrue( d.equals( t.getFeedDescription() ));
+ assertTrue( a.equals( t.getAsprClassification() ) );
+ assertTrue( ! t.isSuspended() );
+
+ String o = t.toString();
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/JUnitTestSuite.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/JUnitTestSuite.java
new file mode 100644
index 0000000..69e1b69
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/JUnitTestSuite.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import ch.qos.logback.classic.Logger;
+import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({DmaapTest.class})
+public class JUnitTestSuite {
+
+ static Logger logger;
+
+ public static void main(String[] args) {
+ logger.info("Running the test suite");
+
+ TestSuite tstSuite = new TestSuite();
+ logger.info("Total Test Counts " + tstSuite.countTestCases());
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MRClientTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MRClientTest.java
new file mode 100644
index 0000000..ba95a85
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MRClientTest.java
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class MRClientTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ String d, t, f, c, m;
+
+ @Before
+ public void setUp() throws Exception {
+ d = "central-onap";
+ t = "org.onap.dmaap.interestingTopic";
+ f = "mrc.onap.org:3904/events/org.onap.dmaap.interestingTopic";
+ c = "publisher";
+ m = "m12345";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test1() {
+
+ // can't use simple reflection to test for null since null constructor
+ // initializes some fields.
+ // rh.reflect( "org.onap.dmaap.dbcapi.model.MR_Client", "get", null );
+ // so brute force instead...
+ String[] a = { "put", "view" };
+ MR_Client m = new MR_Client();
+
+ assertTrue(null == m.getDcaeLocationName());
+ assertTrue(null == m.getFqtn());
+ assertTrue(null == m.getClientRole());
+ assertTrue(null == m.getAction());
+
+ }
+
+ @Test
+ public void test2() {
+ String[] a = { "put", "view" };
+ MR_Client m = new MR_Client(d, f, c, a);
+
+ assertTrue(d.equals(m.getDcaeLocationName()));
+ assertTrue(f.equals(m.getFqtn()));
+ assertTrue(c.equals(m.getClientRole()));
+ String[] ma = m.getAction();
+ assertTrue(a.length == ma.length);
+ for (int i = 0; i < a.length; i++) {
+ assertTrue(a[i].equals(ma[i]));
+ }
+ }
+
+ @Test
+ public void test3() {
+
+ String v = "Validate";
+ rh.reflect("org.onap.dmaap.dbcapi.model.MR_Client", "set", v);
+ }
+
+ @Test
+ public void test4() {
+ MR_Client mrClient = new MR_Client();
+ String stringArray[] = { "test" };
+ mrClient.setAction(stringArray);
+ mrClient.hasAction("");
+ mrClient.setMrClientId("mrClientId");
+ mrClient.setTopicURL("testTopicURL");
+ mrClient.setClientIdentity("clientIdentity");
+
+ assertEquals("clientIdentity", mrClient.getClientIdentity());
+ assertEquals("testTopicURL", mrClient.getTopicURL());
+ assertEquals("mrClientId", mrClient.getMrClientId());
+ assertEquals(false, mrClient.isPublisher());
+ assertEquals(false, mrClient.isSubscriber());
+ assertEquals("test", mrClient.getAction()[0]);
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MR_ClusterTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MR_ClusterTest.java
new file mode 100644
index 0000000..2200627
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MR_ClusterTest.java
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+public class MR_ClusterTest {
+ String d, fqdn, repGrp, p1, p2, prot, p0;
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ @Before
+ public void setUp() throws Exception {
+ d = "central-onap";
+ fqdn = "mr.onap.org";
+ repGrp = "zeppelin";
+ prot = "http";
+ p0 = "3904";
+ p1 = "9092";
+ p2 = "2323";
+
+
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testMR_ClusterClassDefaultConstructor() {
+
+ MR_Cluster t = new MR_Cluster();
+
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getFqdn() == null );
+
+ }
+
+ @Test
+ public void testMR_ClusterClassConstructor() {
+
+ MR_Cluster t = new MR_Cluster( d, fqdn, prot, p0);
+
+ assertTrue( t.getDcaeLocationName() == d );
+ assertTrue( t.getFqdn() == fqdn );
+ assertTrue( t.getTopicProtocol() == prot );
+ assertTrue( t.getTopicPort() == p0 );
+
+ // pass null params to trigger default settings
+ t = new MR_Cluster( d, fqdn, null, null );
+
+ assertTrue( t.getDcaeLocationName() == d );
+ assertTrue( t.getFqdn() == fqdn );
+ assertTrue( t.getTopicProtocol() != null );
+ assertTrue( t.getTopicPort() != null );
+ }
+
+ @Test
+ public void testMR_ClusterManyArgsClassConstructor() {
+
+ MR_Cluster t = new MR_Cluster( d, fqdn, prot, p0, repGrp, p1, p2 );
+
+ assertTrue( t.getDcaeLocationName() == d );
+ assertTrue( t.getFqdn() == fqdn );
+ assertTrue( t.getTopicProtocol() == prot );
+ assertTrue( t.getTopicPort() == p0 );
+ assertTrue( t.getReplicationGroup() == repGrp );
+ assertTrue( t.getSourceReplicationPort() == p1 );
+ assertTrue( t.getTargetReplicationPort() == p2 );
+
+ // pass null params to trigger default settings
+ t = new MR_Cluster( d, fqdn, null, null, null, null, null );
+
+ assertTrue( t.getDcaeLocationName() == d );
+ assertTrue( t.getFqdn() == fqdn );
+ assertTrue( t.getTopicProtocol() != null );
+ assertTrue( t.getTopicPort() != null );
+ assertTrue( t.getReplicationGroup() != null );
+ assertTrue( t.getSourceReplicationPort() != null );
+ assertTrue( t.getTargetReplicationPort() != null );
+ }
+
+ @Test
+ public void testw3() {
+
+ MR_Cluster t = new MR_Cluster();
+
+ assertTrue( t.getDcaeLocationName() == null );
+ assertTrue( t.getFqdn() == null );
+
+ String override = "cluster2.onap.org";
+ String topic2 = "org.onap.topic2";
+ String fqtn = t.genTopicURL( override, topic2 );
+ assertTrue( fqtn.contains( override) && fqtn.contains(topic2));
+
+ fqtn = t.genTopicURL( null, "org.onap.topic2" );
+ assertTrue(fqtn.contains(topic2));
+ }
+
+
+
+ @Test
+ public void testsetter() {
+
+ String v = "validate";
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.model.MR_Cluster", "set", v );
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MirrorMakerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MirrorMakerTest.java
new file mode 100644
index 0000000..39de2be
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/MirrorMakerTest.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import java.util.ArrayList;
+
+
+public class MirrorMakerTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.model.MirrorMaker", "get", null );
+
+ }
+ @Test
+ public void test2() {
+
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.model.MirrorMaker", "set", v );
+ }
+
+ @Test
+ public void test3() {
+ String f = "org.onap.interestingTopic";
+ String c1 = "cluster1.onap.org";
+ String c2 = "cluster2.onap.org";
+ MirrorMaker t = new MirrorMaker( c1, c2 );
+ String m = t.getMmName();
+
+ MirrorMaker.genKey( c1, c2 );
+
+ assertTrue( c1.equals( t.getSourceCluster() ));
+ assertTrue( c2.equals( t.getTargetCluster() ));
+ }
+
+
+ @Test
+ public void test4() {
+ String f = "org.onap.interestingTopic";
+ String c1 = "cluster1.onap.org";
+ String c2 = "cluster2.onap.org";
+ String p1 = "9092";
+ String p2 = "2081";
+ MirrorMaker t = new MirrorMaker( c1, c2 );
+ String m = t.getMmName();
+
+
+ ArrayList<String> topics = new ArrayList<String>();
+ topics.add( f );
+ t.setTopics( topics );
+ t.addTopic( "org.onap.topic2" );
+
+ int i = t.getTopicCount();
+
+ String s = t.getWhitelistUpdateJSON();
+
+ s = t.createMirrorMaker(p1, p2);
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TestRunner.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TestRunner.java
new file mode 100644
index 0000000..16b48e3
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TestRunner.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.model;
+
+import ch.qos.logback.classic.Logger;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
+
+public class TestRunner extends BaseLoggingClass {
+
+ private static Logger logger;
+
+ public static void main(String[] args) {
+
+ Result result = JUnitCore.runClasses(JUnitTestSuite.class);
+ for (Failure failure : result.getFailures()) {
+ logger.info(failure.toString());
+
+ }
+ logger.info(String.valueOf(result.wasSuccessful()));
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TopicTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TopicTest.java
new file mode 100644
index 0000000..5da3aed
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/model/TopicTest.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ================================================================================
+ * 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.onap.dmaap.dbcapi.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class TopicTest {
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ String f, t, d, e, o;
+
+ @Before
+ public void setUp() throws Exception {
+ f = "org.onap.dmaap.interestingTopic";
+ t = "interestingTopic";
+ d = "A so very interesting topic";
+ e = "Yes";
+ o = "m12345";
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test1() {
+ rh.reflect("org.onap.dmaap.dbcapi.model.Topic", "get", null);
+ }
+
+ @Test
+ public void test2() {
+ Topic obj = new Topic(f, t, d, e, o);
+ assertTrue(f.equals(obj.getFqtn()));
+ assertTrue(t.equals(obj.getTopicName()));
+ assertTrue(d.equals(obj.getTopicDescription()));
+ assertTrue(e.equals(obj.getTnxEnabled()));
+ assertTrue(o.equals(obj.getOwner()));
+ }
+
+ @Test
+ public void test3() {
+ String v = "Validate";
+ rh.reflect("org.onap.dmaap.dbcapi.model.Topic", "set", v);
+ }
+
+ @Test
+ public void getNumClientsHavingMRClientListNull() {
+ Topic obj = new Topic(f, t, d, e, o);
+ obj.setClients(null);
+ assertEquals(0, obj.getNumClients());
+ }
+
+ @Test
+ public void testTopicInitializationWithInvalidJsonString() {
+ String json = "{\"key\":\"value\"";
+ Topic obj = new Topic(json);
+ assertEquals(DmaapObject_Status.INVALID, obj.getStatus());
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java
new file mode 100644
index 0000000..76fe914
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthenticationFilterTest.java
@@ -0,0 +1,195 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AAFAuthenticationFilterTest {
+
+ @Spy
+ private AAFAuthenticationFilter filter;
+ @Mock
+ private FilterConfig filterConfig;
+ @Mock
+ private CadiFilter cadiFilterMock;
+ @Mock
+ private HttpServletRequest servletRequest;
+ @Mock
+ private HttpServletResponse servletResponse;
+ @Mock
+ private FilterChain filterChain;
+ @Mock
+ private DmaapConfig dmaapConfig;
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() throws Exception {
+ doReturn(dmaapConfig).when(filter).getConfig();
+ }
+
+ @Test
+ public void init_shouldNotInitializeCADI_whenAafIsNotUsed() throws Exception {
+ //given
+ doReturn("false").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+
+ //when
+ filter.init(filterConfig);
+
+ //then
+ assertFalse(filter.isCadiEnabled());
+ assertNull(filter.getCadiFilter());
+ }
+
+ @Test
+ public void doFilter_shouldSkipCADI_whenAafIsNotUsed() throws Exception {
+ //given
+ doReturn("false").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+ filter.init(filterConfig);
+ filter.setCadiFilter(cadiFilterMock);
+
+ //when
+ filter.doFilter(servletRequest, servletResponse, filterChain);
+
+ //then
+ verify(filterChain).doFilter(servletRequest,servletResponse);
+ verifyZeroInteractions(cadiFilterMock,servletRequest,servletResponse);
+ }
+
+ @Test
+ public void init_shouldFail_whenAafIsUsed_andCadiPropertiesHasNotBeenSet() throws Exception {
+ //given
+ doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+ doReturn("").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+
+ //then
+ thrown.expect(ServletException.class);
+ thrown.expectMessage("Cannot initialize CADI filter.CADI properties not available.");
+
+ //when
+ filter.init(filterConfig);
+ }
+
+ @Test
+ public void init_shouldFail_whenAafIsUsed_andInvalidCadiPropertiesSet() throws Exception {
+ //given
+ String invalidFilePath = "src/test/resources/notExisting.properties";
+ doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+ doReturn(invalidFilePath).when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+
+ //then
+ thrown.expect(ServletException.class);
+ thrown.expectMessage("Could not load CADI properties file: "+invalidFilePath);
+
+ //when
+ filter.init(filterConfig);
+ }
+
+ /*
+ * See https://jira.onap.org/browse/DMAAP-1361 for why this is commented out
+ @Test
+ public void init_shouldInitializeCADI_whenAafIsUsed_andValidCadiPropertiesSet() throws Exception {
+ //given
+ doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+ doReturn("src/test/resources/cadi.properties").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+
+ //when
+ filter.init(filterConfig);
+
+ //then
+ assertTrue(filter.isCadiEnabled());
+ assertNotNull(filter.getCadiFilter());
+ }
+
+ @Test
+ public void doFilter_shouldUseCADIfilter_andAuthenticateUser_whenAAFisUsed_andUserIsValid() throws Exception{
+ //given
+ initCADIFilter();
+ doReturn(200).when(servletResponse).getStatus();
+
+ //when
+ filter.doFilter(servletRequest,servletResponse,filterChain);
+
+ //then
+ verify(cadiFilterMock).doFilter(servletRequest,servletResponse,filterChain);
+ verify(servletResponse).getStatus();
+ verifyNoMoreInteractions(servletResponse);
+ verifyZeroInteractions(filterChain, servletRequest);
+ }
+
+ @Test
+ public void doFilter_shouldUseCADIfilter_andReturnAuthenticationError_whenAAFisUsed_andUserInvalid() throws Exception{
+ //given
+ String errorResponseJson = "{\"code\":401,\"message\":\"invalid or no credentials provided\",\"fields\":\"Authentication\",\"2xx\":false}";
+ initCADIFilter();
+ doReturn(401).when(servletResponse).getStatus();
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ doReturn(pw).when(servletResponse).getWriter();
+
+ //when
+ filter.doFilter(servletRequest,servletResponse,filterChain);
+
+ //then
+ verify(cadiFilterMock).doFilter(servletRequest,servletResponse,filterChain);
+ verify(servletResponse).getStatus();
+ verify(servletResponse).setContentType("application/json");
+ verifyZeroInteractions(filterChain, servletRequest);
+ assertEquals(errorResponseJson, sw.toString());
+ }
+
+ private void initCADIFilter() throws Exception{
+ doReturn("true").when(dmaapConfig).getProperty(eq(AAFAuthenticationFilter.CADI_AUTHN_FLAG), anyString());
+ doReturn("src/test/resources/cadi.properties").when(dmaapConfig).getProperty(AAFAuthenticationFilter.CADI_PROPERTIES);
+ filter.init(filterConfig);
+ filter.setCadiFilter(cadiFilterMock);
+ }
+*/
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java
new file mode 100644
index 0000000..ba11b01
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/AAFAuthorizationFilterTest.java
@@ -0,0 +1,172 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import com.sun.security.auth.UserPrincipal;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import org.onap.dmaap.dbcapi.util.PermissionBuilder;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AAFAuthorizationFilterTest {
+
+ @Spy
+ private AAFAuthorizationFilter filter;
+ @Mock
+ private FilterConfig filterConfig;
+ @Mock
+ private HttpServletRequest servletRequest;
+ @Mock
+ private HttpServletResponse servletResponse;
+ @Mock
+ private FilterChain filterChain;
+ @Mock
+ private DmaapConfig dmaapConfig;
+ @Mock
+ private PermissionBuilder permissionBuilder;
+ @Mock
+ private DmaapService dmaapService;
+
+ @Before
+ public void setUp() throws Exception {
+ filter.setPermissionBuilder(permissionBuilder);
+ doReturn(dmaapConfig).when(filter).getConfig();
+ doReturn(dmaapService).when(filter).getDmaapService();
+ }
+
+ @Test
+ public void init_shouldNotInitializePermissionBuilder_whenAAFnotUsed() throws Exception {
+ //given
+ filter.setPermissionBuilder(null);
+ configureAAFUsage(false);
+
+ //when
+ filter.init(filterConfig);
+
+ //then
+ assertNull(filter.getPermissionBuilder());
+ }
+
+ @Test
+ public void init_shouldInitializePermissionBuilder_whenAAFisUsed() throws Exception {
+ //given
+ filter.setPermissionBuilder(null);
+ configureAAFUsage(true);
+ //doReturn(provideEmptyInstance()).when(dmaapService).getDmaap();
+ when(dmaapService.getDmaap()).thenReturn(mock(Dmaap.class));
+
+ //when
+ filter.init(filterConfig);
+
+ //then
+ assertNotNull(permissionBuilder);
+ }
+
+ @Test
+ public void doFilter_shouldSkipAuthorization_whenAAFnotUsed() throws Exception {
+ //given
+ filter.setCadiEnabled(false);
+
+ //when
+ filter.doFilter(servletRequest,servletResponse,filterChain);
+
+ //then
+ verify(filterChain).doFilter(servletRequest,servletResponse);
+ verifyNoMoreInteractions(filterChain);
+ verifyZeroInteractions(permissionBuilder, servletRequest, servletResponse);
+ }
+
+ @Test
+ public void doFilter_shouldPass_whenUserHasPermissionToResourceEndpoint() throws Exception {
+ //given
+ String user = "johnny";
+ String permission = "org.onap.dmaap-bc.api.topics|mr|GET";
+ when(permissionBuilder.buildPermission(servletRequest)).thenReturn(permission);
+ configureServletRequest(permission, user, true);
+ filter.setCadiEnabled(true);
+
+ //when
+ filter.doFilter(servletRequest,servletResponse,filterChain);
+
+ //then
+ verify(filterChain).doFilter(servletRequest,servletResponse);
+ verify(permissionBuilder).updateDmaapInstance();
+ verifyZeroInteractions(servletResponse);
+ }
+
+ @Test
+ public void doFilter_shouldReturnError_whenUserDontHavePermissionToResourceEndpoint() throws Exception {
+ //given
+ String user = "jack";
+ String permission = "org.onap.dmaap-bc.api.topics|mr|GET";
+ when(permissionBuilder.buildPermission(servletRequest)).thenReturn(permission);
+ configureServletRequest(permission, user, false);
+ filter.setCadiEnabled(true);
+
+ String errorMsgJson = "{\"code\":403,\"message\":\"User "+user+" does not have permission "
+ + permission +"\",\"fields\":\"Authorization\",\"2xx\":false}";
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ when(servletResponse.getWriter()).thenReturn(pw);
+
+ //when
+ filter.doFilter(servletRequest,servletResponse,filterChain);
+
+ //then
+ verifyZeroInteractions(filterChain);
+ verify(permissionBuilder).updateDmaapInstance();
+ verify(servletResponse).setStatus(403);
+ assertEquals(errorMsgJson, sw.toString());
+ }
+
+ private void configureServletRequest(String permission, String user, boolean isUserInRole) {
+ when(servletRequest.getUserPrincipal()).thenReturn(new UserPrincipal(user));
+ when(servletRequest.isUserInRole(permission)).thenReturn(isUserInRole);
+ }
+
+ private void configureAAFUsage(Boolean isUsed) {
+ doReturn(isUsed.toString()).when(dmaapConfig).getProperty(eq(AAFAuthorizationFilter.CADI_AUTHZ_FLAG), anyString());
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_NodeResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_NodeResourceTest.java
new file mode 100644
index 0000000..f131d8f
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_NodeResourceTest.java
@@ -0,0 +1,236 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Node;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+
+public class DR_NodeResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+ private static FastJerseyTestContainer testContainer;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(DR_NodeResource.class));
+ testContainer.init();
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+ DatabaseClass.clearDatabase();
+ DatabaseClass.getDmaap().remove();*/
+ }
+
+ @Test
+ public void getDr_Nodes_test() {
+ Response response = testContainer.target("dr_nodes").request().get(Response.class);
+ System.out.println("GET dr_subs response=" + response.getStatus());
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ }
+
+ @Test
+ public void addDr_Node_shouldReturnError_whenNoLocationAndFqdnProvided() {
+ DR_Node node = new DR_Node(null, null, "hostName", "1.0");
+ Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+ Response response = testContainer.target("dr_nodes")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("dcaeLocation, fqdn", responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Node_shouldReturnError_whenDrNodeWithGiveFqdnAlreadyExists() {
+ DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+ addDrNode(node);
+ Response response = addDrNode(node);
+
+ assertEquals(409, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqdn", responseError.getFields());
+ assertEquals("Node fqdn already exists", responseError.getMessage());
+ }
+
+ @Test
+ public void addDr_Node_shouldExecuteSuccessfully() {
+ DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+ Response response = addDrNode(node);
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ assertDrNodeExistInDB(response.readEntity(DR_Node.class));
+ }
+
+ @Test
+ public void updateDr_Node_shouldReturnError_whenNoLocationAndFqdnProvided() {
+ DR_Node node = new DR_Node(null, null, "hostName", "1.0");
+ Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+ Response response = testContainer.target("dr_nodes")
+ .path("fqdn")
+ .request()
+ .put(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("dcaeLocation, fqdn", responseError.getFields());
+ }
+
+ @Test
+ public void updateDr_Node_shouldReturnError_whenDrNodeForUpdateDoesNotExistInDb() {
+ DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+ Entity<DR_Node> requestedEntity = entity(node, APPLICATION_JSON);
+
+ Response response = testContainer.target("dr_nodes")
+ .path(node.getFqdn())
+ .request()
+ .put(requestedEntity, Response.class);
+
+ assertEquals(404, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqdn", responseError.getFields());
+ assertEquals("Node " + node.getFqdn() + " does not exist", responseError.getMessage());
+ }
+
+ @Test
+ public void updateDr_Node_ShouldExecuteSuccessfully() {
+ DR_Node toUpdate = new DR_Node("fqdn", "location", "hostName", "1.0");
+ Entity<DR_Node> requestedEntity = entity(toUpdate, APPLICATION_JSON);
+
+ addDrNode(new DR_Node("fqdn", "old_location", "old_hostName", "old_1.0"));
+ Response response = testContainer.target("dr_nodes")
+ .path(toUpdate.getFqdn())
+ .request()
+ .put(requestedEntity, Response.class);
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ assertEquals(toUpdate, response.readEntity(DR_Node.class));
+ }
+
+ @Test
+ public void deleteDr_Node_shouldReturnError_whenDrNodeForDeleteDoesNotExistInDb() {
+ Response response = testContainer.target("dr_nodes")
+ .path("fqdn")
+ .request()
+ .delete();
+
+ assertEquals(404, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqdn", responseError.getFields());
+ assertEquals("Node fqdn does not exist", responseError.getMessage());
+ }
+
+ @Test
+ public void deleteDr_Node_shouldReturnError_whenNoExistingFqdnProvided() {
+ Response response = testContainer.target("dr_nodes")
+ .path("")
+ .request()
+ .delete();
+
+ assertEquals(405, response.getStatus());
+ }
+
+ @Test
+ public void deleteDr_Node_shouldExecuteSuccessfully() {
+ DR_Node node = new DR_Node("fqdn", "location", "hostName", "1.0");
+
+ addDrNode(node);
+ Response response = testContainer.target("dr_nodes")
+ .path("fqdn")
+ .request()
+ .delete();
+
+ assertEquals(204, response.getStatus());
+ }
+
+ @Test
+ public void getDr_Node_shouldReturnError_whenDrNodeForDeleteDoesNotExistInDb() {
+ Response response = testContainer.target("dr_nodes")
+ .path("fqdn")
+ .request()
+ .get();
+
+ assertEquals(404, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqdn", responseError.getFields());
+ assertEquals("Node fqdn does not exist", responseError.getMessage());
+ }
+
+ private Response addDrNode(DR_Node node) {
+ return testContainer.target("dr_nodes")
+ .request()
+ .post(entity(node, APPLICATION_JSON), Response.class);
+ }
+
+ private void assertDrNodeExistInDB(DR_Node created) {
+ Response response = testContainer.target("dr_nodes")
+ .path(created.getFqdn())
+ .request()
+ .get();
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ assertEquals(created, response.readEntity(DR_Node.class));
+ }
+
+ @Before
+ public void cleanupDatabase() {
+ DatabaseClass.clearDatabase();
+ }
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_PubResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_PubResourceTest.java
new file mode 100644
index 0000000..340f362
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_PubResourceTest.java
@@ -0,0 +1,291 @@
+
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Pub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+public class DR_PubResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+
+ private static final String DCAE_LOCATION_NAME = "central-onap";
+ private static final String USERNAME = "user1";
+ private static final String USRPWD = "secretW0rd";
+ private static final String FEED_ID = "someFakeFeedId";
+ private static final String PUB_ID = "0";
+ private static FastJerseyTestContainer testContainer;
+ private static TestFeedCreator testFeedCreator;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ //TODO: init is still needed here to assure that dmaap is not null
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(DmaapResource.class)
+ .register(DR_PubResource.class)
+ .register(FeedResource.class));
+
+ testContainer.init();
+ testFeedCreator = new TestFeedCreator(testContainer);
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+ DatabaseClass.clearDatabase();
+ DatabaseClass.getDmaap().remove();*/
+ }
+
+ @Before
+ public void cleanupDatabase() {
+ DatabaseClass.clearDatabase();
+ }
+
+ @Test
+ public void getDr_Pub_test() {
+ Response resp = testContainer.target("dr_pubs").request().get(Response.class);
+ assertTrue(resp.getStatus() == 200);
+ assertTrue(resp.hasEntity());
+ }
+
+ @Test
+ public void addDr_Pub_shallReturnError_whenNoFeedIdAndFeedNameInPubProvided() {
+ //given
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+ Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(400, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedName", responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Pub_shallReturnError_whenFeedNameProvided_butFeedNotExist() {
+ //given
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+ Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+ drPub.setFeedName("feed_name");
+
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(404, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedName", responseError.getFields());
+
+ }
+
+ @Test
+ public void addDr_Pub_shallReturnError_whenFeedIdProvided_butFeedNotExist() {
+ //given
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, FEED_ID, PUB_ID);
+ Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(404, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedId=" + FEED_ID, responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Pub_shallExecuteSuccessfully_whenValidFeedIdProvided() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+ Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(201, resp.getStatus());
+ }
+
+ @Test
+ public void addDr_Pub_shallExecuteSuccessfully_whenValidFeedNameProvided() {
+ //given
+ String feedName = "testFeed";
+ testFeedCreator.addFeed(feedName, "test feed");
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, PUB_ID);
+ drPub.setFeedName(feedName);
+ Entity<DR_Pub> requestedEntity = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(201, resp.getStatus());
+ }
+
+ @Test
+ public void updateDr_Pub_shallExecuteSuccessfully_whenAddingNewPublisher() {
+ //given
+ String pubId = "5";
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "feedId", PUB_ID);
+ Entity<DR_Pub> reqEntity2 = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .path(pubId)
+ .request()
+ .put(reqEntity2, Response.class);
+
+ //then
+ assertEquals(200, resp.getStatus());
+
+ }
+ /*//
+ // When this test is included, the following error is generated:
+ Exception in thread "HTTP-Dispatcher" java.lang.AssertionError: State is not RESPONSE (REQUEST)
+ at jdk.httpserver/sun.net.httpserver.ServerImpl.responseCompleted(ServerImpl.java:814)
+ at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.handleEvent(ServerImpl.java:297)
+ at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:356)
+ at java.base/java.lang.Thread.run(Thread.java:830)
+// I can't figure it out, so created a Jira for now. DMAAP-1358
+ @Test
+ public void updateDr_Pub_shallReturnError_whenPathIsWrong() {
+ //given
+ DR_Pub drPub = new DR_Pub(DCAE_LOCATION_NAME, USERNAME, USRPWD, FEED_ID, PUB_ID);
+ Entity<DR_Pub> reqEntity2 = Entity.entity(drPub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .path("")
+ .request()
+ .put(reqEntity2, Response.class);
+
+ //then
+ assertEquals(405, resp.getStatus());
+ }*/
+ @Test
+ public void deleteDr_Pub_shouldDeleteObjectWithSuccess() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Pub dr_pub = addPub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .path(dr_pub.getPubId())
+ .request()
+ .delete();
+
+ //then
+ assertEquals("Shall delete publisher with success", 204, resp.getStatus());
+ assertFalse("No entity object shall be returned", resp.hasEntity());
+ }
+
+ @Test
+ public void deleteDr_Pub_shouldReturnErrorResponse_whenGivenPubIdNotFound() {
+ //given
+ String notExistingPubId = "6789";
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .path(notExistingPubId)
+ .request()
+ .delete();
+
+ //then
+ assertEquals("Shall return error, when trying to delete not existing publisher", 404, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("pubId", responseError.getFields());
+ }
+
+ @Test
+ public void get_shallReturnExistingObject() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Pub dr_Pub = addPub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+ //when
+ Response resp = testContainer.target("dr_pubs")
+ .path(dr_Pub.getPubId())
+ .request()
+ .get();
+
+ //then
+ assertEquals("Publisher shall be found", 200, resp.getStatus());
+ assertEquals("Retrieved object shall be equal to eh one put into DB", dr_Pub, resp.readEntity(DR_Pub.class));
+ }
+
+ private DR_Pub addPub(String d, String un, String up, String feedId) {
+ DR_Pub dr_pub = new DR_Pub(d, un, up, feedId, "");
+ Entity<DR_Pub> reqEntity2 = Entity.entity(dr_pub, MediaType.APPLICATION_JSON);
+ Response resp = testContainer.target("dr_pubs").request().post(reqEntity2, Response.class);
+ System.out.println("POST dr_pubs resp=" + resp.getStatus());
+ assertTrue(resp.getStatus() == 201);
+ dr_pub = resp.readEntity(DR_Pub.class);
+ return dr_pub;
+ }
+
+ private String assureFeedIsInDB() {
+ Feed feed = testFeedCreator.addFeed("PublisherTestFeed", "feed for DR_Pub testing");
+ assertNotNull("Feed shall be added into DB properly", feed);
+ return feed.getFeedId();
+ }
+
+
+}
+
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_SubResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_SubResourceTest.java
new file mode 100644
index 0000000..13b89ea
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DR_SubResourceTest.java
@@ -0,0 +1,434 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DR_Sub;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+public class DR_SubResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+
+ private static final String DCAE_LOCATION_NAME = "central-onap";
+ private static final String USERNAME = "user1";
+ private static final String USRPWD = "secretW0rd";
+ private static final String DELIVERY_URL = "https://subscriber.onap.org/delivery/id";
+ private static final String LOG_URL = "https://dr-prov/sublog/id";
+ private static final String DELIVERY_URL_TEMPLATE = "https://subscriber.onap.org/delivery/";
+ private static final String LOG_URL_TEMPLATE = "https://dr-prov/sublog/";
+ private static FastJerseyTestContainer testContainer;
+ private static TestFeedCreator testFeedCreator;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ //TODO: init is still needed here to assure that dmaap is not null
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(DR_SubResource.class)
+ .register(FeedResource.class));
+ testContainer.init();
+ testFeedCreator = new TestFeedCreator(testContainer);
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+ DatabaseClass.clearDatabase();
+ DatabaseClass.getDmaap().remove();*/
+ }
+
+ @Before
+ public void cleanupDatabase() {
+ DatabaseClass.clearDatabase();
+ }
+
+ //TODO: figure out generic entity list unmarshall to check the entity list
+ @Test
+ public void getDr_Subs_test() {
+ Response resp = testContainer.target("dr_subs").request().get(Response.class);
+ System.out.println("GET dr_subs resp=" + resp.getStatus());
+
+ assertEquals(200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ }
+
+ @Test
+ public void addDr_Sub_shallReturnError_whenNoFeedIdAndFeedNameInSubProvided() {
+ //given
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(400, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedName", responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Sub_shallReturnError_whenFeedNameProvided_butFeedNotExist() {
+ //given
+ String notExistingFeedName = "notRealFead";
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+ drSub.setFeedName(notExistingFeedName);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(404, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedName", responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Sub_shallReturnError_whenFeedNameProvided_andManyFeedsWithTheSameNameInDB() {
+ //given
+ String notDistinctFeedName = "notDistinctFeedName";
+ Feed feed1 = new Feed(notDistinctFeedName, "1.0", "description", "dgl", "unrestricted");
+ Feed feed2 = new Feed(notDistinctFeedName, "2.0", "description", "dgl", "unrestricted");
+ DatabaseClass.getFeeds().put("1", feed1);
+ DatabaseClass.getFeeds().put("2", feed2);
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+ drSub.setFeedName(notDistinctFeedName);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(409, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedName", responseError.getFields());
+ }
+
+ @Test
+ public void addDr_Sub_shallReturnError_whenFeedIdProvided_butFeedNotExist() {
+ //given
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "someFakeFeedId", DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(404, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertTrue(responseError.getFields().contains("feedId"));
+ }
+
+ @Test
+ public void addDr_Sub_shallExecuteSuccessfully_whenValidFeedIdProvided() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId, DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ DR_Sub created = resp.readEntity(DR_Sub.class);
+ assertSubscriptionExistInDB(created);
+ }
+
+ @Test
+ public void addDr_Sub_shallExecuteSuccessfully_whenValidFeedNameProvided() {
+ //given
+ String feedName = "testFeed";
+ testFeedCreator.addFeed(feedName, "test feed");
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+ drSub.setFeedName(feedName);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ DR_Sub created = resp.readEntity(DR_Sub.class);
+ assertSubscriptionExistInDB(created);
+ }
+
+
+ @Test
+ public void updateDr_Sub_shallReturnError_whenNoFeedIdInSubProvided() {
+ //given
+ String subId = "1234";
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, null, DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(subId)
+ .request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(400, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("feedId", responseError.getFields());
+ }
+
+ @Test
+ public void updateDr_Sub_shallReturnError_whenNoDCAELocationInSubProvided() {
+ //given
+ String subId = "1234";
+ DR_Sub drSub = new DR_Sub(null, USERNAME, USRPWD, "someFeedId", DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(subId)
+ .request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(400, resp.getStatus());
+ ApiError responseError = resp.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("dcaeLocationName", responseError.getFields());
+ }
+
+ @Test
+ public void updateDr_Sub_shallReturnError_whenFeedWithGivenIdInSubNotExists() {
+ //given
+ String subId = "1234";
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, "someFeedId", DELIVERY_URL, LOG_URL, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(subId)
+ .request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(404, resp.getStatus());
+ assertNotNull(resp.readEntity(ApiError.class));
+ }
+
+ @Test
+ public void updateDr_Sub_shallReturnSuccess_whenAddingNewSubscription() {
+ //given
+ String subId = "31";
+ String feedId = assureFeedIsInDB();
+ DR_Sub drSub = new DR_Sub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId, null, null, true);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSub, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(subId)
+ .request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(200, resp.getStatus());
+
+ DR_Sub createdDrSub = resp.readEntity(DR_Sub.class);
+ assertNotNull(createdDrSub.getLastMod());
+ assertEquals(subId, createdDrSub.getSubId());
+ assertEquals(DCAE_LOCATION_NAME, createdDrSub.getDcaeLocationName());
+ assertEquals(USERNAME, createdDrSub.getUsername());
+ assertEquals(USRPWD, createdDrSub.getUserpwd());
+ assertEquals(DELIVERY_URL_TEMPLATE + subId, createdDrSub.getDeliveryURL());
+ assertEquals(LOG_URL_TEMPLATE + subId, createdDrSub.getLogURL());
+
+ assertSubscriptionExistInDB(createdDrSub);
+ }
+
+ @Test
+ public void updateDr_Sub_shallReturnSuccess_whenUpdatingExistingSubscription() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Sub existingDrSub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+ DR_Sub drSubUpdate = new DR_Sub("newDcaeLocationName", "newUserName", "newUserPwd", feedId, null, null, false);
+ Entity<DR_Sub> requestedEntity = Entity.entity(drSubUpdate, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(existingDrSub.getSubId())
+ .request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(200, resp.getStatus());
+
+ DR_Sub updatedDrSub = resp.readEntity(DR_Sub.class);
+ assertNotNull(updatedDrSub.getLastMod());
+ assertEquals(existingDrSub.getSubId(), updatedDrSub.getSubId());
+ assertEquals(drSubUpdate.getDcaeLocationName(), updatedDrSub.getDcaeLocationName());
+ assertEquals(drSubUpdate.getUsername(), updatedDrSub.getUsername());
+ assertEquals(drSubUpdate.getUserpwd(), updatedDrSub.getUserpwd());
+ assertEquals(DELIVERY_URL_TEMPLATE + existingDrSub.getSubId(), updatedDrSub.getDeliveryURL());
+ assertEquals(LOG_URL_TEMPLATE + existingDrSub.getSubId(), updatedDrSub.getLogURL());
+
+ assertSubscriptionExistInDB(updatedDrSub);
+ }
+
+ @Test
+ public void deleteDr_Sub_shouldDeleteSubscriptionWithSuccess() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Sub dr_sub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(dr_sub.getSubId())
+ .request()
+ .delete();
+
+ //then
+ assertEquals("Shall delete subscription with success", 204, resp.getStatus());
+ assertFalse("No entity object shall be returned",resp.hasEntity());
+ assertSubscriptionNotExistInDB(dr_sub.getSubId());
+ }
+
+ @Test
+ public void deleteDr_Sub_shouldReturnErrorResponse_whenGivenSubIdNotFound() {
+ //given
+ String notExistingSubId = "6789";
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(notExistingSubId)
+ .request()
+ .delete();
+
+ //then
+ assertEquals("Shall return error, when trying to delete not existing subscription", 404, resp.getStatus());
+ assertNotNull(resp.readEntity(ApiError.class));
+ }
+
+ @Test
+ public void get_shallReturnExistingObject() {
+ //given
+ String feedId = assureFeedIsInDB();
+ DR_Sub dr_sub = addSub(DCAE_LOCATION_NAME, USERNAME, USRPWD, feedId);
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(dr_sub.getSubId())
+ .request()
+ .get();
+
+ //ten
+ assertEquals("Subscription shall be found",200, resp.getStatus());
+ assertEquals("Retrieved object shall be equal to eh one put into DB", dr_sub, resp.readEntity(DR_Sub.class));
+ }
+
+ @Test
+ public void get_shouldReturnError_whenSubWithIdNotFound() {
+ //given
+ String notExistingSubId = "1234";
+
+ //when
+ Response resp = testContainer.target("dr_subs")
+ .path(notExistingSubId)
+ .request()
+ .get();
+
+ //then
+ assertEquals("Subscription shall not be found", 404, resp.getStatus());
+ assertNotNull(resp.readEntity(ApiError.class));
+ }
+
+ private DR_Sub addSub(String d, String un, String up, String feedId) {
+ DR_Sub dr_sub = new DR_Sub(d, un, up, feedId,
+ "https://subscriber.onap.org/foo", "https://dr-prov/sublog", true);
+
+ Entity<DR_Sub> reqEntity2 = Entity.entity(dr_sub, MediaType.APPLICATION_JSON);
+ Response resp = testContainer.target("dr_subs").request().post(reqEntity2, Response.class);
+ System.out.println("POST dr_subs resp=" + resp.getStatus());
+ assertEquals(201, resp.getStatus());
+ dr_sub = resp.readEntity(DR_Sub.class);
+
+ return dr_sub;
+ }
+
+ private String assureFeedIsInDB() {
+ Feed feed = testFeedCreator.addFeed("SubscriberTestFeed", "feed for DR_Sub testing");
+ assertNotNull("Feed shall be added into DB properly", feed);
+ return feed.getFeedId();
+ }
+
+
+ private void assertSubscriptionNotExistInDB(String subId) {
+ assertEquals(404, testContainer.target("dr_subs")
+ .path(subId)
+ .request()
+ .get()
+ .getStatus());
+ }
+
+ private void assertSubscriptionExistInDB(DR_Sub sub) {
+ Response response = testContainer.target("dr_subs")
+ .path(sub.getSubId())
+ .request()
+ .get();
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ assertEquals(sub, response.readEntity(DR_Sub.class));
+ }
+}
+
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResourceTest.java
new file mode 100644
index 0000000..ff07927
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DcaeLocationResourceTest.java
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.Path;
+import javax.ws.rs.GET;
+
+
+public class DcaeLocationResourceTest extends JerseyTest {
+
+ static DmaapObjectFactory factory = new DmaapObjectFactory();
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig( DcaeLocationResource.class );
+ }
+
+ private static final String fmt = "%24s: %s%n";
+
+
+
+/* may conflict with test framework!
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+*/
+
+
+
+ @Test
+ public void GetTest() {
+ Response resp = target( "dcaeLocations").request().get( Response.class );
+ System.out.println( "GET feed resp=" + resp.getStatus() );
+
+ assertTrue( resp.getStatus() == 200 );
+ }
+ @Test
+ public void PostTest() {
+ DcaeLocation loc = factory.genDcaeLocation( "central" );
+ Entity<DcaeLocation> reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
+ Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
+ System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
+ if ( resp.getStatus() != 409 ) {
+ assertTrue( resp.getStatus() == 201 );
+ }
+
+ resp = target( "dcaeLocations").
+ path( loc.getDcaeLocationName()).request().get( Response.class );
+ System.out.println( "GET feed resp=" + resp.getStatus() );
+
+ assertTrue( resp.getStatus() == 200 );
+ }
+
+ @Test
+ public void PutTest() {
+ DcaeLocation loc = factory.genDcaeLocation( "edge" );
+ Entity<DcaeLocation> reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
+ Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
+ System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
+ if ( resp.getStatus() != 409 ) {
+ assertTrue( resp.getStatus() == 201 );
+ }
+
+
+ loc.setClli("ATLCTYNJ9999");
+ reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
+ resp = target( "dcaeLocations").
+ path( loc.getDcaeLocationName()).request().put( reqEntity, Response.class );
+ System.out.println( "PUT dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
+ assertTrue( resp.getStatus() == 201 );
+
+ }
+
+ @Test
+ public void DelTest() {
+ DcaeLocation loc = factory.genDcaeLocation( "edge" );
+ Entity<DcaeLocation> reqEntity = Entity.entity( loc, MediaType.APPLICATION_JSON );
+ Response resp = target( "dcaeLocations").request().post( reqEntity, Response.class );
+ System.out.println( "POST dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
+ if ( resp.getStatus() != 409 ) {
+ assertTrue( resp.getStatus() == 201 );
+ }
+
+ resp = target( "dcaeLocations").
+ path( loc.getDcaeLocationName()).request().delete( Response.class );
+ System.out.println( "DELETE dcaeLocation resp=" + resp.getStatus() + " " + resp.readEntity( String.class ) );
+ assertTrue( resp.getStatus() == 204 );
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DmaapResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DmaapResourceTest.java
new file mode 100644
index 0000000..29ccb40
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/DmaapResourceTest.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+
+public class DmaapResourceTest extends JerseyTest {
+
+ static DmaapObjectFactory factory = new DmaapObjectFactory();
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig( DmaapResource.class );
+ //return new ResourceConfig( HelloResource.class );
+ }
+
+ private static final String fmt = "%24s: %s%n";
+
+
+
+/* may conflict with test framework!
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+*/
+
+
+
+ @Test
+ public void GetTest() {
+ Response resp = target( "dmaap").request().get( Response.class );
+ assertTrue( resp.getStatus() == 200 );
+ }
+ @Test
+ public void PostTest() {
+
+ Dmaap dmaap = factory.genDmaap();
+ Entity<Dmaap> reqEntity = Entity.entity( dmaap, MediaType.APPLICATION_JSON );
+ Response resp = target( "dmaap").request().post( reqEntity, Response.class );
+ System.out.println( resp.getStatus() );
+ assertTrue( resp.getStatus() == 200 );
+ }
+
+ @Test
+ public void PutTest() {
+
+ Dmaap dmaap = factory.genDmaap();
+ Entity<Dmaap> reqEntity = Entity.entity( dmaap, MediaType.APPLICATION_JSON );
+
+ dmaap.setVersion( "2" );
+ Response resp = target( "dmaap").request().put( reqEntity, Response.class );
+ System.out.println( resp.getStatus() );
+ assertTrue( resp.getStatus() == 200 );
+ }
+
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java
new file mode 100644
index 0000000..8d38a9f
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FastJerseyTestContainer.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import org.glassfish.jersey.test.JerseyTest;
+
+import javax.ws.rs.core.Application;
+
+class FastJerseyTestContainer extends JerseyTest {
+
+ FastJerseyTestContainer(Application jaxrsApplication) {
+ super(jaxrsApplication);
+ }
+
+ void init() throws Exception {
+ this.setUp();
+ }
+
+ void destroy() throws Exception {
+ this.tearDown();
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FeedResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FeedResourceTest.java
new file mode 100644
index 0000000..89dca8a
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/FeedResourceTest.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.service.*;
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.*;
+import java.sql.*;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.Path;
+import javax.ws.rs.GET;
+
+
+public class FeedResourceTest extends JerseyTest {
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig( FeedResource.class );
+ }
+
+ private static final String fmt = "%24s: %s%n";
+
+
+
+/* may conflict with test framework!
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+*/
+
+
+
+ @Test
+ public void GetTest() {
+ Response resp = target( "feeds").request().get( Response.class );
+ System.out.println( "GET feed resp=" + resp.getStatus() );
+
+ assertTrue( resp.getStatus() == 200 );
+ }
+ @Test
+ public void PostTest() {
+ Feed feed = new Feed( "aPostTest", "1.0", "a unit test", "dgl", "unrestricted" );
+ Entity<Feed> reqEntity = Entity.entity( feed, MediaType.APPLICATION_JSON );
+ Response resp = target( "feeds").request().post( reqEntity, Response.class );
+ System.out.println( "POST feed resp=" + resp.getStatus() );
+ assertTrue( resp.getStatus() == 200 );
+ }
+
+/*
+ @Test
+ public void PutTest() {
+
+ Feed feed = new Feed( "aPutTest", "1.0", "a unit test", "dgl", "unrestricted" );
+ Entity<Feed> reqEntity = Entity.entity( feed, MediaType.APPLICATION_JSON );
+ Response resp = target( "feeds").request().post( reqEntity, Response.class );
+ System.out.println( "POST feed resp=" + resp.getStatus() );
+ String postResp = resp.readEntity( String.class );
+ System.out.println( "postResp=" + postResp );
+ Feed rFeed = new Feed( postResp ); getting a null pointer here
+ rFeed.setSuspended( true );
+ String target = new String ("feeds/" + rFeed.getFeedId() );
+ System.out.println( "PUT feed target=" + target );
+ reqEntity = Entity.entity( rFeed, MediaType.APPLICATION_JSON );
+ resp = target( target ).request().put( reqEntity, Response.class );
+ System.out.println( "PUT feed resp=" + resp.getStatus() );
+ assertTrue( resp.getStatus() == 200 );
+ }
+*/
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/InfoResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/InfoResourceTest.java
new file mode 100644
index 0000000..3f57f58
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/InfoResourceTest.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.service.*;
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.*;
+import java.sql.*;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.Path;
+import javax.ws.rs.GET;
+
+
+public class InfoResourceTest extends JerseyTest {
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig( InfoResource.class );
+ }
+
+ private static final String fmt = "%24s: %s%n";
+
+
+
+/* may conflict with test framework!
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+*/
+
+
+
+ @Test
+ public void GetTest() {
+ Response resp = target( "info").request().get( Response.class );
+ assertTrue( resp.getStatus() == 204 );
+ }
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClientResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClientResourceTest.java
new file mode 100644
index 0000000..abe2e45
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClientResourceTest.java
@@ -0,0 +1,304 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.resources;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class MR_ClientResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+ private static FastJerseyTestContainer testContainer;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(MR_ClientResource.class).register(MR_ClusterResource.class).register(TopicResource.class));
+ testContainer.init();
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+ DatabaseClass.getDmaap().remove();
+ DatabaseClass.clearDatabase();*/
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhenNoFqtnProvided() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation", null, "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqtn", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhenNoLocationProvided() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client(null, "fqtn", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("dcaeLocationName", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhenNoClientRoleProvided() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation", "fqtn", null, new String[]{"GET"}), APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("clientRole or clientIdentity", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhenNoActionsProvided() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation", "fqtn", "clientRole", null), APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("action", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhereThereIsNoMrClusterAvailable() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocationName", "fqtn", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("dcaeLocationName", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldReturnErrorWhereThereIsNoTopicForFqtnAvailable() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation", "fqtn", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ createMrCluster(new MR_Cluster("dcaeLocation", "fqdn", "protocol", "port"));
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(404, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqtn", responseError.getFields());
+ }
+
+ @Test
+ public void addMr_Client_shouldAddMrClient() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation2", "testTopic", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ createMrCluster(new MR_Cluster("dcaeLocation2", "fqdn", "protocol", "port"));
+ createTopic("testTopic");
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ assertMRClientExistInDB(response.readEntity(MR_Client.class));
+ }
+
+ @Test
+ public void deleteMr_Client_shouldDeleteMrClient() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation3", "testTopic", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+ createMrCluster(new MR_Cluster("dcaeLocation3", "fqdn", "protocol", "port"));
+ createTopic("testTopic");
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+ assertEquals(200, response.getStatus());
+
+ MR_Client mrClientEntity = response.readEntity(MR_Client.class);
+ Response deleteResponse = testContainer.target("mr_clients")
+ .path(mrClientEntity.getMrClientId())
+ .request()
+ .delete();
+
+ assertEquals(204, deleteResponse.getStatus());
+ assertMrClientNotExistInDB(mrClientEntity.getMrClientId());
+ }
+
+ @Test
+ public void deleteMr_Clients_shouldReturnMethodNotAllowedCodeWhenClientIdIsMissing() {
+ Response deleteResponse = testContainer.target("mr_clients")
+ .request()
+ .delete();
+
+ assertEquals(405, deleteResponse.getStatus());
+ }
+
+ @Test
+ public void getMr_Client_shouldReturnErrorWhenThereIsNoClient() {
+ Response response = testContainer.target("mr_clients")
+ .path("not_existing_id")
+ .request()
+ .get();
+
+ assertEquals(404, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("mrClientId", responseError.getFields());
+ }
+
+ @Test
+ public void updateMr_Client_shouldReturnErrorWhenNoFqtnProvided() {
+ MR_Client mrClient = new MR_Client("dcaeLocation", null, "clientRole", new String[]{"GET"});
+ Entity<MR_Client> requestedEntity = entity(mrClient, APPLICATION_JSON);
+
+ Response response = testContainer.target("mr_clients")
+ .path(mrClient.getMrClientId())
+ .request()
+ .put(requestedEntity, Response.class);
+
+ assertEquals(400, response.getStatus());
+ ApiError responseError = response.readEntity(ApiError.class);
+ assertNotNull(responseError);
+ assertEquals("fqtn", responseError.getFields());
+ }
+
+ @Test
+ public void updateMr_Client_shouldUpdate() {
+ Entity<MR_Client> requestedEntity = entity(
+ new MR_Client("dcaeLocation4", "testTopic", "clientRole", new String[]{"GET"}), APPLICATION_JSON);
+
+ createMrCluster(new MR_Cluster("dcaeLocation4", "fqdn", "protocol", "port"));
+ createTopic("testTopic");
+
+ Response response = testContainer.target("mr_clients")
+ .request()
+ .post(requestedEntity, Response.class);
+ MR_Client createdMrClient = response.readEntity(MR_Client.class);
+ createdMrClient.setDcaeLocationName("updatedDcaeLocation");
+
+
+ Response updateResponse = testContainer.target("mr_clients")
+ .path(createdMrClient.getMrClientId())
+ .request()
+ .put(requestedEntity, Response.class);
+
+ assertEquals(200, updateResponse.getStatus());
+ assertTrue(updateResponse.hasEntity());
+ assertMRClientExistInDB(updateResponse.readEntity(MR_Client.class));
+
+ }
+
+ @Test
+ public void getMr_Clients_test() {
+ Response response = testContainer.target("mr_clients").request().get(Response.class);
+ System.out.println("GET dr_subs response=" + response.getStatus());
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ }
+
+
+ private void createMrCluster(MR_Cluster cluster) {
+ Response response = testContainer.target("mr_clusters")
+ .request()
+ .post(entity(cluster, APPLICATION_JSON), Response.class);
+ assertEquals(201, response.getStatus());
+ }
+
+ private void createTopic(String tname) {
+ Topic topic = new Topic();
+ topic.setFqtn(tname);
+ topic.setFqtn(tname);
+ DatabaseClass.getTopics().put(topic.getFqtn(), topic);
+ }
+
+ private void assertMRClientExistInDB(MR_Client created) {
+ Response response = testContainer.target("mr_clients")
+ .path(created.getMrClientId())
+ .request()
+ .get();
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ MR_Client receivedMrClient = response.readEntity(MR_Client.class);
+ assertEquals(created.getFqtn(), receivedMrClient.getFqtn());
+ assertEquals(created.getDcaeLocationName(), receivedMrClient.getDcaeLocationName());
+ }
+
+ private void assertMrClientNotExistInDB(String clientId) {
+ assertEquals(404, testContainer.target("mr_clients")
+ .path(clientId)
+ .request()
+ .get()
+ .getStatus());
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResourceTest.java
new file mode 100644
index 0000000..9027f13
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/MR_ClusterResourceTest.java
@@ -0,0 +1,284 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.eclipse.jetty.http.HttpStatus;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+public class MR_ClusterResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+ private static FastJerseyTestContainer testContainer;
+ private static final String MR_CLUSTERS_TARGET = "mr_clusters";
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(MR_ClusterResource.class).register(DcaeLocationResource.class));
+ testContainer.init();
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ /*TODO: Cannot cleanup yet until still other Resources tests depends on the static DB content
+
+ DatabaseClass.getDmaap().remove();
+ DatabaseClass.clearDatabase();*/
+ }
+
+ @Before
+ public void setUpClusterAndLocation() {
+ DatabaseClass.clearDatabase();
+ }
+
+ @Test
+ public void getMrClusters_shouldReturnEmptyList_whenNoMrClustersInDataBase() {
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+
+ List<MR_Cluster> mrClusters = resp.readEntity(new GenericType<List<MR_Cluster>>() {
+ });
+ assertTrue(mrClusters.isEmpty());
+ }
+
+ @Test
+ public void addMrCluster_shouldReturnValidationError_whenDcaeLocationNameNotProvided() {
+ //given
+ Entity<MR_Cluster> requestEntity = entity(new MR_Cluster(), APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).request().post(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("dcaeLocationName", errorObj.getFields());
+ }
+
+ @Test
+ public void addMrCluster_shouldReturnValidationError_whenFqdnNotProvided() {
+ //given
+ MR_Cluster mr_cluster = new MR_Cluster();
+ mr_cluster.setDcaeLocationName("central-cloud");
+ Entity<MR_Cluster> requestEntity = entity(mr_cluster, APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).request().post(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("fqdn", errorObj.getFields());
+ }
+
+ @Test
+ public void addMrCluster_shouldAddMrClusterToDatabase() {
+ //given
+ MR_Cluster mrCluster = DMAAP_OBJECT_FACTORY.genMR_Cluster("edge");
+ Entity<MR_Cluster> requestEntity = entity(mrCluster, APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).request().post(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ MR_Cluster respEntity = resp.readEntity(MR_Cluster.class);
+ assertTrue(respEntity.isStatusValid());
+ }
+
+ @Test
+ public void addMrCluster_shouldReturnInvalidMrCluster_whenClusterCannotBeAddedToDatabase() {
+ //given
+ MR_Cluster mrCluster = DMAAP_OBJECT_FACTORY.genMR_Cluster("central");
+ Entity<MR_Cluster> requestEntity = entity(mrCluster, APPLICATION_JSON);
+ prepareDcaeLocationForCentralCluster();
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).request().post(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ MR_Cluster respEntity = resp.readEntity(MR_Cluster.class);
+ assertFalse(respEntity.isStatusValid());
+ }
+
+ private void prepareDcaeLocationForCentralCluster() {
+ DcaeLocation centralDcaeLoc = DMAAP_OBJECT_FACTORY.genDcaeLocation("central");
+ centralDcaeLoc.setStatus(DmaapObject_Status.VALID);
+ DatabaseClass.getDcaeLocations().put(centralDcaeLoc.getDcaeLocationName(), centralDcaeLoc);
+ }
+
+ @Test
+ public void updateMrCluster_shouldReturnValidationError_whenDcaeLocationNameNotProvided() {
+ //given
+ Entity<MR_Cluster> requestEntity = entity(new MR_Cluster(), APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path("clusterId")
+ .request().put(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("dcaeLocationName", errorObj.getFields());
+ }
+
+ @Test
+ public void updateMrCluster_shouldReturnApiError_whenMrClusterWithGivenIdNotFound() {
+ //given
+ MR_Cluster mr_cluster = new MR_Cluster();
+ mr_cluster.setDcaeLocationName("central-cloud");
+ Entity<MR_Cluster> requestEntity = entity(mr_cluster, APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path("notExistingMrCluster")
+ .request().put(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.NOT_FOUND_404, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("dcaeLocationName", errorObj.getFields());
+ }
+
+ @Test
+ public void updateMrCluster_shouldUpdateClusterInDatabase() {
+ //given
+ String newReplicationGroup = "someNewReplicationGroup";
+ prepareDcaeLocationForEdgeCluster();
+ String clusterId = provideExistingEdgeMRClusterId();
+ MR_Cluster changedMrCluster = DMAAP_OBJECT_FACTORY.genMR_Cluster("edge");
+ changedMrCluster.setReplicationGroup(newReplicationGroup);
+ Entity<MR_Cluster> requestEntity = entity(changedMrCluster, APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path(clusterId)
+ .request().put(requestEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ MR_Cluster respEntity = resp.readEntity(MR_Cluster.class);
+ assertTrue(respEntity.isStatusValid());
+ assertEquals(newReplicationGroup, respEntity.getReplicationGroup());
+ }
+
+ private void prepareDcaeLocationForEdgeCluster() {
+ DcaeLocation edgeDcaeLoc = DMAAP_OBJECT_FACTORY.genDcaeLocation("edge");
+ edgeDcaeLoc.setStatus(DmaapObject_Status.VALID);
+ DatabaseClass.getDcaeLocations().put(edgeDcaeLoc.getDcaeLocationName(), edgeDcaeLoc);
+ }
+
+ private String provideExistingEdgeMRClusterId() {
+ MR_Cluster cluster = DMAAP_OBJECT_FACTORY.genMR_Cluster("edge");
+ cluster.setStatus(DmaapObject_Status.VALID);
+ DatabaseClass.getMr_clusters().put(cluster.getDcaeLocationName(), cluster);
+ return cluster.getDcaeLocationName();
+ }
+
+ @Test
+ public void deleteMr_Cluster_shouldReturnApiError_whenTryingToDeleteNotExistingMrCluster() {
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path("notExistingClusterId")
+ .request().delete(Response.class);
+
+ //then
+ assertEquals(HttpStatus.NOT_FOUND_404, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("dcaeLocationName", errorObj.getFields());
+ }
+
+ @Test
+ public void deleteMr_Cluster_shouldRemoveMrClusterFromDatabase() {
+ //given
+ String clusterId = provideExistingEdgeMRClusterId();
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path(clusterId)
+ .request().delete(Response.class);
+
+ //then
+ assertEquals(HttpStatus.NO_CONTENT_204, resp.getStatus());
+ assertFalse(resp.hasEntity());
+ }
+
+ @Test
+ public void getMr_Cluster_shouldReturnApiError_whenTryingToGetNotExistingMrCluster() {
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path("notExistingClusterId")
+ .request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("dcaeLocationName", errorObj.getFields());
+ }
+
+ @Test
+ public void getMr_Cluster_shouldReturnExistingMrCluster() {
+ //given
+ String clusterId = provideExistingEdgeMRClusterId();
+
+ //when
+ Response resp = testContainer.target(MR_CLUSTERS_TARGET).path(clusterId)
+ .request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ MR_Cluster mrCluster = resp.readEntity(MR_Cluster.class);
+ assertEquals(clusterId, mrCluster.getDcaeLocationName());
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java
new file mode 100644
index 0000000..0c88c0c
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequestTimeLogFilterTest.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import com.att.eelf.configuration.EELFLogger;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RequestTimeLogFilterTest {
+
+ private Clock clock ;
+ private RequestTimeLogFilter requestTimeLogFilter;
+ public static final long START = 1L;
+ @Mock
+ private ContainerRequestContext requestContext;
+ @Mock
+ private ContainerResponseContext responseContext;
+ @Mock
+ private EELFLogger logger;
+
+
+ @Before
+ public void setup() {
+ clock = Clock.fixed(Instant.parse("1970-01-01T00:00:10Z"), ZoneId.systemDefault());
+ requestTimeLogFilter = new RequestTimeLogFilter(logger, clock);
+ }
+
+ @Test
+ public void shouldHaveDefaultConstructor() {
+ assertNotNull(new RequestTimeLogFilter());
+ }
+
+ @Test
+ public void filterShouldSetStartTimestampProperty() {
+ requestTimeLogFilter.filter(requestContext);
+ verify(requestContext).setProperty("start",clock.millis());
+ }
+
+ @Test
+ public void filterShouldPrintElapsedTime() {
+ when(requestContext.getProperty("start")).thenReturn(START);
+
+ requestTimeLogFilter.filter(requestContext, responseContext);
+
+ verify(logger).info(anyString(),eq(clock.millis() - START));
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java
new file mode 100644
index 0000000..f07058b
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredCheckerTest.java
@@ -0,0 +1,86 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA 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.onap.dmaap.dbcapi.resources;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static org.junit.Assert.fail;
+
+public class RequiredCheckerTest {
+
+ private static final String NAME = "field_name";
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+ private RequiredChecker requiredChecker = new RequiredChecker();
+
+
+ @Test
+ public void required_shouldThrowExceptionWhenObjectIsNull() throws RequiredFieldException {
+ thrown.expect(RequiredFieldException.class);
+ thrown.expect(new ApiErrorMatcher(new ApiError(BAD_REQUEST.getStatusCode(),
+ "missing required field", NAME)));
+
+ requiredChecker.required(NAME, null);
+ }
+
+ @Test
+ public void required_shouldThrowExceptionWhenRegexValidationFailed() throws RequiredFieldException {
+ thrown.expect(RequiredFieldException.class);
+ thrown.expect(new ApiErrorMatcher(new ApiError(BAD_REQUEST.getStatusCode(),
+ "value 'with white space' violates regexp check '^\\S+$'", NAME)));
+
+ requiredChecker.required(NAME, "with white space", "^\\S+$");
+ }
+
+ @Test
+ public void required_shouldPassValidation() {
+ try {
+ requiredChecker.required(NAME, "value", "^\\S+$");
+ } catch (RequiredFieldException e) {
+ fail("No exception should be thrown");
+ }
+ }
+
+ class ApiErrorMatcher extends BaseMatcher {
+
+ private final ApiError expectedApiEror;
+
+ ApiErrorMatcher(ApiError expectedApiEror) {
+ this.expectedApiEror = expectedApiEror;
+ }
+
+ @Override
+ public boolean matches(Object exception) {
+ return expectedApiEror.equals(((RequiredFieldException) exception).getApiError());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Following ApiError is expected: ").appendValue(expectedApiEror);
+ }
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java
new file mode 100644
index 0000000..d3dcc42
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/RequiredFieldExceptionTest.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * ===================================================================
+ * 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.onap.dmaap.dbcapi.resources;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+public class RequiredFieldExceptionTest {
+ ApiError apiError;
+ RequiredFieldException requiredFieldException;
+ String expectedValue;
+
+ @Before
+ public void setUp() {
+ apiError = new ApiError(BAD_REQUEST.getStatusCode(), "value 'with white space' violates regexp check '^\\S+$'",
+ "field_name");
+
+ expectedValue = "RequiredFieldException{" + "apiError=" + apiError + '}';
+
+ requiredFieldException = new RequiredFieldException(apiError);
+ }
+
+ @Test
+ public void testRequiredFieldExceptionToString() {
+ assertEquals(expectedValue, requiredFieldException.toString());
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java
new file mode 100644
index 0000000..ff61d14
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/ResponseBuilderTest.java
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA 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.onap.dmaap.dbcapi.resources;
+
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
+import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
+import static org.junit.Assert.assertEquals;
+
+public class ResponseBuilderTest {
+
+ private static final String OBJECT = "Objcect";
+ private static final String MESSAGE = "msg";
+ private static final int CODE = 100;
+ private ResponseBuilder responseBuilder = new ResponseBuilder();
+
+ @Test
+ public void success_shouldCreateResponseWithOKStatusCode() {
+
+ Response response = responseBuilder.success(OBJECT);
+
+ assertEquals(OBJECT, response.getEntity());
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void success_shouldCreateResponseWithDefinedStatusCode() {
+
+ Response response = responseBuilder.success(CODE, OBJECT);
+
+ assertEquals(OBJECT, response.getEntity());
+ assertEquals(CODE, response.getStatus());
+ }
+
+ @Test
+ public void unauthorized_shouldCreateCorrectResponse() {
+
+ ApiError error = new ApiError(UNAUTHORIZED.getStatusCode(), MESSAGE, "Authorization");
+ Response response = responseBuilder.unauthorized(MESSAGE);
+
+ assertEquals(error, response.getEntity());
+ assertEquals(error.getCode(), response.getStatus());
+ }
+
+ @Test
+ public void unavailable_shouldCreateCorrectResponse() {
+
+ ApiError error = new ApiError(SERVICE_UNAVAILABLE.getStatusCode(),
+ "Request is unavailable due to unexpected condition");
+ Response response = responseBuilder.unavailable();
+
+ assertEquals(error, response.getEntity());
+ assertEquals(error.getCode(), response.getStatus());
+ }
+
+ @Test
+ public void notFound_shouldCreateCorrectResponse() {
+ ApiError error = new ApiError(NOT_FOUND.getStatusCode(), "Requested object not found");
+ Response response = responseBuilder.notFound();
+
+ assertEquals(error, response.getEntity());
+ assertEquals(error.getCode(), response.getStatus());
+ }
+
+ @Test
+ public void error_shouldCreateCorrectResponse() {
+ ApiError error = new ApiError(CODE, "Some Error");
+ Response response = responseBuilder.error(error);
+
+ assertEquals(error, response.getEntity());
+ assertEquals(error.getCode(), response.getStatus());
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java
new file mode 100644
index 0000000..e4dedb1
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TestFeedCreator.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.onap.dmaap.dbcapi.model.Feed;
+
+
+public class TestFeedCreator {
+
+
+ private final FastJerseyTestContainer testContainer;
+
+ public TestFeedCreator(FastJerseyTestContainer testContainer) {
+ this.testContainer = testContainer;
+ }
+
+ Feed addFeed(String name, String desc) {
+ Feed feed = new Feed(name, "1.0", desc, "dgl", "unrestricted");
+ Entity<Feed> reqEntity = Entity.entity(feed, MediaType.APPLICATION_JSON);
+ Response resp = testContainer.target("feeds").request().post(reqEntity, Response.class);
+ int rc = resp.getStatus();
+ System.out.println("POST feed resp=" + rc);
+ assertTrue(rc == 200 || rc == 409);
+ feed = resp.readEntity(Feed.class);
+ return feed;
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TopicResourceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TopicResourceTest.java
new file mode 100644
index 0000000..5b7c46d
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/resources/TopicResourceTest.java
@@ -0,0 +1,356 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.database.DatabaseClass;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.model.FqtnType;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.ReplicationType;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+
+public class TopicResourceTest {
+
+ private static final DmaapObjectFactory DMAAP_OBJECT_FACTORY = new DmaapObjectFactory();
+ private static final String TOPICS_TARGET = "topics";
+
+ private static FastJerseyTestContainer testContainer;
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ //TODO: init is still needed here to assure that dmaap is not null
+ DatabaseClass.getDmaap().init(DMAAP_OBJECT_FACTORY.genDmaap());
+
+ testContainer = new FastJerseyTestContainer(new ResourceConfig()
+ .register(TopicResource.class));
+ testContainer.init();
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ testContainer.destroy();
+ }
+
+ @Before
+ public void setUpClusterAndLocation() {
+ DatabaseClass.clearDatabase();
+
+ DcaeLocation centralDcaeLoc = DMAAP_OBJECT_FACTORY.genDcaeLocation("central");
+ centralDcaeLoc.setStatus(DmaapObject_Status.VALID);
+ DatabaseClass.getDcaeLocations().put(centralDcaeLoc.getDcaeLocationName(), centralDcaeLoc);
+
+ MR_Cluster cluster = DMAAP_OBJECT_FACTORY.genMR_Cluster("central");
+ cluster.setStatus(DmaapObject_Status.VALID);
+ DatabaseClass.getMr_clusters().put(cluster.getDcaeLocationName(), cluster);
+ }
+
+ @Test
+ public void getTopics_shouldReturnEmptyList_whenNoTopicsInDataBase() {
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+
+ List<Topic> topics = resp.readEntity(new GenericType<List<Topic>>() {
+ });
+ assertTrue(topics.isEmpty());
+ }
+
+ @Test
+ public void getTopics_shouldReturnTopicsRegisteredInDataBase() {
+ //given
+ Topic topic1 = DMAAP_OBJECT_FACTORY.genSimpleTopic("testTopic1");
+ Topic topic2 = DMAAP_OBJECT_FACTORY.genSimpleTopic("testTopic2");
+ DatabaseClass.getTopics().put(topic1.getFqtn(), topic1);
+ DatabaseClass.getTopics().put(topic2.getFqtn(), topic2);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+
+ List<Topic> topics = resp.readEntity(new GenericType<List<Topic>>() {
+ });
+ assertEquals(2, topics.size());
+ assertTrue(topics.contains(topic1));
+ assertTrue(topics.contains(topic2));
+ }
+
+ @Test
+ public void getTopics_shouldReturnValidationError_whenTopicNameIsInvalid() {
+ //given
+ String topicName = "wrong Topic Name";
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topicName).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("topicName", errorObj.getFields());
+ }
+
+ @Test
+ public void getTopic_shouldReturnError_whenRequestedTopicNotFound() {
+ //given
+ String topicName = "notExistingTopic";
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topicName).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.NOT_FOUND_404, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("fqtn", errorObj.getFields());
+ }
+
+ @Test
+ public void getTopic_shouldReturnTopicInformation_whenRequestedTopicExists() {
+ //given
+ Topic topic1 = DMAAP_OBJECT_FACTORY.genSimpleTopic("testTopic1");
+ DatabaseClass.getTopics().put(topic1.getFqtn(), topic1);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topic1.getFqtn()).request().get(Response.class);
+
+ //then
+ assertEquals(HttpStatus.OK_200, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ Topic retrievedTopic = resp.readEntity(Topic.class);
+ assertEquals(topic1, retrievedTopic);
+ }
+
+
+ @Test
+ public void deleteTopic_shouldReturnError_whenTopicNotFound() {
+ //given
+ String topicName = "notExisting";
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topicName).request().delete(Response.class);
+
+ //then
+ assertEquals(HttpStatus.NOT_FOUND_404, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("fqtn", errorObj.getFields());
+ }
+
+ @Test
+ public void deleteTopic_shouldDeleteTopicFromDataBase_whenFound() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("testTopic");
+ DatabaseClass.getTopics().put(topic.getFqtn(), topic);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topic.getFqtn()).request().delete(Response.class);
+
+ //then
+ assertEquals(HttpStatus.NO_CONTENT_204, resp.getStatus());
+ assertFalse(resp.hasEntity());
+ }
+
+ @Test
+ public void addTopic_shouldReturnValidationError_whenTopicNameIsInvalid() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("wrong topic name with spaces");
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("topicName", errorObj.getFields());
+ }
+
+ @Test
+ public void addTopic_shouldReturnValidationError_whenTopicDescriptionNotProvided() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ topic.setTopicDescription(null);
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("topicDescription", errorObj.getFields());
+ }
+
+ @Test
+ public void addTopic_shouldReturnValidationError_whenTopicOwnerNotProvided() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ topic.setOwner(null);
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("owner", errorObj.getFields());
+ }
+
+ @Test
+ public void addTopic_shouldReturnError_whenTopicAlreadyExist() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ DatabaseClass.getTopics().put(topic.getFqtn(), topic);
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CONFLICT_409, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("fqtn", errorObj.getFields());
+ }
+
+ @Test
+ public void addTopic_shouldReturnExistingTopic_whenTopicAlreadyExist_andUseExistingQueryParamUsed() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ DatabaseClass.getTopics().put(topic.getFqtn(), topic);
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).queryParam("useExisting", true).request()
+ .post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ assertEquals(topic, resp.readEntity(Topic.class));
+ }
+
+ @Test
+ public void addTopic_shouldReturnError_whenAddingTopicWithInvalidGlobalMRclusterHostname() {
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ topic.setReplicationCase(ReplicationType.REPLICATION_CENTRAL_TO_GLOBAL);
+ topic.setGlobalMrURL("some.invalid.Glob$al.M@R.ur)l");
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals("globalMrURL", errorObj.getFields());
+ }
+
+ @Test
+ public void addTopic_shouldAddTopicWithDefaultOptionalValues_whenNotProvided() {
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ Topic createdTopic = resp.readEntity(Topic.class);
+ assertEquals(topic, createdTopic);
+ assertEquals(FqtnType.FQTN_LEGACY_FORMAT, createdTopic.getFqtnStyle());
+ assertEquals("2", createdTopic.getPartitionCount());
+ assertEquals("1", createdTopic.getReplicationCount());
+ }
+
+ @Test
+ public void addTopic_shouldAddTopicWithOriginalOptionalValues_whenProvided() {
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ topic.setFqtnStyle(FqtnType.FQTN_PROJECTID_FORMAT);
+ topic.setFqtn(topic.genFqtn());
+ topic.setPartitionCount("6");
+ topic.setReplicationCount("9");
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).request().post(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.CREATED_201, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ Topic createdTopic = resp.readEntity(Topic.class);
+ assertEquals(topic, createdTopic);
+ assertEquals(FqtnType.FQTN_PROJECTID_FORMAT, createdTopic.getFqtnStyle());
+ assertEquals("6", createdTopic.getPartitionCount());
+ assertEquals("9", createdTopic.getReplicationCount());
+ }
+
+ @Test
+ public void updateTopic_shouldReturnError_withInformationThatItIsNotSupported() {
+ //given
+ Topic topic = DMAAP_OBJECT_FACTORY.genSimpleTopic("topicName");
+ DatabaseClass.getTopics().put(topic.getFqtn(), topic);
+ topic.setOwner("newOwner");
+ Entity<Topic> requestedEntity = Entity.entity(topic, MediaType.APPLICATION_JSON);
+
+ //when
+ Response resp = testContainer.target(TOPICS_TARGET).path(topic.getFqtn()).request()
+ .put(requestedEntity, Response.class);
+
+ //then
+ assertEquals(HttpStatus.BAD_REQUEST_400, resp.getStatus());
+ assertTrue(resp.hasEntity());
+ ApiError errorObj = resp.readEntity(ApiError.class);
+ assertEquals(TopicResource.UNSUPPORTED_PUT_MSG, errorObj.getMessage());
+ }
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/JettyServerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/JettyServerTest.java
new file mode 100644
index 0000000..35c9243
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/JettyServerTest.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.server;
+
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.Properties;
+
+public class JettyServerTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+
+ JettyServer m = null;
+
+ @Before
+ public void setUp() throws Exception {
+ Properties p = DmaapConfig.getConfig();
+ try {
+ m = new JettyServer(p);
+ } catch (Exception e ) {
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ m.getServer().stop();
+ } catch (Exception e ) {
+ }
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.server.JettyServer", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.server.JettyServer", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ }
+
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/MainTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/MainTest.java
new file mode 100644
index 0000000..0e74f45
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/server/MainTest.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.server;
+
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MainTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ Main m;
+
+
+ @Before
+ public void setUp() throws Exception {
+ //m = new Main();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.server.Main", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.server.Main", "set", v );
+
+ }
+
+/*
+ @Test
+ public void test3() {
+ String[] args = { "--help", "--version" };
+
+ try {
+ m.main( args );
+ } catch (Exception e ) {
+ }
+
+ }
+*/
+
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafPermissionServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafPermissionServiceTest.java
new file mode 100644
index 0000000..716736e
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafPermissionServiceTest.java
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.AafUserRole;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status.INVALID;
+import static org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status.VALID;
+
+@RunWith(JUnitParamsRunner.class)
+public class AafPermissionServiceTest {
+
+ private static final String ROLE = "dmaap.mr.demoTopic.publisher";
+ private static final String IDENTITY = "dmaap-bc@dmaap-bc.onap.org";
+ private static final String TOPIC_PERM = "org.onap.dmaap.mr.topic";
+ private static final String FQTN = "org.onap.dmaap.mr.demoTopic";
+ private static final String PUB_ACTION = "pub";
+ private static final int INTERNAL_SERVER_ERROR = 500;
+ @Mock
+ private AafService aafService;
+ @Mock
+ private DmaapService dmaapService;
+ @Mock
+ private MR_Client mrClient;
+ private AafPermissionService aafPermissionService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ aafPermissionService = new AafPermissionService(aafService, dmaapService);
+ given(mrClient.getClientIdentity()).willReturn(IDENTITY);
+ given(mrClient.getFqtn()).willReturn(FQTN);
+ given(mrClient.getAction()).willReturn(new String[]{PUB_ACTION});
+ given(dmaapService.getTopicPerm()).willReturn(TOPIC_PERM);
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldAssignClientToRole(int aafServiceReturnedCode) {
+ AafUserRole userRole = new AafUserRole(IDENTITY, ROLE);
+ given(aafService.addUserRole(userRole)).willReturn(aafServiceReturnedCode);
+
+ ApiError apiError = aafPermissionService.assignClientToRole(mrClient, ROLE);
+
+ then(aafService).should().addUserRole(userRole);
+ then(mrClient).should().setStatus(VALID);
+ assertOkStatus(apiError);
+ }
+
+ @Test
+ public void shouldReturnErrorStatusWhenClientWasNotAssignedToRole() {
+ AafUserRole userRole = new AafUserRole(IDENTITY, ROLE);
+ given(aafService.addUserRole(userRole)).willReturn(INTERNAL_SERVER_ERROR);
+
+ ApiError apiError = aafPermissionService.assignClientToRole(mrClient, ROLE);
+
+ then(mrClient).should().setStatus(INVALID);
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldGrantActionPermissionForClientRole(int aafServiceReturnedCode) {
+ DmaapGrant grant = new DmaapGrant(new DmaapPerm(TOPIC_PERM, ":topic." + FQTN, PUB_ACTION), ROLE);
+ given(mrClient.getClientRole()).willReturn(ROLE);
+ given(aafService.addGrant(grant)).willReturn(aafServiceReturnedCode);
+
+ ApiError apiError = aafPermissionService.grantClientRolePerms(mrClient);
+
+ then(aafService).should().addGrant(grant);
+ then(mrClient).should().setStatus(VALID);
+ assertOkStatus(apiError);
+ }
+
+ @Test
+ public void shouldReturnErrorStatusWhenPermissionWasNotGrantToRole() {
+ DmaapGrant grant = new DmaapGrant(new DmaapPerm(TOPIC_PERM, ":topic." + FQTN, PUB_ACTION), ROLE);
+ given(mrClient.getClientRole()).willReturn(ROLE);
+ given(aafService.addGrant(grant)).willReturn(INTERNAL_SERVER_ERROR);
+
+ ApiError apiError = aafPermissionService.grantClientRolePerms(mrClient);
+
+ then(mrClient).should().setStatus(INVALID);
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldReturnOkStatusWhenClientRoleIsNull() {
+ given(mrClient.getClientRole()).willReturn(null);
+
+ ApiError apiError = aafPermissionService.grantClientRolePerms(mrClient);
+
+ verifyZeroInteractions(aafService);
+ then(mrClient).should().setStatus(VALID);
+ assertOkStatus(apiError);
+ }
+
+ private void assertErrorStatus(ApiError apiError, int code) {
+ assertEquals(code, apiError.getCode());
+ }
+
+ private void assertOkStatus(ApiError apiError) {
+ assertTrue(apiError.is2xx());
+ assertEquals("OK", apiError.getMessage());
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafTopicSetupServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafTopicSetupServiceTest.java
new file mode 100644
index 0000000..0ca406a
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/AafTopicSetupServiceTest.java
@@ -0,0 +1,470 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.dmaap.dbcapi.aaf.AafNamespace;
+import org.onap.dmaap.dbcapi.aaf.AafRole;
+import org.onap.dmaap.dbcapi.aaf.AafService;
+import org.onap.dmaap.dbcapi.aaf.AafUserRole;
+import org.onap.dmaap.dbcapi.aaf.DmaapGrant;
+import org.onap.dmaap.dbcapi.aaf.DmaapPerm;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
+
+@RunWith(JUnitParamsRunner.class)
+public class AafTopicSetupServiceTest {
+
+ private static final int INTERNAL_SERVER_ERROR = 500;
+ private static final int NOT_FOUND = 404;
+ private static final int CREATED = 201;
+ private static final int OK = 200;
+ private static final String TOPIC_NS_ROOT = "org.onap.dmaap.mr";
+ private static final String TOPIC_PERM = "org.onap.dmaap.mr.topic";
+ private static final String TOPIC_FQTN = "org.onap.dmaap.mr.sample_topic";
+ private static final String IDENTITY = "dmaap-bc@dmaap-bc.onap.org";
+ private AafServiceStub aafService = new AafServiceStub();
+ @Mock
+ private DmaapService dmaapService;
+ @Mock
+ private DmaapConfig dmaapConfig;
+ private AafTopicSetupService aafTopicSetupService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ Dmaap dmaap = new Dmaap();
+ dmaap.setTopicNsRoot(TOPIC_NS_ROOT);
+ given(dmaapService.getDmaap()).willReturn(dmaap);
+ given(dmaapService.getTopicPerm()).willReturn(TOPIC_PERM);
+ given(dmaapConfig.getProperty("aaf.CreateTopicRoles", "true")).willReturn("true");
+ given(dmaapConfig.getProperty("MR.ClientDeleteLevel", "0")).willReturn("2");
+ aafTopicSetupService = new AafTopicSetupService(aafService, dmaapService, dmaapConfig);
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldCreatePublisherSubscriberViewerPermissions(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+
+ aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "pub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "sub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view"));
+ }
+
+ @Test
+ public void shouldReturnOkStatusWhenNoError() {
+ aafService.givenReturnCode(201);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertOkStatus(apiError);
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldAddNamespace(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+ Topic topic = givenTopic(TOPIC_FQTN);
+
+ aafTopicSetupService.aafTopicSetup(topic);
+
+ AafNamespace namespace = new AafNamespace(TOPIC_FQTN, IDENTITY);
+ aafService.shouldAddNamespace(namespace);
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldCretePublisherRoleAndSetItToTopic(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+ Topic topic = givenTopic(TOPIC_FQTN);
+
+ aafTopicSetupService.aafTopicSetup(topic);
+
+ AafRole role = new AafRole(TOPIC_FQTN, "publisher");
+ aafService.shouldAddRole(role);
+ assertEquals(role.getFullyQualifiedRole(), topic.getPublisherRole());
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldCreteSubscriberRoleAndSetItToTopic(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+ Topic topic = givenTopic(TOPIC_FQTN);
+
+ aafTopicSetupService.aafTopicSetup(topic);
+
+ AafRole role = new AafRole(TOPIC_FQTN, "subscriber");
+ aafService.shouldAddRole(role);
+ assertEquals(role.getFullyQualifiedRole(), topic.getSubscriberRole());
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldGrantPubAndViewPermissionToPublisherRole(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+
+ aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ AafRole role = new AafRole(TOPIC_FQTN, "publisher");
+ DmaapPerm pubPerm = new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "pub");
+ DmaapPerm viewPerm = new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view");
+ aafService.shouldAddGrant(new DmaapGrant(pubPerm, role.getFullyQualifiedRole()));
+ aafService.shouldAddGrant(new DmaapGrant(viewPerm, role.getFullyQualifiedRole()));
+ }
+
+ @Test
+ @Parameters({"201", "409"})
+ public void shouldGrantSubAndViewPermissionToSubscriberRole(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+
+ aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ AafRole role = new AafRole(TOPIC_FQTN, "subscriber");
+ DmaapPerm subPerm = new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "sub");
+ DmaapPerm viewPerm = new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view");
+ aafService.shouldAddGrant(new DmaapGrant(subPerm, role.getFullyQualifiedRole()));
+ aafService.shouldAddGrant(new DmaapGrant(viewPerm, role.getFullyQualifiedRole()));
+ }
+
+ @Test
+ public void shouldCreateOnlyPermissionsWhenCreateTopicRolesIsFalse() {
+ given(dmaapConfig.getProperty("aaf.CreateTopicRoles", "true")).willReturn("false");
+
+ aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "pub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "sub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view"));
+ aafService.shouldHaveNoNamespaceRolesAndGrantsAdded();
+ }
+
+ @Test
+ public void shouldCreateOnlyPermissionsWhenTopicFqtnDoesntStartWithNsRoot() {
+
+ String topicFqtn = "sample_topic";
+ aafTopicSetupService.aafTopicSetup(givenTopic(topicFqtn));
+
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "pub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "sub"));
+ aafService.shouldAddPerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "view"));
+ aafService.shouldHaveNoNamespaceRolesAndGrantsAdded();
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenTopicSnRootIsNotDefined() {
+ Dmaap dmaap = new Dmaap();
+ dmaap.setTopicNsRoot(null);
+ given(dmaapService.getDmaap()).willReturn(dmaap);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenPermissionCreationWasFailed() {
+ aafService.givenAddPermStatus(NOT_FOUND);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenNamespaceCreationWasFailed() {
+ aafService.givenAddNamespaceStatus(NOT_FOUND);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenRoleCreationWasFailed() {
+ aafService.givenAddRoleStatus(NOT_FOUND);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenGrantPermToRoleWasFailed() {
+ aafService.givenAddGrantStatus(NOT_FOUND);
+
+ ApiError apiError = aafTopicSetupService.aafTopicSetup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, NOT_FOUND);
+ }
+
+ @Test
+ @Parameters({"200", "404"})
+ public void shouldremovePublisherSubscriberViewerPermissions(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+
+ aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "pub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "sub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view"));
+ }
+
+ @Test
+ @Parameters({"200", "404"})
+ public void shouldRemoveNamespace(int aafServiceReturnedCode) {
+ aafService.givenReturnCode(aafServiceReturnedCode);
+ Topic topic = givenTopic(TOPIC_FQTN);
+
+ aafTopicSetupService.aafTopicCleanup(topic);
+
+ AafNamespace namespace = new AafNamespace(TOPIC_FQTN, IDENTITY);
+ aafService.shouldRemoveNamespace(namespace);
+ }
+
+ @Test
+ public void shouldRemoveOnlyPermissionsWhenCreateTopicRolesIsFalse() {
+ given(dmaapConfig.getProperty("aaf.CreateTopicRoles", "true")).willReturn("false");
+
+ aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "pub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "sub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + TOPIC_FQTN, "view"));
+ aafService.shouldNotRemoveNamespace();
+ }
+
+ @Test
+ public void shouldRemoveOnlyPermissionsWhenTopicFqtnDoesntStartWithNsRoot() {
+
+ String topicFqtn = "sample_topic";
+ aafTopicSetupService.aafTopicCleanup(givenTopic(topicFqtn));
+
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "pub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "sub"));
+ aafService.shouldRemovePerm(new DmaapPerm(TOPIC_PERM, ":topic." + topicFqtn, "view"));
+ aafService.shouldNotRemoveNamespace();
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenPermissionRemovalWasFailed() {
+ aafService.givenRemovePermStatus(INTERNAL_SERVER_ERROR);
+
+ ApiError apiError = aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldHandleExceptionWhenNamespaceRemovalWasFailed() {
+ aafService.givenRemoveNamespaceStatus(INTERNAL_SERVER_ERROR);
+
+ ApiError apiError = aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ assertErrorStatus(apiError, INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void shouldNotPerformCleanupWhenDeleteLevelIsLessThanTwo() {
+ given(dmaapConfig.getProperty("MR.ClientDeleteLevel", "0")).willReturn("0");
+
+ ApiError apiError = aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldNotPerformCleanup();
+ assertOkStatus(apiError);
+ }
+
+ @Test
+ public void shouldNotPerformCleanupWhenDeleteLevelIsNotNumericValue() {
+ given(dmaapConfig.getProperty("MR.ClientDeleteLevel", "0")).willReturn("not number");
+
+ ApiError apiError = aafTopicSetupService.aafTopicCleanup(givenTopic(TOPIC_FQTN));
+
+ aafService.shouldNotPerformCleanup();
+ assertOkStatus(apiError);
+ }
+
+ private Topic givenTopic(String topicFqtn) {
+ Topic topic = new Topic();
+ topic.setFqtn(topicFqtn);
+ return topic;
+ }
+
+ private void assertOkStatus(ApiError apiError) {
+ assertTrue(apiError.is2xx());
+ assertEquals("OK", apiError.getMessage());
+ }
+
+ private void assertErrorStatus(ApiError apiError, int code) {
+ assertEquals(code, apiError.getCode());
+ }
+
+ private class AafServiceStub implements AafService {
+
+ private AafNamespace addedNamespace;
+ private AafNamespace removedNamespace;
+ private List<DmaapPerm> addedPerms = newArrayList();
+ private List<DmaapPerm> removedPerms = newArrayList();
+ private List<AafRole> addedRoles = newArrayList();
+ private List<DmaapGrant> addedGrants = newArrayList();
+ private int addNamespaceStatus = CREATED;
+ private int addGrantStatus = CREATED;
+ private int addRoleStatus = CREATED;
+ private int addPermStatus = CREATED;
+ private int removePermStatus = OK;
+ private int removeNamespaceStatus = OK;
+
+ @Override
+ public String getIdentity() {
+ return IDENTITY;
+ }
+
+ @Override
+ public int addPerm(DmaapPerm perm) {
+ this.addedPerms.add(perm);
+ return addPermStatus;
+ }
+
+ @Override
+ public int delPerm(DmaapPerm perm, boolean force) {
+ removedPerms.add(perm);
+ return removePermStatus;
+ }
+
+ @Override
+ public int addGrant(DmaapGrant grant) {
+ addedGrants.add(grant);
+ return addGrantStatus;
+ }
+
+ @Override
+ public int addUserRole(AafUserRole ur) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int addRole(AafRole role) {
+ this.addedRoles.add(role);
+ return addRoleStatus;
+ }
+
+ @Override
+ public int addNamespace(AafNamespace namespace) {
+ this.addedNamespace = namespace;
+ return addNamespaceStatus;
+ }
+
+ @Override
+ public int delNamespace(AafNamespace namespace, boolean force) {
+ this.removedNamespace = namespace;
+ return removeNamespaceStatus;
+ }
+
+ void givenReturnCode(int status) {
+ this.addNamespaceStatus = status;
+ this.addGrantStatus = status;
+ this.addRoleStatus = status;
+ this.addPermStatus = status;
+ this.removePermStatus = status;
+ this.removeNamespaceStatus = status;
+ }
+
+ void givenAddNamespaceStatus(int addNamespaceStatus) {
+ this.addNamespaceStatus = addNamespaceStatus;
+ }
+
+ void givenRemoveNamespaceStatus(int removeNamespaceStatus) {
+ this.removeNamespaceStatus = removeNamespaceStatus;
+ }
+
+ void givenAddGrantStatus(int addGrantStatus) {
+ this.addGrantStatus = addGrantStatus;
+ }
+
+ void givenAddRoleStatus(int addRoleStatus) {
+ this.addRoleStatus = addRoleStatus;
+ }
+
+ void givenAddPermStatus(int addPermStatus) {
+ this.addPermStatus = addPermStatus;
+ }
+
+ void givenRemovePermStatus(int removePermStatus) {
+ this.removePermStatus = removePermStatus;
+ }
+
+ void shouldAddPerm(DmaapPerm perm) {
+ assertTrue(addedPerms.contains(perm));
+ }
+
+ void shouldRemovePerm(DmaapPerm perm) {
+ assertTrue(removedPerms.contains(perm));
+ }
+
+ void shouldAddNamespace(AafNamespace namespace) {
+ assertEquals(namespace, this.addedNamespace);
+ }
+
+ void shouldRemoveNamespace(AafNamespace namespace) {
+ assertEquals(namespace, this.removedNamespace);
+ }
+
+ void shouldAddRole(AafRole role) {
+ assertTrue(addedRoles.contains(role));
+ }
+
+ void shouldAddGrant(DmaapGrant grant) {
+ assertTrue(addedGrants.contains(grant));
+ }
+
+ void shouldHaveNoNamespaceRolesAndGrantsAdded() {
+ assertNull(this.addedNamespace);
+ assertTrue(this.addedGrants.isEmpty());
+ assertTrue(this.addedRoles.isEmpty());
+ }
+
+ void shouldNotRemoveNamespace() {
+ assertNull(this.removedNamespace);
+ }
+
+ void shouldNotPerformCleanup() {
+ shouldNotRemoveNamespace();
+ assertTrue(removedPerms.isEmpty());
+ }
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/ApiServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/ApiServiceTest.java
new file mode 100644
index 0000000..c860e55
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/ApiServiceTest.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ApiServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ ApiService ds;
+
+ @Before
+ public void setUp() throws Exception {
+ ds = new ApiService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ //rh.reflect( "org.onap.dmaap.dbcapi.service.ApiService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.ApiService", "set", v );
+
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/CredentialsParserTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/CredentialsParserTest.java
new file mode 100644
index 0000000..ae5becc
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/CredentialsParserTest.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class CredentialsParserTest {
+
+ private CredentialsParser credentialsParser = new CredentialsParser();
+
+ @Test
+ public void parse_shouldReturnEmptyCredentialsWhenAuthorizationHeaderIsNull() {
+
+ Credentials credentials = credentialsParser.parse(null);
+
+ assertTrue(credentials.getId().isEmpty());
+ assertTrue(credentials.getPwd().isEmpty());
+ }
+
+ @Test
+ public void parse_shouldReturnEmptyCredentialsWhenAuthorizationHeaderIsEmpty() {
+
+ Credentials credentials = credentialsParser.parse("");
+
+ assertTrue(credentials.getId().isEmpty());
+ assertTrue(credentials.getPwd().isEmpty());
+ }
+
+ @Test
+ public void parse_shouldParseCorrectCredentials() {
+
+ Credentials credentials = credentialsParser.parse("Basic dXNlcjpwYXNzd29yZA==");
+
+ assertEquals("user", credentials.getId());
+ assertEquals("password", credentials.getPwd());
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DR_NodeServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DR_NodeServiceTest.java
new file mode 100644
index 0000000..307d5b5
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DR_NodeServiceTest.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.List;
+
+public class DR_NodeServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+ static DmaapObjectFactory factory = new DmaapObjectFactory();
+
+ DR_NodeService ns;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new DR_NodeService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.service.DR_NodeService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.DR_NodeService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String f = "drsn01.onap.org";
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = factory.genDcaeLocation( "central" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+ DR_Node node = new DR_Node( f, locname, "zplvm009.onap.org", "1.0.46" );
+ DR_Node n2 = ns.addDr_Node( node, err );
+
+ if ( n2 != null ) {
+ n2 = ns.getDr_Node( f, err );
+ }
+
+ List<DR_Node> l = ns.getAllDr_Nodes();
+ if ( n2 != null ) {
+ n2.setVersion( "1.0.47" );
+ n2 = ns.updateDr_Node( n2, err );
+ }
+
+ n2 = ns.removeDr_Node( f, err );
+
+
+ }
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DcaeLocationServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DcaeLocationServiceTest.java
new file mode 100644
index 0000000..e0b32a4
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DcaeLocationServiceTest.java
@@ -0,0 +1,144 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.DmaapObject;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class DcaeLocationServiceTest {
+
+ private static final String LOCATION_A = "locationA";
+ private static final String LOCATION_B = "locationB";
+ private DcaeLocationService locationService = new DcaeLocationService(new HashMap<>());
+
+ @Test
+ public void getAllDcaeLocations_shouldReturnEmptyCollection() {
+
+ List<DcaeLocation> allDcaeLocations = locationService.getAllDcaeLocations();
+
+ assertTrue(allDcaeLocations.isEmpty());
+ }
+
+ @Test
+ public void addDcaeLocation_shouldAddLocationToMap() {
+ DcaeLocation locationA = createDcaeLocation(LOCATION_A);
+
+ DcaeLocation addedLocation = locationService.addDcaeLocation(locationA);
+
+ assertEquals(locationA, locationService.getDcaeLocation(LOCATION_A));
+ assertSame(locationA, addedLocation);
+ }
+
+ @Test
+ public void addDcaeLocation_shouldSetStatusAndLastModDate() {
+ DcaeLocation locationA = createDcaeLocation(LOCATION_A);
+ Date creationDate = new Date(10);
+ locationA.setLastMod(creationDate);
+
+ DcaeLocation addedLocation = locationService.addDcaeLocation(locationA);
+
+ assertTrue(addedLocation.getLastMod().after(creationDate));
+ assertEquals(DmaapObject.DmaapObject_Status.VALID, addedLocation.getStatus());
+ }
+
+ @Test
+ public void updateDcaeLocation_shouldUpdateLocationAndLastModDate() {
+ DcaeLocation location = createDcaeLocation(LOCATION_A);
+ Date creationDate = new Date(10);
+ location.setLastMod(creationDate);
+ locationService.addDcaeLocation(location);
+
+ DcaeLocation updatedLocation = locationService.updateDcaeLocation(location);
+
+ assertTrue(updatedLocation.getLastMod().after(creationDate));
+ assertSame(location, updatedLocation);
+ }
+
+ @Test
+ public void updateDcaeLocation_shouldShouldReturnNullWhenLocationNameIsEmpty() {
+ DcaeLocation location = createDcaeLocation("");
+
+ DcaeLocation updatedLocation = locationService.updateDcaeLocation(location);
+
+ assertNull(updatedLocation);
+ assertTrue(locationService.getAllDcaeLocations().isEmpty());
+ }
+
+ @Test
+ public void removeDcaeLocation_shouldRemoveLocationFromService() {
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_A));
+
+ locationService.removeDcaeLocation(LOCATION_A);
+
+ assertTrue(locationService.getAllDcaeLocations().isEmpty());
+ }
+
+ @Test
+ public void getCentralLocation_shouldGetFirstCentralLocation() {
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_A, "layerA"));
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_B, "centralLayer"));
+
+ assertEquals(LOCATION_B, locationService.getCentralLocation());
+ }
+
+ @Test
+ public void getCentralLocation_shouldReturnDefaultCentralLocationNameWhenThereIsNoCentralLocation() {
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_A, "layerA"));
+
+ assertEquals("aCentralLocation", locationService.getCentralLocation());
+ }
+
+ @Test
+ public void isEdgeLocation_shouldReturnTrueForNotCentralLocation() {
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_A, "layerA"));
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_B, "centralLayer"));
+
+ assertTrue(locationService.isEdgeLocation(LOCATION_A));
+ assertFalse(locationService.isEdgeLocation(LOCATION_B));
+ }
+
+ @Test
+ public void isEdgeLocation_shouldReturnFalseWhenLocationDoesNotExist() {
+ locationService.addDcaeLocation(createDcaeLocation(LOCATION_A, "layerA"));
+
+ assertFalse(locationService.isEdgeLocation("not_existing_location"));
+ }
+
+ private DcaeLocation createDcaeLocation(String locationName) {
+ return createDcaeLocation(locationName, "dcaeLayer");
+ }
+
+ private DcaeLocation createDcaeLocation(String locationName, String dcaeLayer) {
+ return new DcaeLocation("clli", dcaeLayer, locationName, "openStackAvailabilityZone", "subnet");
+ }
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DmaapServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DmaapServiceTest.java
new file mode 100644
index 0000000..b8b660f
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/DmaapServiceTest.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class DmaapServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ DmaapService ds;
+
+ @Before
+ public void setUp() throws Exception {
+ ds = new DmaapService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ //rh.reflect( "org.onap.dmaap.dbcapi.service.DmaapService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.DmaapService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ Dmaap nd = new Dmaap.DmaapBuilder().setVer("1").setTnr("org.onap.dmaap").setDn("onap-demo").setDpu("drps.demo.onap.org").setLu("").setBat("MMAGENT_TOPIC").setNk("").setAko("").createDmaap();
+ ds.addDmaap( nd );
+ }
+
+ @Test
+ public void test4() {
+ Dmaap d = ds.getDmaap();
+
+ }
+
+ @Test
+ public void test5() {
+ Dmaap nd = new Dmaap.DmaapBuilder().setVer("2").setTnr("org.onap.dmaap").setDn("onap-demo").setDpu("drps.demo.onap.org").setLu("").setBat("MMAGENT_TOPIC").setNk("").setAko("").createDmaap();
+ ds.updateDmaap( nd );
+
+ }
+
+ @Test
+ public void test6() {
+ String t = ds.getTopicPerm();
+ String t2 = ds.getTopicPerm( "val2" );
+ String t3 = ds.getBridgeAdminFqtn();
+
+ boolean b = ds.testCreateMmaTopic();
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/Dr_PubServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/Dr_PubServiceTest.java
new file mode 100644
index 0000000..2cfe475
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/Dr_PubServiceTest.java
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.List;
+import java.util.ArrayList;
+
+public class Dr_PubServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ DR_PubService ns;
+ FeedService fs;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new DR_PubService();
+ fs = new FeedService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.service.DR_PubService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.DR_PubService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = new DcaeLocation( "CLLI1234", "central-onap", locname, "aZone", "10.10.10.0/24" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+ Feed f = new Feed( "aTest", "1.0", "a unit test", "dgl", "unrestricted" );
+ f = fs.addFeed( f, err );
+
+ assertTrue( f != null );
+ DR_Pub node = new DR_Pub( locname, "aUser", "aPwd", f.getFeedId(), "pubId01" );
+ DR_Pub n2 = ns.addDr_Pub( node );
+ DR_Pub node2 = new DR_Pub( locname, "aUser", "aPwd", f.getFeedId() );
+ n2 = ns.addDr_Pub( node2 );
+
+ if ( n2 != null ) {
+ n2 = ns.getDr_Pub( n2.getPubId(), err );
+ }
+
+ List<DR_Pub> l = ns.getAllDr_Pubs();
+ if ( n2 != null ) {
+ n2 = ns.updateDr_Pub( n2 );
+ }
+
+ n2 = ns.removeDr_Pub( n2.getPubId(), err );
+
+
+ }
+
+ @Test
+ public void test4() {
+ ArrayList<DR_Pub> l = ns.getDr_PubsByFeedId( "1" );
+
+
+ }
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/FeedServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/FeedServiceTest.java
new file mode 100644
index 0000000..478647b
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/FeedServiceTest.java
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.Feed;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class FeedServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ FeedService ds;
+
+ @Before
+ public void setUp() throws Exception {
+ ds = new FeedService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.service.FeedService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.FeedService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ ApiError err = new ApiError();
+
+ Feed f = new Feed( "aTest", "1.0", "a unit test", "dgl", "unrestricted" );
+ f = ds.addFeed( f, err );
+ System.out.println( "f=" + f );
+
+ ds.updateFeed( f, err );
+
+ ds.removeFeed( f, err );
+ }
+
+ @Test
+ public void test4() {
+ ApiError err = new ApiError();
+ Feed f = ds.getFeed( "aName", err );
+
+ f = ds.getFeedByName( "aName", "1.0", err );
+
+ f = ds.getFeedPure( "aName", err );
+ }
+
+ @Test
+ public void test5() {
+ List<Feed> f = ds.getAllFeeds( "aName", "1.0", "startsWith" );
+
+ }
+
+
+ @Test
+ public void syncTestHard() {
+ ApiError err = new ApiError();
+ ds.sync( true, err );
+
+ assert( 200 == err.getCode());
+ }
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClientServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClientServiceTest.java
new file mode 100644
index 0000000..e80697a
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClientServiceTest.java
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.DcaeLocation;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.MR_Cluster;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+public class MR_ClientServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ private static DmaapObjectFactory factory = new DmaapObjectFactory();
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ private TopicService ts;
+ private MR_ClusterService mcs;
+ private MR_ClientService cls;
+ private DcaeLocationService dls;
+
+ private String f;
+ private String locname;
+
+ @Before
+ public void setUp() throws Exception {
+ ts = new TopicService();
+ mcs = new MR_ClusterService();
+ cls = new MR_ClientService();
+ f = "mrsn01.onap.org";
+ locname = "central-demo";
+
+ dls = new DcaeLocationService();
+ DcaeLocation loc = factory.genDcaeLocation( "central" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+ String[] h = { "zplvm009.onap.org", "zplvm007.onap.org", "zplvm008.onap.org" };
+ MR_Cluster node = factory.genMR_Cluster( "central" );
+ MR_Cluster n2 = mcs.addMr_Cluster( node, err );
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.service.MR_ClientService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.MR_ClientService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ Topic topic = factory.genSimpleTopic( "test3" );
+ ApiError err = new ApiError();
+ Topic nTopic = ts.addTopic( topic, err, false );
+ if ( nTopic != null ) {
+ assertTrue( nTopic.getTopicName().equals( topic.getTopicName() ));
+ }
+
+ MR_Client c = factory.genPublisher( "edge", topic.getFqtn() );
+
+ c = cls.addMr_Client( c, topic, err );
+
+ }
+
+ @Test
+ public void test4() {
+ List<MR_Client> l = cls.getAllMr_Clients();
+
+ List<MR_Client> al = cls.getAllMrClients( "foo" );
+
+ List<MR_Client> al2 = cls.getClientsByLocation( "central" );
+ }
+
+ @Test
+ public void AddSubscriberToTopic() {
+ Topic topic = factory.genSimpleTopic( "test5" );
+ ApiError err = new ApiError();
+ Topic nTopic = ts.addTopic( topic, err, false );
+ if ( nTopic != null ) {
+ assertTrue( nTopic.getTopicName().equals( topic.getTopicName() ));
+ }
+ MR_Client c = factory.genPublisher( "central", topic.getFqtn() );
+
+ c = cls.addMr_Client( c, topic, err );
+ assertTrue( c != null );
+
+ c = factory.genSubscriber( "central", topic.getFqtn() );
+ c = cls.addMr_Client( c, topic, err );
+ assertTrue( err.getCode() == 200 );
+
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClusterServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClusterServiceTest.java
new file mode 100644
index 0000000..8ae2667
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MR_ClusterServiceTest.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.List;
+
+public class MR_ClusterServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ MR_ClusterService ns;
+
+ @Before
+ public void setUp() throws Exception {
+ ns = new MR_ClusterService();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.service.MR_ClusterService", "get", null );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.MR_ClusterService", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String f = "mrsn01.onap.org";
+ String locname = "central-demo";
+
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation loc = new DcaeLocation( "CLLI1234", "some-onap", locname, "aZone", "10.10.10.0/24" );
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+ String[] h = { "zplvm009.onap.org", "zplvm007.onap.org", "zplvm008.onap.org" };
+ MR_Cluster node = new MR_Cluster( locname, f, "http", "3904");
+ MR_Cluster n2 = ns.addMr_Cluster( node, err );
+
+ if ( n2 != null ) {
+ n2 = ns.getMr_Cluster( f, err );
+ }
+
+ List<MR_Cluster> l = ns.getAllMr_Clusters();
+ if ( n2 != null ) {
+ n2 = ns.updateMr_Cluster( n2, err );
+ }
+
+ n2 = ns.removeMr_Cluster( f, err );
+
+
+ }
+
+/*
+ @Test
+ public void test4() {
+ List<MR_Client> l = cls.getAllMr_Clients();
+
+ ArrayList<MR_Client> al = cls.getAllMrClients( "foo" );
+
+ ArrayList<MR_Client> al2 = cls.getClientsByLocation( "central" );
+ }
+
+ @Test
+ public void test5() {
+ Topic topic = new Topic();
+ ApiError err = new ApiError();
+ topic.setTopicName( "test3" );
+ topic.setFqtnStyle( FqtnType.Validator("none") );
+ topic.getFqtn();
+ Topic nTopic = ts.addTopic( topic, err );
+ if ( nTopic != null ) {
+ assertTrue( nTopic.getTopicName().equals( topic.getTopicName() ));
+ }
+ String[] actions = { "pub", "view" };
+ MR_Client c = new MR_Client( "central-onap", "org.onap.dmaap.demo.interestingTopic2", "org.onap.clientApp.publisher", actions );
+
+ c = cls.addMr_Client( c, topic, err );
+ if ( c != null ) {
+ actions[0] = "sub";
+ c.setAction( actions );
+ c = cls.updateMr_Client( c, err );
+ assertTrue( err.getCode() == 200 );
+ }
+ }
+*/
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTest.java
new file mode 100644
index 0000000..f247bad
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTest.java
@@ -0,0 +1,185 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.service;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.testframework.DmaapObjectFactory;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.List;
+import java.util.ArrayList;
+
+public class MirrorMakerServiceTest {
+
+ private static final String fmt = "%24s: %s%n";
+ private static DmaapObjectFactory factory = new DmaapObjectFactory();
+ ReflectionHarness rh = new ReflectionHarness();
+
+ private MirrorMakerService mms;
+ private TopicService ts;
+ private MR_ClusterService mcs;
+ private MR_ClientService cls;
+ private DcaeLocationService dls;
+
+ private Topic replicationTopic;
+
+
+ DmaapService ds;
+ String locname;
+
+ @Before
+ public void setUp() throws Exception {
+ mms = new MirrorMakerService();
+ ts = new TopicService();
+ assert( ts != null );
+ mcs = new MR_ClusterService();
+ assert( mcs != null );
+ Dmaap nd = factory.genDmaap();
+ ds = new DmaapService();
+ ds.addDmaap( nd );
+ ts = new TopicService();
+ mcs = new MR_ClusterService();
+ cls = new MR_ClientService();
+
+ dls = new DcaeLocationService();
+ DcaeLocation loc = factory.genDcaeLocation( "central" );
+ locname = loc.getDcaeLocationName();
+ dls.addDcaeLocation( loc );
+ loc = factory.genDcaeLocation( "edge");
+ dls.addDcaeLocation( loc );
+
+ ApiError err = new ApiError();
+
+ MR_Cluster node = factory.genMR_Cluster( "central" );
+ mcs.addMr_Cluster( node, err);
+ node = factory.genMR_Cluster("edge" );
+ mcs.addMr_Cluster(node, err);
+
+
+ String t = "org.onap.dmaap.bridgingTopic";
+ replicationTopic = factory.genSimpleTopic(t);
+ replicationTopic.setReplicationCase( ReplicationType.REPLICATION_EDGE_TO_CENTRAL );
+
+ String c = "publisher";
+ String[] a = { "sub", "view" };
+ MR_Client sub = factory.genMR_Client("central", replicationTopic.getFqtn(), c, a );
+ String[] b = { "pub", "view" };
+ MR_Client pub = factory.genMR_Client( "edge", replicationTopic.getFqtn(), c, b );
+ ArrayList<MR_Client> clients = new ArrayList<MR_Client>();
+
+ clients.add( sub );
+ clients.add( pub );
+
+ replicationTopic.setClients( clients );
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+// @Test
+// public void test_getters() {
+//
+//
+// rh.reflect( "org.onap.dmaap.dbcapi.service.MirrorMakerService", "get", null );
+//
+// }
+
+ @Test
+ public void test_setters() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.service.MirrorMakerService", "set", v );
+
+ }
+
+
+
+ @Test
+ public void CreateMirrorMakerWithSingleTopic() {
+ ApiError err = new ApiError();
+
+
+ Topic nTopic = ts.addTopic(replicationTopic, err, true );
+
+ assertTrue( err.getCode() == 200 );
+
+ List<String> mma = mms.getAllMirrorMakers();
+ }
+
+ @Test
+ public void DeleteMirrorMakerWithSingleTopic() {
+
+ ApiError err = new ApiError();
+ Topic nTopic = ts.addTopic(replicationTopic, err, true );
+ replicationTopic.setTopicDescription("modified topic");
+ nTopic = ts.updateTopic( replicationTopic, err );
+
+ assertTrue( err.getCode() == 200 );
+
+
+ List<String> mma = mms.getAllMirrorMakers();
+
+ int nMM = mma.size();
+ assertTrue( nMM >= 1);
+
+ String name = mma.get(0);
+
+ MirrorMaker mm = mms.getMirrorMaker(name);
+
+ mms.delMirrorMaker(mm);
+
+ mma = mms.getAllMirrorMakers();
+
+ assertTrue( mma.size() == (nMM-1) );
+ }
+
+ @Test
+ public void SplitMirrorMakerWithSingleTopic() {
+
+ ApiError err = new ApiError();
+
+
+ Topic nTopic = ts.addTopic( replicationTopic, err, true );
+ replicationTopic.setTopicDescription("modified topic");
+ nTopic = ts.updateTopic( replicationTopic, err );
+
+
+ assertTrue( err.getCode() == 200 );
+ List<String> mma = mms.getAllMirrorMakers();
+
+ int nMM = mma.size();
+ assertTrue( nMM >= 1);
+
+ String name = mma.get(0);
+
+ MirrorMaker mm = mms.getMirrorMaker(name);
+
+ MirrorMaker mm2 = mms.splitMM(mm);
+
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTestMockito.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTestMockito.java
new file mode 100644
index 0000000..5beadc6
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/MirrorMakerServiceTestMockito.java
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 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.onap.dmaap.dbcapi.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.dmaap.dbcapi.model.MirrorMaker;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MirrorMakerServiceTestMockito {
+
+ @Spy
+ private MirrorMakerService service;
+
+ @Mock
+ private CadiFilter cadiFilterMock;
+ @Mock
+ private HttpServletRequest servletRequest;
+ @Mock
+ private HttpServletResponse servletResponse;
+
+ @Mock
+ private DmaapConfig dmaapConfig;
+
+ @Mock
+ private MirrorMaker mm = new MirrorMaker();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @Test
+ public void init_normalConstructor() throws Exception {
+ //given
+
+
+ //when
+
+
+ //then
+ assertEquals( MirrorMakerService.getProvUserPwd(), MirrorMakerService.PROV_PWD_DEFAULT);
+ assertEquals( MirrorMakerService.getDefaultConsumerPort(), MirrorMakerService.TARGET_REPLICATION_PORT_DEFAULT);
+ assertEquals( MirrorMakerService.getDefaultProducerPort(), MirrorMakerService.SOURCE_REPLICATION_PORT_DEFAULT);
+ }
+
+ // Todo: learn how to make more tests in Mockito
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/TopicServiceTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/TopicServiceTest.java
new file mode 100644
index 0000000..a37ce02
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/service/TopicServiceTest.java
@@ -0,0 +1,305 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.service;
+
+import com.google.common.collect.ImmutableMap;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.model.ApiError;
+import org.onap.dmaap.dbcapi.model.MR_Client;
+import org.onap.dmaap.dbcapi.model.Topic;
+import org.onap.dmaap.dbcapi.util.DmaapConfig;
+
+import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Lists.newArrayList;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.onap.dmaap.dbcapi.model.ReplicationType.REPLICATION_GLOBAL_TO_FQDN;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TopicServiceTest {
+
+ private static final String TOPIC_FQTN = "topic_1";
+ private static final String GLOBAL_MR_HOST = "global.mr.host";
+ private TopicService topicService;
+ @Mock
+ private MR_ClientService clientService;
+ @Mock
+ private DmaapConfig dmaapConfig;
+ @Mock
+ private MR_ClusterService clusters;
+ @Mock
+ private DcaeLocationService locations;
+ @Mock
+ private MirrorMakerService bridge;
+ @Mock
+ private AafTopicSetupService aafTopicSetupService;
+
+ @Before
+ public void setUp() throws Exception {
+ given(dmaapConfig.getProperty("MR.globalHost", "global.host.not.set")).willReturn(GLOBAL_MR_HOST);
+ given(aafTopicSetupService.aafTopicSetup(any(Topic.class))).willReturn(new ApiError(200, "OK"));
+ given(aafTopicSetupService.aafTopicCleanup(any(Topic.class))).willReturn(new ApiError(200, "OK"));
+ createTopicService();
+ }
+
+ @Test
+ public void getTopics_shouldReturnTopicsReceivedDuringServiceCreation() {
+
+ ImmutableMap<String, Topic> topics = ImmutableMap.of(TOPIC_FQTN, new Topic());
+ topicService = new TopicService(topics, clientService, dmaapConfig, clusters, locations, bridge, aafTopicSetupService);
+
+ assertEquals(topics, topicService.getTopics());
+ }
+
+ @Test
+ public void getAllTopics_shouldReturnTopicsWithClients() {
+
+ ArrayList<MR_Client> mrClients = newArrayList(new MR_Client());
+ given(clientService.getAllMrClients(TOPIC_FQTN)).willReturn(mrClients);
+
+ List<Topic> allTopics = topicService.getAllTopics();
+
+ assertThat(getOnlyElement(allTopics), hasCorrectFqtn(TOPIC_FQTN));
+ assertEquals(mrClients, getOnlyElement(allTopics).getClients());
+ }
+
+ @Test
+ public void getAllTopicsWithoutClients_shouldReturnNoClients() {
+
+ List<Topic> allTopics = topicService.getAllTopicsWithoutClients();
+
+ assertThat(getOnlyElement(allTopics), hasCorrectFqtn(TOPIC_FQTN));
+ assertNull(getOnlyElement(allTopics).getClients());
+ verifyZeroInteractions(clientService);
+ }
+
+ @Test
+ public void getAllTopics_shouldCacheClients() {
+
+ ArrayList<MR_Client> mrClients = newArrayList(new MR_Client());
+ given(clientService.getAllMrClients(TOPIC_FQTN)).willReturn(mrClients);
+
+ topicService.getAllTopics();
+ List<Topic> allTopics = topicService.getAllTopicsWithoutClients();
+
+ assertThat(getOnlyElement(allTopics), hasCorrectFqtn(TOPIC_FQTN));
+ assertEquals(mrClients, getOnlyElement(allTopics).getClients());
+ }
+
+ @Test
+ public void getTopic_shouldReturnTopicByFqtn() {
+
+ ApiError apiError = new ApiError();
+ Topic topic = topicService.getTopic(TOPIC_FQTN, apiError);
+
+ assertThat(topic, hasCorrectFqtn(TOPIC_FQTN));
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void getTopic_shouldReturnTopicWithMrClients() {
+
+ ArrayList<MR_Client> mrClients = newArrayList(new MR_Client());
+ given(clientService.getAllMrClients(TOPIC_FQTN)).willReturn(mrClients);
+
+ Topic topic = topicService.getTopic(TOPIC_FQTN, new ApiError());
+
+ assertThat(topic, hasCorrectFqtn(TOPIC_FQTN));
+ assertEquals(mrClients, topic.getClients());
+ }
+
+ @Test
+ public void getTopic_shouldReturnError() {
+
+ ApiError apiError = new ApiError();
+ Topic topic = topicService.getTopic("not_existing", apiError);
+
+ assertNull(topic);
+ assertEquals(NOT_FOUND.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void addTopic_shouldAddNewTopic() {
+ Topic newTopic = createTopic("");
+
+ ApiError apiError = new ApiError();
+ Topic addedTopic = topicService.addTopic(newTopic, apiError, true);
+
+ assertSame(newTopic, addedTopic);
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ assertNotNull(topicService.getTopic(addedTopic.getFqtn(), new ApiError()));
+ }
+
+ @Test
+ public void addTopic_shouldReturnErrorWhenTopicAlreadyExists() {
+ Topic newTopic = createTopic("");
+
+ ApiError apiError = new ApiError();
+ Topic addedTopic = topicService.addTopic(newTopic, apiError, false);
+ Topic secondAddedTopic = topicService.addTopic(addedTopic, apiError, false);
+
+ assertNull(secondAddedTopic);
+ assertEquals(Response.Status.CONFLICT.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void addTopic_shouldAddTheSameTopicWhenUseExistingIsSet() {
+ Topic newTopic = createTopic("");
+
+ ApiError apiError = new ApiError();
+ Topic addedTopic = topicService.addTopic(newTopic, apiError, false);
+ Topic secondAddedTopic = topicService.addTopic(addedTopic, apiError, true);
+
+ assertSame(addedTopic, secondAddedTopic);
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ assertNotNull(topicService.getTopic(secondAddedTopic.getFqtn(), new ApiError()));
+ }
+
+
+ @Test
+ public void addTopic_shouldSetGlobalMrURL() {
+ Topic newTopic = createTopic(TOPIC_FQTN);
+ newTopic.setReplicationCase(REPLICATION_GLOBAL_TO_FQDN);
+
+ ApiError apiError = new ApiError();
+ Topic addedTopic = topicService.addTopic(newTopic, apiError, true);
+
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ assertEquals(GLOBAL_MR_HOST, addedTopic.getGlobalMrURL());
+ }
+
+ @Test
+ public void addTopic_shouldReturnErrorWhenGlobalMrURLIsInvalid() {
+ given(dmaapConfig.getProperty("MR.globalHost", "global.host.not.set")).willReturn("invalid@host");
+ createTopicService();
+ Topic newTopic = createTopic(TOPIC_FQTN);
+ newTopic.setReplicationCase(REPLICATION_GLOBAL_TO_FQDN);
+
+ ApiError apiError = new ApiError();
+ Topic addedTopic = topicService.addTopic(newTopic, apiError, true);
+
+ assertEquals(500, apiError.getCode());
+ assertNull(addedTopic);
+ }
+
+ @Test
+ public void removeTopic_shouldFailIfTopicDoesNotExist() {
+ ApiError apiError = new ApiError();
+
+ Topic removedTopic = topicService.removeTopic("not_existing_fqtn", apiError);
+
+ assertNull(removedTopic);
+ assertEquals(NOT_FOUND.getStatusCode(), apiError.getCode());
+ assertTrue(topicService.getTopics().containsKey(TOPIC_FQTN));
+ }
+
+ @Test
+ public void removeTopic_shouldExecuteAafCleanup() {
+ ApiError apiError = new ApiError();
+
+ Topic removedTopic = topicService.removeTopic(TOPIC_FQTN, apiError);
+
+ then(aafTopicSetupService).should().aafTopicCleanup(removedTopic);
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void removeTopic_shouldRemoveEachMrClientAssignedToTopic() {
+ ApiError apiError = new ApiError();
+ MR_Client mrClient = new MR_Client();
+ mrClient.setMrClientId("mrClientId");
+
+ given(clientService.getAllMrClients(TOPIC_FQTN)).willReturn(newArrayList(mrClient));
+
+ topicService.removeTopic(TOPIC_FQTN, apiError);
+
+ then(clientService).should().removeMr_Client(mrClient.getMrClientId(), false, apiError);
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void removeTopic_shouldRemoveTopicFromCache() {
+ ApiError apiError = new ApiError();
+
+ topicService.removeTopic(TOPIC_FQTN, apiError);
+
+ assertTrue(topicService.getTopics().isEmpty());
+ assertEquals(OK.getStatusCode(), apiError.getCode());
+ }
+
+ @Test
+ public void removeTopic_shouldFailIfAafCleanupWasFailed() {
+ ApiError apiError = new ApiError();
+ given(aafTopicSetupService.aafTopicCleanup(any(Topic.class))).willReturn(new ApiError(404, "sth went wrong"));
+
+ Topic removedTopic = topicService.removeTopic(TOPIC_FQTN, apiError);
+
+ assertNull(removedTopic);
+ assertEquals(404, apiError.getCode());
+ assertTrue(topicService.getTopics().containsKey(TOPIC_FQTN));
+ }
+
+ private void createTopicService() {
+ Map<String, Topic> mrTopics = new HashMap<>();
+ mrTopics.put(TOPIC_FQTN, createTopic(TOPIC_FQTN));
+ topicService = new TopicService(mrTopics, clientService, dmaapConfig, clusters, locations, bridge, aafTopicSetupService);
+ }
+
+ private Topic createTopic(String fqtn) {
+ return new Topic(fqtn, "name", "desc", "tnxEnabled", "owner");
+ }
+
+ public static Matcher<Topic> hasCorrectFqtn(final String fqtn) {
+ return new BaseMatcher<Topic>() {
+ public boolean matches(Object o) {
+ return fqtn.equals(((Topic) o).getFqtn());
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("Topics should should be equal. Expected fqtn: ").appendValue(fqtn);
+ }
+ };
+ }
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/DmaapObjectFactory.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/DmaapObjectFactory.java
new file mode 100644
index 0000000..9d45a54
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/DmaapObjectFactory.java
@@ -0,0 +1,128 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.testframework;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.util.RandomInteger;
+
+public class DmaapObjectFactory {
+
+ /*
+ * we use localhost for most references so that connection attempts will resolve and not retry
+ * but still we expect that requests will fail.
+ */
+ private static final String fmt = "%24s: %s%n";
+ private static final String dmaap_name = "onap-ut";
+ private static final String dmaap_ver = "1";
+ private static final String dmaap_topic_root = "org.onap.dmaap";
+ private static final String dmaap_dr = "https://localhost:8443";
+ private static final String dmaap_log_url = "http://localhost:8080/log";
+ private static final String dmaap_mm_topic = "org.onap.dmaap.dcae.MM_AGENT_TOPIC";
+ private static final String central_loc = "SanFrancisco";
+ private static final String central_layer = "central-cloud";
+ private static final String central_clli = "SFCAL19240";
+ private static final String central_zone = "osaz01";
+ private static final String central_subnet = "10.10.10.0/24";
+ private static final String central_cluster_fqdn = "localhost";
+ private static final String pub_role = "org.onap.vnfapp.publisher";
+ private static final String sub_role = "org.onap.vnfapp.subscriber";
+ private static final String edge_loc = "Atlanta";
+ private static final String edge_layer = "edge-cloud";
+ private static final String edge_clli = "ATLGA10245";
+ private static final String edge_zone = "osaz02";
+ private static final String edge_subnet = "10.10.20.0/24";
+ private static final String edge_cluster_fqdn = "localhost";
+ private static final String[]hosts = { "host1", "host2", "host3" };
+ private static final String port = "3904";
+ private static final String prot = "http";
+
+ public Dmaap genDmaap() {
+ return new Dmaap.DmaapBuilder().setVer(dmaap_ver).setTnr(dmaap_topic_root).setDn(dmaap_name).setDpu(dmaap_dr).setLu(dmaap_log_url).setBat(dmaap_mm_topic).setNk("nk").setAko("ako").createDmaap();
+ }
+
+ public DcaeLocation genDcaeLocation( String layer ) {
+ if ( layer.contains( "edge" ) ) {
+ return new DcaeLocation( edge_clli, edge_layer, edge_loc, edge_zone, edge_subnet );
+ }
+ return new DcaeLocation( central_clli, central_layer, central_loc, central_zone, central_subnet );
+ }
+
+
+ public MR_Cluster genMR_Cluster( String layer ) {
+ if ( layer.contains( "edge" ) ) {
+ return new MR_Cluster( edge_loc, edge_cluster_fqdn, prot, port );
+ }
+ return new MR_Cluster( central_loc, central_cluster_fqdn, prot, port );
+ }
+
+ public Topic genSimpleTopic( String tname ) {
+ Topic t = new Topic();
+ t.setTopicName( tname );
+ t.setFqtnStyle( FqtnType.Validator("none") );
+ t.setTopicDescription( "a simple Topic named " + tname );
+ t.setOwner( "ut");
+ t.setFqtn(t.genFqtn());
+ return t;
+ }
+
+ public MR_Client genMR_Client( String l, String f, String r, String[] a ) {
+ if ( l.contains( "edge" ) ) {
+ return new MR_Client( edge_loc, f, r, a );
+ }
+ return new MR_Client( central_loc, f, r, a );
+ }
+
+ public MR_Client genPublisher( String layer, String fqtn ) {
+ String[] actions = { "pub", "view" };
+ return genMR_Client( layer, fqtn, pub_role, actions );
+ }
+ public MR_Client genSubscriber( String layer, String fqtn ) {
+ String[] actions = { "sub", "view" };
+ return genMR_Client( layer, fqtn, sub_role, actions );
+ }
+
+ public DR_Sub genDrSub( String l, String feed ) {
+ String un = "user1";
+ String up = "secretW0rd";
+ String du = "sub.server.onap.org:8443/deliver/here";
+ String lu = "https://drps.onap.org:8443/sublog/123";
+ boolean u100 = true;
+
+ if ( l.contains( "edge" ) ) {
+ return new DR_Sub( edge_loc, un, up, feed, du, lu, u100 );
+ }
+ return new DR_Sub( central_loc, un, up, feed, du, lu, u100 );
+ }
+
+ public DR_Node genDR_Node( String l ) {
+ String version = "1.0.1";
+ RandomInteger ri = new RandomInteger( 1000 );
+ int i = ri.next();
+ String fqdn = String.format( "drns%d.onap.org", i );
+ String host = String.format( "host%d.onap.org", i );
+
+ if ( l.contains( "edge" ) ) {
+ return new DR_Node( fqdn, edge_loc, host, version );
+ }
+ return new DR_Node( fqdn, central_loc, host, version );
+ }
+
+
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/ReflectionHarness.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/ReflectionHarness.java
new file mode 100644
index 0000000..be4b754
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/testframework/ReflectionHarness.java
@@ -0,0 +1,169 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.testframework;
+
+import static java.lang.System.err;
+import static java.lang.System.out;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+public class ReflectionHarness {
+ private static final String fmt = "%24s: %s%n";
+
+
+ // following 2 functions taken from: http://tutorials.jenkov.com/java-reflection/getters-setters.html
+ public static boolean isGetter(Method method){
+ if(!method.getName().startsWith("get")) return false;
+ if(method.getParameterTypes().length != 0) return false;
+ if(void.class.equals(method.getReturnType())) return false;
+ return true;
+ }
+
+ public static boolean isSetter(Method method){
+ if(!method.getName().startsWith("set")) return false;
+ if(method.getParameterTypes().length != 1) return false;
+ return true;
+ }
+
+ private void testGetter( Class<?> c, Method m, Class<?>[] pType, String val ) {
+ out.format( fmt, "testGetter: Method Name", m.getName() );
+ Class retType = m.getReturnType();
+ out.format( fmt, "testGetter: Return Type ", retType );
+ out.format( fmt, "testGetter: val ", (val != null)?val:"null" );
+ assertTrue( pType.length == 0 );
+
+ try {
+ Object t = c.newInstance();
+
+ try {
+ m.setAccessible(true);
+ Object o = m.invoke( t );
+
+ if( retType.equals( Class.forName( "java.lang.String" ) ) ) {
+ if ( val == null ) {
+ out.format( fmt, "testGetter: expected null, got ", (o != null)?o:"null" );
+ assert( o == null );
+ } else {
+ out.format( fmt, "testGetter: expected val, got ", (o != null)?o:"null" );
+ assert( o.equals( val ) );
+ }
+ } else {
+ out.format( fmt, "testGetter: " + m.getName() + " untested retType", retType );
+
+ }
+
+ } catch (InvocationTargetException e ) {
+ Throwable cause = e.getCause();
+ err.format( "%s() returned %x%n", m.getName(), cause.getMessage() );
+ }
+
+ } catch (ClassNotFoundException nfe ){
+ nfe.printStackTrace();
+ } catch (IllegalArgumentException ae ) {
+ ae.printStackTrace();
+ } catch (InstantiationException ie ) {
+ ie.printStackTrace();
+ } catch (IllegalAccessException iae ) {
+ iae.printStackTrace();
+ }
+ }
+
+ private void testSetter( Class<?> c, Method m, Class<?>[] pType ) {
+ //out.format( fmt, "testSetter: Method Name", m.getName() );
+ Class retType = m.getReturnType();
+ //out.format( fmt, "testSetter: Return Type ", retType );
+ //out.format( fmt, "testSetter: val ", (val != null)?val:"null" );
+ assertTrue( pType.length == 1 );
+
+ try {
+ Object t = c.newInstance();
+
+ try {
+ m.setAccessible(true);
+ //out.format( fmt, "testSetter: " + m.getName() + " to try pType", pType[0] );
+ if ( pType[0].equals( Class.forName( "java.lang.String" ) ) ) {
+ String val = "Validate123";
+ Object o = m.invoke( t, val );
+ } else if ( pType[0].equals( boolean.class ) ) { // note primitive class notation
+ boolean b = true;
+ Object o = m.invoke( t, b );
+ } else {
+ out.format( fmt, "testSetter: " + m.getName() + " untested pType", pType[0] );
+ }
+
+ } catch (InvocationTargetException e ) {
+ Throwable cause = e.getCause();
+ err.format( "%s() returned %x%n", m.getName(), cause.getMessage() );
+ }
+
+ } catch (ClassNotFoundException nfe ){
+ nfe.printStackTrace();
+ } catch (IllegalArgumentException ae ) {
+ ae.printStackTrace();
+ } catch (InstantiationException ie ) {
+ ie.printStackTrace();
+ } catch (IllegalAccessException iae ) {
+ iae.printStackTrace();
+ }
+ }
+
+ public void reflect(String... args) {
+ try {
+ Class<?> c = Class.forName(args[0]);
+ Method[] allMethods = c.getDeclaredMethods();
+ String methodPrefix = args[1];
+ for (Method m : allMethods) {
+ if (!m.getName().startsWith(methodPrefix)) {
+ continue;
+ }
+ //out.format("%s%n", m.toGenericString());
+
+ //out.format(fmt, "ReturnType", m.getReturnType());
+ //out.format(fmt, "GenericReturnType", m.getGenericReturnType());
+
+ Class<?>[] pType = m.getParameterTypes();
+ Type[] gpType = m.getGenericParameterTypes();
+ for (int i = 0; i < pType.length; i++) {
+ //out.format(fmt,"ParameterType", pType[i]);
+ //out.format(fmt,"GenericParameterType", gpType[i]);
+ }
+ if ( isGetter( m ) ) {
+ testGetter( c, m, pType , args[2]);
+ } else if ( isSetter( m ) ) {
+ testSetter( c, m, pType );
+ }
+
+ Class<?>[] xType = m.getExceptionTypes();
+ Type[] gxType = m.getGenericExceptionTypes();
+ for (int i = 0; i < xType.length; i++) {
+ //out.format(fmt,"ExceptionType", xType[i]);
+ //out.format(fmt,"GenericExceptionType", gxType[i]);
+ }
+ }
+
+ // production code should handle these exceptions more gracefully
+ } catch (ClassNotFoundException x) {
+ x.printStackTrace();
+ }
+ }
+}
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapConfigTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapConfigTest.java
new file mode 100644
index 0000000..6ef05c0
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapConfigTest.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.util;
+
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DmaapConfigTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ DmaapConfig g;
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.util.DmaapConfig", "get", "" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ rh.reflect( "org.onap.dmaap.dbcapi.util.DmaapConfig", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+
+ String f = g.getConfigFileName();
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapTimestampTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapTimestampTest.java
new file mode 100644
index 0000000..33d1d17
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/DmaapTimestampTest.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.util;
+
+import org.junit.Test;
+
+import java.util.Date;
+
+import static org.junit.Assert.assertTrue;
+
+public class DmaapTimestampTest {
+
+ private DmaapTimestamp dmaapTimestamp = new DmaapTimestamp();
+
+ @Test
+ public void mark_shouldUpdateTimestamp() {
+ dmaapTimestamp = new DmaapTimestamp(new Date(10));
+ Date timestamp = dmaapTimestamp.getVal();
+
+ dmaapTimestamp.mark();
+
+ assertTrue(timestamp.before(dmaapTimestamp.getVal()));
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/FqdnTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/FqdnTest.java
new file mode 100644
index 0000000..7c7815f
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/FqdnTest.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 IBM 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.onap.dmaap.dbcapi.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class FqdnTest {
+
+ @Test
+ public void testIsValid() {
+ assertTrue(Fqdn.isValid("www.ibm.com"));
+ assertFalse(Fqdn.isValid("testuser@ibm.com"));
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/GraphTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/GraphTest.java
new file mode 100644
index 0000000..770ee65
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/GraphTest.java
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2018 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.onap.dmaap.dbcapi.util;
+
+import org.onap.dmaap.dbcapi.model.*;
+import org.onap.dmaap.dbcapi.service.*;
+import org.onap.dmaap.dbcapi.testframework.ReflectionHarness;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.*;
+
+public class GraphTest {
+
+ private static final String fmt = "%24s: %s%n";
+
+ ReflectionHarness rh = new ReflectionHarness();
+
+ Graph g;
+
+
+ @Before
+ public void setUp() throws Exception {
+ HashMap<String, String> hm = new HashMap<String,String>();
+ g = new Graph( hm );
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void test1() {
+
+
+ rh.reflect( "org.onap.dmaap.dbcapi.util.Graph", "get", "idNotSet@namespaceNotSet:pwdNotSet" );
+
+ }
+
+ @Test
+ public void test2() {
+ String v = "Validate";
+ //rh.reflect( "org.onap.dmaap.dbcapi.util.Graph", "set", v );
+
+ }
+
+ @Test
+ public void test3() {
+ String loc = "central-onap";
+ String[] actions = { "pub", "sub" };
+ DcaeLocationService dls = new DcaeLocationService();
+ DcaeLocation dl = new DcaeLocation( "CLLI123", "central-layer", loc, "aZone", "10.10.10.10" );
+ dls.addDcaeLocation( dl );
+ MR_Client mrc = new MR_Client();
+ mrc.setAction( actions );
+ List<MR_Client> cl = new ArrayList<MR_Client>();
+ cl.add( mrc );
+ cl.add( new MR_Client( loc, "aTopic", "ignore", actions ) );
+
+ g = new Graph( cl, true );
+
+ HashMap<String, String> hm = new HashMap<String, String>();
+
+
+ String s = g.put( "aKey", "aVal" );
+ s = g.get( "aKey" );
+
+ s = g.getCentralLoc();
+ g.setHasCentral( true );
+ g.hasCentral();
+
+ hm = g.getGraph();
+
+ Collection<String> k = g.getKeys();
+
+ }
+
+
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java
new file mode 100644
index 0000000..8db9d2e
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/PermissionBuilderTest.java
@@ -0,0 +1,164 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.dmaap.dbcapi.model.Dmaap;
+import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
+import org.onap.dmaap.dbcapi.service.DmaapService;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PermissionBuilderTest {
+
+ private static final String DMAAP_NAME = "mr";
+ private PermissionBuilder permissionBuilder;
+ @Mock
+ private DmaapConfig dmaapConfig;
+ @Mock
+ private DmaapService dmaapService;
+ @Mock
+ private HttpServletRequest request;
+
+
+ @Test
+ public void updateDmaapInstance_shouldSetBootInstance_whenDmaapIsNotInitialized() {
+ //given
+ doReturn(null).when(dmaapService).getDmaap();
+ permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+ //when
+ permissionBuilder.updateDmaapInstance();
+
+ //then
+ assertEquals(PermissionBuilder.BOOT_INSTANCE, permissionBuilder.getInstance());
+ }
+
+ @Test
+ public void updateDmaapInstance_shouldSetBootInstance_whenDmaapIsInitializedWithDefaultInstance() {
+ //given
+ doReturn(provideDefaultInstance()).when(dmaapService).getDmaap();
+ permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+ //when
+ permissionBuilder.updateDmaapInstance();
+
+ //then
+ assertEquals(PermissionBuilder.BOOT_INSTANCE, permissionBuilder.getInstance());
+ }
+
+ @Test
+ public void updateDmaapInstance_shouldSetRealInstance_whenDmaapServiceProvidesOne() {
+ //given
+ when(dmaapService.getDmaap()).thenReturn(provideDefaultInstance(), provideRealInstance(DMAAP_NAME));
+ permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+ //when
+ permissionBuilder.updateDmaapInstance();
+
+ //then
+ assertEquals(DMAAP_NAME, permissionBuilder.getInstance());
+ }
+
+ @Test
+ public void updateDmaapInstance_shouldNotUpdateDmaapInstance_whenAlreadyInitializedWithRealInstance() {
+ //given
+ when(dmaapService.getDmaap()).thenReturn(provideRealInstance(DMAAP_NAME), provideRealInstance("newName"));
+ permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+ //when
+ permissionBuilder.updateDmaapInstance();
+
+ //then
+ assertEquals(DMAAP_NAME, permissionBuilder.getInstance());
+ verify(dmaapService, atMost(1)).getDmaap();
+ }
+
+ @Test
+ public void buildPermission_shouldBuildPermissionWithBootInstance() {
+ //given
+ String path = "/dmaap";
+ String method = "GET";
+ initPermissionBuilder(path, method, provideDefaultInstance());
+
+ //when
+ String permission = permissionBuilder.buildPermission(request);
+
+ //then
+ assertEquals("org.onap.dmaap-bc.api.dmaap|boot|GET", permission);
+ }
+
+ @Test
+ public void buildPermission_shouldBuildPermissionWithRealInstance() {
+ //given
+ String path = "/dmaap";
+ String method = "GET";
+ initPermissionBuilder(path, method, provideRealInstance(DMAAP_NAME));
+
+ //when
+ String permission = permissionBuilder.buildPermission(request);
+
+ //then
+ assertEquals("org.onap.dmaap-bc.api.dmaap|mr|GET", permission);
+ }
+
+ @Test
+ public void buildPermission_shouldBuildPermissionWhenUrlContainsId() {
+ //given
+ String path = "/topics/topic_id_123";
+ String method = "GET";
+ initPermissionBuilder(path, method, provideRealInstance(DMAAP_NAME));
+
+ //when
+ String permission = permissionBuilder.buildPermission(request);
+
+ //then
+ assertEquals("org.onap.dmaap-bc.api.topics|mr|GET", permission);
+ }
+
+ private void initPermissionBuilder(String path, String method, Dmaap dmaapInstance) {
+ when(dmaapConfig.getProperty(PermissionBuilder.API_NS_PROP, PermissionBuilder.DEFAULT_API_NS))
+ .thenReturn(PermissionBuilder.DEFAULT_API_NS);
+ when(dmaapService.getDmaap()).thenReturn(dmaapInstance);
+ permissionBuilder = new PermissionBuilder(dmaapConfig, dmaapService);
+
+ when(request.getPathInfo()).thenReturn(path);
+ when(request.getMethod()).thenReturn(method);
+ }
+
+ private Dmaap provideDefaultInstance() {
+ return new Dmaap.DmaapBuilder().setVer("0").setTnr("").setDn("").setDpu("").setLu("").setBat("").setNk("").setAko("").createDmaap();
+ }
+
+ private Dmaap provideRealInstance(String dmaapName) {
+ Dmaap dmaap = new Dmaap.DmaapBuilder().setVer("1").setTnr("org.onap.dmaap").setDn(dmaapName).setDpu("https://dmaap-dr-prov:8443").setLu("").setBat("DCAE_MM_AGENT").setNk("").setAko("").createDmaap();
+ dmaap.setStatus(DmaapObject_Status.VALID);
+ return dmaap;
+ }
+
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomIntegerTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomIntegerTest.java
new file mode 100644
index 0000000..1184cdb
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomIntegerTest.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class RandomIntegerTest {
+
+ private static final int RANGE = 10;
+ private RandomInteger ri = new RandomInteger(RANGE);
+
+ @Test
+ public void next_shouldReturnIntegerFromGivenRange() {
+
+ int next = ri.next();
+
+ assertTrue(next >= 0 && next <= RANGE);
+ }
+
+}
+
diff --git a/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomStringTest.java b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomStringTest.java
new file mode 100644
index 0000000..e549dc3
--- /dev/null
+++ b/dmaap-bc/src/test/java/org/onap/dmaap/dbcapi/util/RandomStringTest.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dmaap
+ * ================================================================================
+ * Copyright (C) 2019 Nokia 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.onap.dmaap.dbcapi.util;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class RandomStringTest {
+
+ private static final int LENGTH = 10;
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+ private RandomString randomString = new RandomString(LENGTH);
+
+ @Test
+ public void nextString_shouldReturnStringWithGivenLength() {
+
+ String nextString = randomString.nextString();
+
+ assertEquals(LENGTH, nextString.length());
+ }
+
+ @Test
+ public void nextString_shouldReturnAlphanumeric() {
+
+ String nextString = randomString.nextString();
+
+ assertTrue(nextString.matches("[a-z0-9]*"));
+ }
+
+ @Test
+ public void constructor_shouldThrowExceptionForNegativeLength() {
+
+ thrown.expect(IllegalArgumentException.class);
+
+ new RandomString(-1);
+ }
+} \ No newline at end of file
diff --git a/dmaap-bc/src/test/resources/cadi.properties b/dmaap-bc/src/test/resources/cadi.properties
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dmaap-bc/src/test/resources/cadi.properties
diff --git a/dmaap-bc/src/test/resources/dmaapbc.properties b/dmaap-bc/src/test/resources/dmaapbc.properties
new file mode 100644
index 0000000..5290032
--- /dev/null
+++ b/dmaap-bc/src/test/resources/dmaapbc.properties
@@ -0,0 +1,274 @@
+# Copyright © 2018 AT&T, Amdocs, Bell Canada 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.
+
+
+#####################################################
+#
+# Hooks for specific environment configurations
+#
+#####################################################
+# Indicator for whether to use AAF for authentication
+#UseAAF: false
+
+# Stub out southbound calls for Unit Test cases to run. e.g. not timeout
+# Comment out in other environments to get default (No)
+UnitTest: Yes
+
+
+#####################################################
+#
+# Settings for Southbound API: Datarouter
+#
+#####################################################
+
+# URI to retrieve dynamic DR configuration
+ProvisioningURI: /internal/prov
+
+# indicator for handling feed delete:
+# DeleteOnDR - means use the DR API to DELETE a feed. (default for backwards compatibility)
+# SimulateDelete - means preserve the feed on DR (after cleaning it up), and mark as DELETED in DBCL. Better for cloudify environments.
+Feed.deleteHandling: DeleteOnDR
+
+###########################################################
+# The following properties default to match ONAP DR instance.
+# However, there are some non-ONAP DR instances that require other values.
+# Sets the X-DR-ON-BEHALF-OF HTTP Header value
+#DR.onBehalfHeader:
+# Value for the Content-Type Header in DR Feed API
+#DR.feedContentType:
+# Value for the Content-Type Header in DR Subscription API
+#DR.subContentType:
+#
+# END OF properties helpful for non-ONAP DR instance.
+############################################################
+
+#####################################################
+#
+# Settings for Soutbound API: Postgresql
+#
+#####################################################
+# flag indicates if we are using postgresql
+UsePGSQL: false
+
+# postgres host name
+# Need to connect to PG primary service, designated by service.name2
+DB.host: none
+
+# postgres schema name
+#DB.schema: {{ .Values.postgres.config.pgDatabase }}
+
+# postgres user name
+#DB.user: {{ .Values.postgres.config.pgUserName }}
+
+# postgres user password
+DB.cred: none
+
+
+#####################################################
+#
+# Settings for Soutbound API: Message Router
+#
+#####################################################
+# indicator for multi-site (locations) deployment. Give clue to buscontroller whether
+# there is a need for message replication between edge and central.
+# ONAP Casablanca is a single site deployment
+MR.multisite: true
+
+# FQDN of primary message router.
+# In ONAP Casablanca, there is only 1 message router service, so use that.
+# In a multi-site, MR cluster deployment, use the CNAME DNS entry which resolves to the primary central MR
+MR.CentralCname: notSet.onap.org
+
+# Indicator for whether we want hostname verification on SSL connection to MR
+MR.hostnameVerify: false
+
+# MR Client Delete Level thoroughness:
+# 0 = don't delete
+# 1 = delete from persistent store
+# 2 = delete from persistent store (DB) and authorization store (AAF)
+MR.ClientDeleteLevel: 1
+
+# namespace of MR Topic Factory
+MR.TopicFactoryNS: org.onap.dmaap.mr.topicFactory
+
+# AAF Role assigned to Topic Manager Identity
+MR.TopicMgrRole: org.onap.dmaap-bc.TopicMgr
+
+# MR topic ProjectID (used in certain topic name generation formats)
+MR.projectID: 23456
+
+# Use Basic Authentication when provisioning topics
+#MR.authentication: basicAuth
+
+# MR topic name style (default is FQTN_LEGACY_FORMAT)
+MR.topicStyle: FQTN_LEGACY_FORMAT
+#
+# end of MR Related Properties
+################################################################################
+
+
+#####################################################
+#
+# Settings for Southbound API: CADI
+#
+#####################################################
+# path to cadi.properties
+#cadi.properties: /opt/app/osaaf/local/org.onap.dmaap-bc.props
+
+#####################################################
+#
+# Settings for Southbound API: AAF proxy
+#
+#####################################################
+# URL of the AAF server
+aaf.URL: https://localhost:8100/proxy
+
+# TopicMgr Identity
+aaf.TopicMgrUser: idNotSet@namespaceNotSet
+
+# Password for TopicMgr identity
+aaf.TopicMgrPassword: pwdNotSet
+
+# Buscontroller Admin Identity
+aaf.AdminUser: idNotSet@namespaceNotSet
+
+# Admin Password
+aaf.AdminPassword: pwdNotSet
+
+# Identity that is owner of any created namespaces for topics
+#aaf.NsOwnerIdentity: ownerNotSet@namespaceNotSet.org
+
+
+# this overrides the Class used for Decryption.
+# This allows for a plugin encryption/decryption method if needed.
+# Call this Class for decryption at runtime.
+#AafDecryption.Class: com.company.proprietaryDecryptor
+
+# location of the codec keyfile used to decrypt passwords in this properties file before they are passed to AAF
+# Not used in ONAP, but possibly used with Decryption override class.
+CredentialCodecKeyfile: etc/LocalKey
+
+#
+# endof AAF Properties
+####################################################
+
+
+#####################################################
+#
+# Settings for authorization of DBCAPI
+#
+#####################################################
+# Namespace for URI values for the API used to create AAF permissions
+# e.g. if ApiNamespace is X.Y.dmaapbc.api then for URI /mr_clients we create AAF perm X.Y.dmaapbc.api.mr_clients
+ApiNamespace: org.onap.dmaapBC.api
+
+# If API authorization is required, then implement a class to enforce it.
+# This overrides the Class used for API permission check.
+ApiPermission.Class: org.onap.dmaap.dbcapi.authentication.AllowAll
+
+#####################################################
+#
+# Settings for Southbound API: MirrorMaker provisioning
+#
+#####################################################
+# AAF Role of client publishing MM prov cmds
+MM.ProvRole: org.onap.dmaapBC.MMprov.prov
+
+# AAF identity when publishing MM prov cmds
+MM.ProvUserMechId: idNotSet@namespaceNotSet
+
+# pwd for Identity used to publish MM prov cmds
+MM.ProvUserPwd: pwdNotSet
+
+# AAF Role of MirrorMaker agent subscribed to prov cmds.
+MM.AgentRole: org.onap.dmaapBC.MMagent.agent
+
+#####################################################
+#
+# Certificate Management
+#
+#####################################################
+
+# Indicates how we are expecting certificates to be provided:
+# cadi - a set of artifacts will be downloaded from AAF at deployment time, and details will be in a cadi properties file
+# legacy (default) - artifacts will be installed manually or some other way and details will be in this file
+CertificateManagement: legacy
+
+# When CertificateManagement is cadi, then this is where all the cadi properties will be.
+# Note that the cadi properties include where the cert is, and the encrypted passwords to read.
+cadi.properties: /opt/app/osaaf/local/org.onap.dmaap-bc.props
+
+###########################################################################################
+# When CertificateManagement is legacy, we need to provide more details about cert handling:
+#CertificateManagement: legacy
+# the type of keystore for https (for legacy CertificateManagment only)
+KeyStoreType: jks
+
+# path to the keystore file (for legacy CertificateManagment only)
+KeyStoreFile: etc/keystore
+
+# password for the https keystore (for legacy CertificateManagment only)
+KeyStorePassword: changeit
+# password for the private key in the https keystore (for legacy CertificateManagment only)
+KeyPassword: changeit
+
+# type of truststore for https (for legacy CertificateManagment only)
+TrustStoreType: jks
+
+# path to the truststore for https (for legacy CertificateManagment only)
+TrustStoreFile: ${DMAAPBC_TSTOREFILE}
+
+# password for the https truststore (for legacy CertificateManagment only)
+TrustStorePassword: changeit
+#
+# END OF legacy CertificateManagement properties
+###########################################################################################
+
+
+#####################################################
+#
+# HTTP Server Configuration
+#
+#####################################################
+
+# Allow http access to dbcapi
+HttpAllowed: true
+
+# listen to http port within this container (server)
+IntHttpPort: 8080
+
+# listen to https port within this container (server)
+# set to 0 if no certificates are available.
+IntHttpsPort: 0
+
+
+inHttpsPort: 0
+
+#####################################################
+#
+# Deprecated properties
+#
+#####################################################
+# csit: stubs out some southbound APIs for csit (deprecated)
+#csit: No
+# name of this DMaaP instance (deprecated)
+#DmaapName: onap-cit
+# external port number for https taking port mapping into account (deprecated)
+#ExtHttpsPort: 443
+# path to the file used to trigger an orderly shutdown (deprecated)
+#QuiesceFile: etc/SHUTDOWN
+# FQDN of DR Prov Server (deprecated)
+#DR.provhost: localhost
+# root of topic namespace (decrecated)
+#topicNsRoot: org.onap.dcae.dmaap