From 174b3b1db95d277ec8788ae751d6ebb20707c964 Mon Sep 17 00:00:00 2001 From: "Vikram Potturi(apotturi)" Date: Wed, 11 Apr 2018 17:51:52 -0400 Subject: [PATCH] Adding code to the jar Change-Id: I25fe0ff6a324aab97c13173fa406d427139970e1 Issue-ID: MUSIC-68 Signed-off-by: Vikram Potturi(apotturi) --- jar/DO_NOT_EDIT_ANYTHING_IN_THIS_FOLDER.md | 1 + jar/pom.xml | 470 +++++++ jar/src/main/java/LICENSE.txt | 24 + .../org/onap/music/datastore/MusicDataStore.java | 451 +++++++ .../onap/music/datastore/PreparedQueryObject.java | 79 ++ .../music/datastore/jsonobjects/AAFResponse.java | 42 + .../music/datastore/jsonobjects/JSONObject.java | 37 + .../music/datastore/jsonobjects/JsonDelete.java | 87 ++ .../music/datastore/jsonobjects/JsonInsert.java | 122 ++ .../music/datastore/jsonobjects/JsonKeySpace.java | 77 ++ .../datastore/jsonobjects/JsonLeasedLock.java | 52 + .../music/datastore/jsonobjects/JsonOnboard.java | 83 ++ .../music/datastore/jsonobjects/JsonSelect.java | 59 + .../music/datastore/jsonobjects/JsonTable.java | 117 ++ .../music/datastore/jsonobjects/JsonUpdate.java | 132 ++ .../music/datastore/jsonobjects/NameSpace.java | 47 + .../music/eelf/healthcheck/MusicHealthCheck.java | 175 +++ .../music/eelf/logging/EELFLoggerDelegate.java | 354 ++++++ .../music/eelf/logging/format/AppMessages.java | 183 +++ .../onap/music/eelf/logging/format/ErrorCodes.java | 106 ++ .../music/eelf/logging/format/ErrorSeverity.java | 37 + .../onap/music/eelf/logging/format/ErrorTypes.java | 44 + .../music/exceptions/MusicExceptionMapper.java | 53 + .../music/exceptions/MusicLockingException.java | 74 ++ .../exceptions/MusicPolicyVoilationException.java | 79 ++ .../onap/music/exceptions/MusicQueryException.java | 89 ++ .../music/exceptions/MusicServiceException.java | 84 ++ .../onap/music/lockingservice/LockListener.java | 39 + .../onap/music/lockingservice/MusicLockState.java | 137 +++ .../music/lockingservice/MusicLockingService.java | 166 +++ .../onap/music/lockingservice/ProtocolSupport.java | 208 ++++ .../org/onap/music/lockingservice/ZNodeName.java | 118 ++ .../lockingservice/ZkStatelessLockService.java | 339 +++++ .../music/lockingservice/ZooKeeperOperation.java | 42 + .../main/java/org/onap/music/main/CachingUtil.java | 420 +++++++ .../java/org/onap/music/main/CronJobManager.java | 47 + .../main/java/org/onap/music/main/MusicCore.java | 992 +++++++++++++++ .../main/java/org/onap/music/main/MusicDigest.java | 78 ++ .../main/java/org/onap/music/main/MusicUtil.java | 560 +++++++++ .../org/onap/music/main/PropertiesListener.java | 151 +++ .../main/java/org/onap/music/main/ResultType.java | 41 + .../main/java/org/onap/music/main/ReturnType.java | 74 ++ .../music/response/jsonobjects/JsonResponse.java | 265 ++++ .../org/onap/music/rest/RestMusicAdminAPI.java | 372 ++++++ .../java/org/onap/music/rest/RestMusicBmAPI.java | 307 +++++ .../java/org/onap/music/rest/RestMusicDataAPI.java | 1289 ++++++++++++++++++++ .../onap/music/rest/RestMusicHealthCheckAPI.java | 113 ++ .../org/onap/music/rest/RestMusicLocksAPI.java | 423 +++++++ .../java/org/onap/music/rest/RestMusicQAPI.java | 251 ++++ .../java/org/onap/music/rest/RestMusicTestAPI.java | 67 + .../org/onap/music/rest/RestMusicVersionAPI.java | 63 + jar/src/main/resources/LICENSE.txt | 24 + jar/src/main/resources/Resources.properties | 50 + jar/src/main/resources/cache.ccf | 56 + jar/src/main/resources/logback.xml | 270 ++++ jar/src/main/resources/project.properties | 4 + jar/src/main/webapp/WEB-INF/classes/LICENSE.txt | 24 + .../webapp/WEB-INF/classes/Resources.properties | 50 + jar/src/main/webapp/WEB-INF/classes/cache.ccf | 56 + jar/src/main/webapp/WEB-INF/classes/logback.xml | 270 ++++ .../onap/music/datastore/MusicDataStore$1.class | Bin 0 -> 1145 bytes .../org/onap/music/datastore/MusicDataStore.class | Bin 0 -> 16991 bytes .../onap/music/datastore/PreparedQueryObject.class | Bin 0 -> 1269 bytes .../music/datastore/jsonobjects/AAFResponse.class | Bin 0 -> 1131 bytes .../music/datastore/jsonobjects/JSONObject.class | Bin 0 -> 579 bytes .../music/datastore/jsonobjects/JsonDelete.class | Bin 0 -> 2670 bytes .../music/datastore/jsonobjects/JsonInsert.class | Bin 0 -> 3605 bytes .../music/datastore/jsonobjects/JsonKeySpace.class | Bin 0 -> 2287 bytes .../datastore/jsonobjects/JsonLeasedLock.class | Bin 0 -> 1172 bytes .../music/datastore/jsonobjects/JsonOnboard.class | Bin 0 -> 1855 bytes .../music/datastore/jsonobjects/JsonSelect.class | Bin 0 -> 1603 bytes .../music/datastore/jsonobjects/JsonTable.class | Bin 0 -> 3200 bytes .../music/datastore/jsonobjects/JsonUpdate.class | Bin 0 -> 3856 bytes .../music/datastore/jsonobjects/NameSpace.class | Bin 0 -> 1024 bytes .../music/eelf/healthcheck/MusicHealthCheck.class | Bin 0 -> 3731 bytes .../music/eelf/logging/EELFLoggerDelegate.class | Bin 0 -> 7091 bytes .../music/eelf/logging/format/AppMessages.class | Bin 0 -> 6182 bytes .../music/eelf/logging/format/ErrorCodes.class | Bin 0 -> 979 bytes .../music/eelf/logging/format/ErrorSeverity.class | Bin 0 -> 1426 bytes .../music/eelf/logging/format/ErrorTypes.class | Bin 0 -> 1695 bytes .../music/exceptions/MusicExceptionMapper.class | Bin 0 -> 2230 bytes .../music/exceptions/MusicLockingException.class | Bin 0 -> 987 bytes .../exceptions/MusicPolicyVoilationException.class | Bin 0 -> 1075 bytes .../music/exceptions/MusicQueryException.class | Bin 0 -> 1199 bytes .../music/exceptions/MusicServiceException.class | Bin 0 -> 1430 bytes .../onap/music/lockingservice/LockListener.class | Bin 0 -> 187 bytes .../lockingservice/MusicLockState$LockStatus.class | Bin 0 -> 1301 bytes .../onap/music/lockingservice/MusicLockState.class | Bin 0 -> 4553 bytes .../music/lockingservice/MusicLockingService.class | Bin 0 -> 7236 bytes .../music/lockingservice/ProtocolSupport$1.class | Bin 0 -> 1667 bytes .../music/lockingservice/ProtocolSupport.class | Bin 0 -> 6010 bytes .../org/onap/music/lockingservice/ZNodeName.class | Bin 0 -> 3399 bytes .../lockingservice/ZkStatelessLockService$1.class | Bin 0 -> 1421 bytes .../lockingservice/ZkStatelessLockService$2.class | Bin 0 -> 1438 bytes .../lockingservice/ZkStatelessLockService$3.class | Bin 0 -> 1221 bytes .../lockingservice/ZkStatelessLockService$4.class | Bin 0 -> 1889 bytes ...atelessLockService$LockZooKeeperOperation.class | Bin 0 -> 4331 bytes .../lockingservice/ZkStatelessLockService.class | Bin 0 -> 8894 bytes .../music/lockingservice/ZooKeeperOperation.class | Bin 0 -> 274 bytes .../classes/org/onap/music/main/CachingUtil.class | Bin 0 -> 17372 bytes .../org/onap/music/main/CronJobManager.class | Bin 0 -> 1321 bytes .../org/onap/music/main/MusicCore$Condition.class | Bin 0 -> 1541 bytes .../classes/org/onap/music/main/MusicCore.class | Bin 0 -> 28476 bytes .../classes/org/onap/music/main/MusicDigest.class | Bin 0 -> 1062 bytes .../classes/org/onap/music/main/MusicUtil$1.class | Bin 0 -> 1166 bytes .../classes/org/onap/music/main/MusicUtil.class | Bin 0 -> 12499 bytes .../org/onap/music/main/PropertiesListener.class | Bin 0 -> 6316 bytes .../classes/org/onap/music/main/ResultType.class | Bin 0 -> 1527 bytes .../classes/org/onap/music/main/ReturnType.class | Bin 0 -> 1976 bytes .../music/response/jsonobjects/JsonResponse.class | Bin 0 -> 4990 bytes .../org/onap/music/rest/RestMusicAdminAPI.class | Bin 0 -> 12920 bytes .../org/onap/music/rest/RestMusicBmAPI.class | Bin 0 -> 11103 bytes .../rest/RestMusicDataAPI$RowIdentifier.class | Bin 0 -> 913 bytes .../org/onap/music/rest/RestMusicDataAPI.class | Bin 0 -> 40199 bytes .../onap/music/rest/RestMusicHealthCheckAPI.class | Bin 0 -> 3351 bytes .../org/onap/music/rest/RestMusicLocksAPI.class | Bin 0 -> 13871 bytes .../org/onap/music/rest/RestMusicQAPI.class | Bin 0 -> 7943 bytes .../org/onap/music/rest/RestMusicTestAPI.class | Bin 0 -> 2338 bytes .../org/onap/music/rest/RestMusicVersionAPI.class | Bin 0 -> 2133 bytes .../main/webapp/WEB-INF/classes/project.properties | 4 + jar/src/test/java/LICENSE.txt | 24 + .../org/onap/music/unittests/CassandraCQL.java | 256 ++++ .../org/onap/music/unittests/JsonResponseTest.java | 83 ++ .../onap/music/unittests/MusicDataStoreTest.java | 162 +++ .../org/onap/music/unittests/MusicUtilTest.java | 207 ++++ .../org/onap/music/unittests/ResultTypeTest.java | 43 + .../org/onap/music/unittests/ReturnTypeTest.java | 83 ++ .../org/onap/music/unittests/TestLockStore.java | 53 + .../org/onap/music/unittests/TestMusicCore.java | 489 ++++++++ .../music/unittests/TestMusicCoreIntegration.java | 176 +++ .../onap/music/unittests/TestRestMusicData.java | 718 +++++++++++ .../unittests/jsonobjects/AAFResponseTest.java | 54 + .../unittests/jsonobjects/JsonDeleteTest.java | 86 ++ .../unittests/jsonobjects/JsonInsertTest.java | 86 ++ .../unittests/jsonobjects/JsonKeySpaceTest.java | 72 ++ .../unittests/jsonobjects/JsonLeasedLockTest.java | 53 + .../unittests/jsonobjects/JsonOnboardTest.java | 78 ++ .../unittests/jsonobjects/JsonSelectTest.java | 41 + .../music/unittests/jsonobjects/JsonTableTest.java | 99 ++ .../unittests/jsonobjects/JsonUpdateTest.java | 103 ++ 140 files changed, 13494 insertions(+) create mode 100644 jar/DO_NOT_EDIT_ANYTHING_IN_THIS_FOLDER.md create mode 100644 jar/pom.xml create mode 100644 jar/src/main/java/LICENSE.txt create mode 100644 jar/src/main/java/org/onap/music/datastore/MusicDataStore.java create mode 100644 jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java create mode 100755 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java create mode 100644 jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java create mode 100644 jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java create mode 100644 jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java create mode 100644 jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java create mode 100644 jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java create mode 100644 jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java create mode 100644 jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java create mode 100644 jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java create mode 100644 jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java create mode 100644 jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java create mode 100644 jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java create mode 100644 jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/LockListener.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java create mode 100644 jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java create mode 100755 jar/src/main/java/org/onap/music/main/CachingUtil.java create mode 100644 jar/src/main/java/org/onap/music/main/CronJobManager.java create mode 100644 jar/src/main/java/org/onap/music/main/MusicCore.java create mode 100644 jar/src/main/java/org/onap/music/main/MusicDigest.java create mode 100755 jar/src/main/java/org/onap/music/main/MusicUtil.java create mode 100755 jar/src/main/java/org/onap/music/main/PropertiesListener.java create mode 100644 jar/src/main/java/org/onap/music/main/ResultType.java create mode 100644 jar/src/main/java/org/onap/music/main/ReturnType.java create mode 100644 jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java create mode 100755 jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java create mode 100644 jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java create mode 100755 jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java create mode 100644 jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java create mode 100644 jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java create mode 100755 jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java create mode 100644 jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java create mode 100644 jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java create mode 100644 jar/src/main/resources/LICENSE.txt create mode 100644 jar/src/main/resources/Resources.properties create mode 100644 jar/src/main/resources/cache.ccf create mode 100644 jar/src/main/resources/logback.xml create mode 100644 jar/src/main/resources/project.properties create mode 100644 jar/src/main/webapp/WEB-INF/classes/LICENSE.txt create mode 100644 jar/src/main/webapp/WEB-INF/classes/Resources.properties create mode 100644 jar/src/main/webapp/WEB-INF/classes/cache.ccf create mode 100644 jar/src/main/webapp/WEB-INF/classes/logback.xml create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/MusicDataStore$1.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/MusicDataStore.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/PreparedQueryObject.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/AAFResponse.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JSONObject.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonDelete.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonInsert.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonKeySpace.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonLeasedLock.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonOnboard.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonSelect.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonTable.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonUpdate.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/NameSpace.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/healthcheck/MusicHealthCheck.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/EELFLoggerDelegate.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/AppMessages.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorCodes.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorSeverity.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorTypes.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicExceptionMapper.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicLockingException.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicPolicyVoilationException.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicQueryException.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicServiceException.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/LockListener.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState$LockStatus.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockingService.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ProtocolSupport$1.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ProtocolSupport.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZNodeName.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$1.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$2.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$3.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$4.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$LockZooKeeperOperation.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZooKeeperOperation.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/CachingUtil.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/CronJobManager.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore$Condition.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicDigest.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil$1.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/PropertiesListener.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/ResultType.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/ReturnType.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/response/jsonobjects/JsonResponse.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicAdminAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicBmAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicDataAPI$RowIdentifier.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicDataAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicHealthCheckAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicLocksAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicQAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicTestAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicVersionAPI.class create mode 100644 jar/src/main/webapp/WEB-INF/classes/project.properties create mode 100644 jar/src/test/java/LICENSE.txt create mode 100644 jar/src/test/java/org/onap/music/unittests/CassandraCQL.java create mode 100644 jar/src/test/java/org/onap/music/unittests/JsonResponseTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/MusicDataStoreTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/MusicUtilTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/ResultTypeTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/ReturnTypeTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/TestLockStore.java create mode 100644 jar/src/test/java/org/onap/music/unittests/TestMusicCore.java create mode 100644 jar/src/test/java/org/onap/music/unittests/TestMusicCoreIntegration.java create mode 100644 jar/src/test/java/org/onap/music/unittests/TestRestMusicData.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/AAFResponseTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonDeleteTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonInsertTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonKeySpaceTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonOnboardTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonSelectTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonTableTest.java create mode 100644 jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonUpdateTest.java diff --git a/jar/DO_NOT_EDIT_ANYTHING_IN_THIS_FOLDER.md b/jar/DO_NOT_EDIT_ANYTHING_IN_THIS_FOLDER.md new file mode 100644 index 00000000..d0baf49b --- /dev/null +++ b/jar/DO_NOT_EDIT_ANYTHING_IN_THIS_FOLDER.md @@ -0,0 +1 @@ +This folder (/jar) is not guaranteed to be around for Casablanca. diff --git a/jar/pom.xml b/jar/pom.xml new file mode 100644 index 00000000..83696a28 --- /dev/null +++ b/jar/pom.xml @@ -0,0 +1,470 @@ + + + 4.0.0 + org.onap.music + MUSIC + jar + 2.5.3 + + This is the MUSIC REST interface, packaged as a war file. + + + + org.onap.oparent + oparent + 0.1.1 + + + + + UTF-8 + 1.19 + 2.25.1 + 2.0.1 + 3.4.0 + 3.4.11 + + UTF-8 + UTF-8 + + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/org/onap/music/${project.version} + + ${maven.build.timestamp} + yyyy.MM.dd.HH.mm + + ${project.version}-${timestamp} + ${project.version}-latest + + + + + ecomp-releases + ECOMP Release Repository + ${onap.nexus.url}/${releaseNexusPath} + + + ecomp-snapshots + Snapshot Repository + ${nexusproxy}/${snapshotNexusPath} + + + ecomp-staging + Staging Repository + ${nexusproxy}/${stagingNexusPath} + + + + + MUSIC + src/main/java + src/main/webapp/WEB-INF/classes + src/test/java + target/test-classes + validate + + + src/main/resources + true + + + + + maven-eclipse-plugin + 2.9 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.7 + 1.7 + + jar/** + + + + + maven-war-plugin + 2.4 + + WebContent + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + make-a-jar + compile + + jar + + + + **/*.xml + **/*.properties + **/Sample* + + + + + + + org.apache.maven.plugins + maven-install-plugin + 2.4 + + + install + + install-file + + + jar + ${project.artifactId} + ${project.groupId} + ${project.version} + ${project.build.directory}/${project.artifactId}.jar + + + + + + + + + + + javax.servlet + servlet-api + 2.4 + provided + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + ch.qos.logback + logback-core + 1.2.3 + + + org.slf4j + slf4j-log4j12 + + + + + ch.qos.logback + logback-classic + 1.2.3 + + + org.slf4j + slf4j-log4j12 + + + + + com.att.eelf + eelf-core + 1.0.1-oss + + + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra.version} + + + + + + org.apache.zookeeper + zookeeper + ${zookeeper.version} + + + org.slf4j + slf4j-log4j12 + + + + + + + + com.sun.jersey + jersey-client + ${jersey1.version} + + + com.sun.jersey + jersey-server + ${jersey1.version} + + + com.sun.jersey + jersey-json + ${jersey1.version} + + + com.sun.jersey + jersey-servlet + ${jersey1.version} + + + + + org.apache.commons + commons-jcs-core + 2.2 + + + commons-codec + commons-codec + 1.11 + + + + + junit + junit + 4.12 + test + + + org.cassandraunit + cassandra-unit + 3.3.0.2 + test + + + org.apache.curator + curator-test + 2.3.0 + + + org.apache.zookeeper + zookeeper + + + org.slf4j + slf4j-log4j12 + + + test + + + org.mockito + mockito-all + 1.9.0 + test + + + + io.netty + netty-handler + 4.0.56.Final + + + com.fasterxml.jackson.core + jackson-databind + 2.9.4 + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + io.swagger + swagger-jersey-jaxrs + 1.5.18 + + + com.google.guava + guava + 19.0 + + + org.mindrot + jbcrypt + 0.4 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + true + true + true + + https://docs.oracle.com/javase/7/docs/api/ + https://tomcat.apache.org/tomcat-7.0-doc/jspapi/ + http://docs.oracle.com/javaee/7/api/ + + + + + + + + + docker + + + + io.fabric8 + docker-maven-plugin + 0.19.1 + + true + 1.23 + nexus3.onap.org:10003 + + + + onap/music/music + docker_music + + true + + ${docker.tag} + ${docker.latest.tag} + + ${project.basedir} + + artifact + + + + + + onap/music/cassandra_music + docker_cassandra + + true + + 3.0-${timestamp} + 3.0-latest + + ${project.basedir}/distribution/cassandra + + + + + + + + + + + clean-images + pre-clean + + remove + + + true + music + + + + generate-images + package + + build + + + + push-images + deploy + + push + + + onap/music/music + + + + + + + + + + + ecomp-releases + Release Repository + ${nexusproxy}/${releaseNexusPath} + + + ecomp-snapshots + Snapshot Repository + ${nexusproxy}/${snapshotNexusPath} + + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + diff --git a/jar/src/main/java/LICENSE.txt b/jar/src/main/java/LICENSE.txt new file mode 100644 index 00000000..cc6cdea5 --- /dev/null +++ b/jar/src/main/java/LICENSE.txt @@ -0,0 +1,24 @@ + +The following license applies to all files in this and sub-directories. Licenses +are included in individual source files where appropriate, and if it differs +from this text, it supersedes this. Any file that does not have license text +defaults to being covered by this text; not all files support the addition of +licenses. +# +# ------------------------------------------------------------------------- +# Copyright (c) 2017 AT&T Intellectual Property +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------- +# \ No newline at end of file diff --git a/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java b/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java new file mode 100644 index 00000000..5daeb76c --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java @@ -0,0 +1,451 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicUtil; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.ColumnDefinitions.Definition; +import com.datastax.driver.core.ConsistencyLevel; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.TableMetadata; +import com.datastax.driver.core.exceptions.AlreadyExistsException; +import com.datastax.driver.core.exceptions.InvalidQueryException; +import com.datastax.driver.core.exceptions.NoHostAvailableException; +import com.datastax.driver.core.policies.RoundRobinPolicy; +import com.datastax.driver.core.HostDistance; +import com.datastax.driver.core.PoolingOptions; + + +/** + * @author nelson24 + * + */ +public class MusicDataStore { + + private Session session; + private Cluster cluster; + + + + /** + * @param session + */ + public void setSession(Session session) { + this.session = session; + } + + /** + * @param session + */ + public Session getSession() { + return session; + } + + /** + * @param cluster + */ + public void setCluster(Cluster cluster) { + this.cluster = cluster; + } + + + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicDataStore.class); + + /** + * + */ + public MusicDataStore() { + connectToCassaCluster(); + } + + + /** + * @param cluster + * @param session + */ + public MusicDataStore(Cluster cluster, Session session) { + this.session = session; + this.cluster = cluster; + } + + /** + * + * @param remoteIp + * @throws MusicServiceException + */ + public MusicDataStore(String remoteIp) { + try { + connectToCassaCluster(remoteIp); + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + } + + /** + * + * @return + */ + private ArrayList getAllPossibleLocalIps() { + ArrayList allPossibleIps = new ArrayList(); + try { + Enumeration en = NetworkInterface.getNetworkInterfaces(); + while (en.hasMoreElements()) { + NetworkInterface ni = (NetworkInterface) en.nextElement(); + Enumeration ee = ni.getInetAddresses(); + while (ee.hasMoreElements()) { + InetAddress ia = (InetAddress) ee.nextElement(); + allPossibleIps.add(ia.getHostAddress()); + } + } + } catch (SocketException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.CONNCECTIVITYERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR); + }catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR); + } + return allPossibleIps; + } + + /** + * This method iterates through all available IP addresses and connects to multiple cassandra + * clusters. + */ + private void connectToCassaCluster() { + Iterator it = getAllPossibleLocalIps().iterator(); + String address = "localhost"; + String[] addresses = null; + address = MusicUtil.getMyCassaHost(); + addresses = address.split(","); + + logger.info(EELFLoggerDelegate.applicationLogger, + "Connecting to cassa cluster: Iterating through possible ips:" + + getAllPossibleLocalIps()); + PoolingOptions poolingOptions = new PoolingOptions(); + poolingOptions + .setConnectionsPerHost(HostDistance.LOCAL, 4, 10) + .setConnectionsPerHost(HostDistance.REMOTE, 2, 4); + while (it.hasNext()) { + try { + if(MusicUtil.getCassName() != null && MusicUtil.getCassPwd() != null) { + logger.info(EELFLoggerDelegate.applicationLogger, + "Building with credentials "+MusicUtil.getCassName()+" & "+MusicUtil.getCassPwd()); + cluster = Cluster.builder().withPort(9042) + .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) + .withLoadBalancingPolicy(new RoundRobinPolicy()) + .withPoolingOptions(poolingOptions) + .addContactPoints(addresses).build(); + } + else + cluster = Cluster.builder().withPort(9042) + .withLoadBalancingPolicy(new RoundRobinPolicy()) + .addContactPoints(addresses).build(); + + Metadata metadata = cluster.getMetadata(); + logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster " + + metadata.getClusterName() + " at " + address); + session = cluster.connect(); + + break; + } catch (NoHostAvailableException e) { + address = it.next(); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.HOSTUNAVAILABLE, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR); + } + } + } + + /** + * + */ + public void close() { + session.close(); + } + + /** + * This method connects to cassandra cluster on specific address. + * + * @param address + */ + private void connectToCassaCluster(String address) throws MusicServiceException { + cluster = Cluster.builder().withPort(9042) + .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) + .addContactPoint(address).build(); + Metadata metadata = cluster.getMetadata(); + logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster " + + metadata.getClusterName() + " at " + address); + try { + session = cluster.connect(); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.CASSANDRACONNECTIVITY, ErrorSeverity.ERROR, ErrorTypes.SERVICEUNAVAILABLE); + throw new MusicServiceException( + "Error while connecting to Cassandra cluster.. " + ex.getMessage()); + } + } + + /** + * + * @param keyspace + * @param tableName + * @param columnName + * @return DataType + */ + public DataType returnColumnDataType(String keyspace, String tableName, String columnName) { + KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace); + TableMetadata table = ks.getTable(tableName); + return table.getColumn(columnName).getType(); + + } + + /** + * + * @param keyspace + * @param tableName + * @return TableMetadata + */ + public TableMetadata returnColumnMetadata(String keyspace, String tableName) { + KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace); + return ks.getTable(tableName); + } + + + /** + * Utility function to return the Java specific object type. + * + * @param row + * @param colName + * @param colType + * @return + */ + public Object getColValue(Row row, String colName, DataType colType) { + + switch (colType.getName()) { + case VARCHAR: + return row.getString(colName); + case UUID: + return row.getUUID(colName); + case VARINT: + return row.getVarint(colName); + case BIGINT: + return row.getLong(colName); + case INT: + return row.getInt(colName); + case FLOAT: + return row.getFloat(colName); + case DOUBLE: + return row.getDouble(colName); + case BOOLEAN: + return row.getBool(colName); + case MAP: + return row.getMap(colName, String.class, String.class); + default: + return null; + } + } + + public boolean doesRowSatisfyCondition(Row row, Map condition) throws Exception { + ColumnDefinitions colInfo = row.getColumnDefinitions(); + + for (Map.Entry entry : condition.entrySet()) { + String colName = entry.getKey(); + DataType colType = colInfo.getType(colName); + Object columnValue = getColValue(row, colName, colType); + Object conditionValue = MusicUtil.convertToActualDataType(colType, entry.getValue()); + if (columnValue.equals(conditionValue) == false) + return false; + } + return true; + } + + /** + * Utility function to store ResultSet values in to a MAP for output. + * + * @param results + * @return MAP + */ + public Map> marshalData(ResultSet results) { + Map> resultMap = + new HashMap>(); + int counter = 0; + for (Row row : results) { + ColumnDefinitions colInfo = row.getColumnDefinitions(); + HashMap resultOutput = new HashMap(); + for (Definition definition : colInfo) { + if (!definition.getName().equals("vector_ts")) + resultOutput.put(definition.getName(), + getColValue(row, definition.getName(), definition.getType())); + } + resultMap.put("row " + counter, resultOutput); + counter++; + } + return resultMap; + } + + + // Prepared Statements 1802 additions + /** + * This Method performs DDL and DML operations on Cassandra using specified consistency level + * + * @param queryObject Object containing cassandra prepared query and values. + * @param consistency Specify consistency level for data synchronization across cassandra + * replicas + * @return Boolean Indicates operation success or failure + * @throws MusicServiceException + * @throws MusicQueryException + */ + public boolean executePut(PreparedQueryObject queryObject, String consistency) + throws MusicServiceException, MusicQueryException { + + boolean result = false; + + if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) { + logger.error(EELFLoggerDelegate.errorLogger, queryObject.getQuery(),AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicQueryException("Ill formed queryObject for the request = " + "[" + + queryObject.getQuery() + "]"); + } + logger.info(EELFLoggerDelegate.applicationLogger, + "In preprared Execute Put: the actual insert query:" + + queryObject.getQuery() + "; the values" + + queryObject.getValues()); + PreparedStatement preparedInsert = null; + try { + + preparedInsert = session.prepare(queryObject.getQuery()); + + } catch(InvalidQueryException iqe) { + logger.error(EELFLoggerDelegate.errorLogger, iqe.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); + throw new MusicQueryException(iqe.getMessage()); + }catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); + throw new MusicQueryException(e.getMessage()); + } + + try { + if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { + logger.info(EELFLoggerDelegate.applicationLogger, "Executing critical put query"); + preparedInsert.setConsistencyLevel(ConsistencyLevel.QUORUM); + } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) { + logger.info(EELFLoggerDelegate.applicationLogger, "Executing simple put query"); + preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE); + } + + ResultSet rs = session.execute(preparedInsert.bind(queryObject.getValues().toArray())); + result = rs.wasApplied(); + + } + catch (AlreadyExistsException ae) { + logger.error(EELFLoggerDelegate.errorLogger, ae.getMessage(),AppMessages.SESSIONFAILED+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicServiceException(ae.getMessage()); + } + catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONFAILED+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicQueryException("Executing Session Failure for Request = " + "[" + + queryObject.getQuery() + "]" + " Reason = " + e.getMessage()); + } + + + return result; + } + + /** + * This method performs DDL operations on Cassandra using consistency level ONE. + * + * @param queryObject Object containing cassandra prepared query and values. + * @return ResultSet + * @throws MusicServiceException + * @throws MusicQueryException + */ + public ResultSet executeEventualGet(PreparedQueryObject queryObject) + throws MusicServiceException, MusicQueryException { + + if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) { + logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicQueryException("Ill formed queryObject for the request = " + "[" + + queryObject.getQuery() + "]"); + } + logger.info(EELFLoggerDelegate.applicationLogger, + "Executing Eventual get query:" + queryObject.getQuery()); + + ResultSet results = null; + try { + PreparedStatement preparedEventualGet = session.prepare(queryObject.getQuery()); + preparedEventualGet.setConsistencyLevel(ConsistencyLevel.ONE); + results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray())); + + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicServiceException(ex.getMessage()); + } + return results; + } + + /** + * + * This method performs DDL operation on Cassandra using consistency level QUORUM. + * + * @param queryObject Object containing cassandra prepared query and values. + * @return ResultSet + * @throws MusicServiceException + * @throws MusicQueryException + */ + public ResultSet executeCriticalGet(PreparedQueryObject queryObject) + throws MusicServiceException, MusicQueryException { + if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) { + logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicQueryException("Error processing Prepared Query Object for the request = " + "[" + + queryObject.getQuery() + "]"); + } + logger.info(EELFLoggerDelegate.applicationLogger, + "Executing Critical get query:" + queryObject.getQuery()); + PreparedStatement preparedEventualGet = session.prepare(queryObject.getQuery()); + preparedEventualGet.setConsistencyLevel(ConsistencyLevel.QUORUM); + ResultSet results = null; + try { + results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray())); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + throw new MusicServiceException(ex.getMessage()); + } + return results; + + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java b/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java new file mode 100644 index 00000000..694d9acd --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author srupane + * + */ +public class PreparedQueryObject { + + + private List values; + private StringBuilder query; + + + + /** + * + */ + public PreparedQueryObject() { + + this.values = new ArrayList<>(); + this.query = new StringBuilder(); + } + + /** + * @return + */ + public List getValues() { + return values; + } + + /** + * @param o + */ + public void addValue(Object o) { + this.values.add(o); + } + + /** + * @param s + */ + public void appendQueryString(String s) { + this.query.append(s); + } + + /** + * @return + */ + public String getQuery() { + return this.query.toString(); + } + + + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java new file mode 100644 index 00000000..df6089ee --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.util.ArrayList; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Reponse class for AAF request") +public class AAFResponse { + + private ArrayList ns = null; + + @ApiModelProperty(value = "Namespace value") + public ArrayList getNs() { + return ns; + } + + public void setNs(ArrayList ns) { + this.ns = ns; + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java new file mode 100644 index 00000000..8de0a2cd --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java @@ -0,0 +1,37 @@ +package org.onap.music.datastore.jsonobjects; +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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============================================= + * ==================================================================== + */ + + +public class JSONObject { + + private String data; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java new file mode 100644 index 00000000..a5db4be5 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.util.ArrayList; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Json model for delete") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonDelete { + + private ArrayList columns = null; + private Map consistencyInfo; + private Map conditions; + String ttl, timestamp; + + + @ApiModelProperty(value = "Conditions") + public Map getConditions() { + return conditions; + } + + public void setConditions(Map conditions) { + this.conditions = conditions; + } + + @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic") + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + @ApiModelProperty(value = "Column values") + public ArrayList getColumns() { + return columns; + } + + public void setColumns(ArrayList columns) { + this.columns = columns; + } + + + @ApiModelProperty(value = "Time to live information") + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + @ApiModelProperty(value = "Time stamp") + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java new file mode 100644 index 00000000..a58552c6 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java @@ -0,0 +1,122 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Json model for table vlaues insert") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonInsert implements Serializable { + private String keyspaceName; + private String tableName; + private Map values; + private String ttl; + private String timestamp; + private Map row_specification; + private Map consistencyInfo; + + @ApiModelProperty(value = "keyspace") + public String getKeyspaceName() { + return keyspaceName; + } + + public void setKeyspaceName(String keyspaceName) { + this.keyspaceName = keyspaceName; + } + + @ApiModelProperty(value = "Table name") + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic") + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + @ApiModelProperty(value = "Time to live information") + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + @ApiModelProperty(value = "Time stamp") + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + @ApiModelProperty(value = "values returned") + public Map getValues() { + return values; + } + + public void setValues(Map values) { + this.values = values; + } + + @ApiModelProperty(value = "Information for selecting specific rows for insert") + public Map getRow_specification() { + return row_specification; + } + + public void setRow_specification(Map row_specification) { + this.row_specification = row_specification; + } + + public byte[] serialize() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutput out = null; + try { + out = new ObjectOutputStream(bos); + out.writeObject(this); + } catch (IOException e) { + e.printStackTrace(); + } + return bos.toByteArray(); + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java new file mode 100644 index 00000000..54de02fd --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Json model creating new keyspace") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonKeySpace { + private String keyspaceName; + private Map replicationInfo; + private String durabilityOfWrites; + private Map consistencyInfo; + + @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic") + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + @ApiModelProperty(value = "Replication information") + public Map getReplicationInfo() { + return replicationInfo; + } + + public void setReplicationInfo(Map replicationInfo) { + this.replicationInfo = replicationInfo; + } + + @ApiModelProperty(value = "Durability", allowableValues = "true,false") + public String getDurabilityOfWrites() { + return durabilityOfWrites; + } + + public void setDurabilityOfWrites(String durabilityOfWrites) { + this.durabilityOfWrites = durabilityOfWrites; + } + + @ApiModelProperty(value = "Keyspace name") + public String getKeyspaceName() { + return keyspaceName; + } + + public void setKeyspaceName(String keyspaceName) { + this.keyspaceName = keyspaceName; + } + + + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java new file mode 100644 index 00000000..497e17d1 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "model for leased lock") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonLeasedLock { + long leasePeriod; + String notifyUrl; + + @ApiModelProperty(value = "Lease period") + public long getLeasePeriod() { + return leasePeriod; + } + + public void setLeasePeriod(long leasePeriod) { + this.leasePeriod = leasePeriod; + } + + @ApiModelProperty(value = "URL to be notified") + public String getNotifyUrl() { + return notifyUrl; + } + + public void setNotifyUrl(String notifyUrl) { + this.notifyUrl = notifyUrl; + } +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java new file mode 100755 index 00000000..0bac1e31 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonOnboard", description = "Defines the Json for Onboarding an application.") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonOnboard { + private String appname; + private String userId; + private String password; + private String isAAF; + private String aid; + + @ApiModelProperty(value = "Application Password") + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @ApiModelProperty(value = "Application UUID") + public String getAid() { + return aid; + } + + public void setAid(String aid) { + this.aid = aid; + } + + @ApiModelProperty(value = "Application name") + public String getAppname() { + return appname; + } + + public void setAppname(String appname) { + this.appname = appname; + } + + @ApiModelProperty(value = "User Id") + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + @ApiModelProperty(value = "Is AAF Application", allowableValues = "true, false") + public String getIsAAF() { + return isAAF; + } + + public void setIsAAF(String isAAF) { + this.isAAF = isAAF; + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java new file mode 100644 index 00000000..64bc3887 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java @@ -0,0 +1,59 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonSelect implements Serializable { + private Map consistencyInfo; + + + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + public byte[] serialize() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutput out = null; + try { + out = new ObjectOutputStream(bos); + out.writeObject(this); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return bos.toByteArray(); + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java new file mode 100644 index 00000000..5d508adb --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java @@ -0,0 +1,117 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Defines the Json for Creating a new Table.") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonTable { + private String keyspaceName; + private String tableName; + + private Map fields; + private Map properties; + private String primaryKey; + private String sortingKey; + private String clusteringOrder; + private Map consistencyInfo; + + @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic") + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + @ApiModelProperty(value = "Properties") + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + @ApiModelProperty(value = "Fields") + public Map getFields() { + return fields; + } + + public void setFields(Map fields) { + this.fields = fields; + } + + @ApiModelProperty(value = "KeySpace Name") + public String getKeyspaceName() { + return keyspaceName; + } + + public void setKeyspaceName(String keyspaceName) { + this.keyspaceName = keyspaceName; + } + + @ApiModelProperty(value = "Table Name") + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + @ApiModelProperty(value = "Sorting Key") + public String getSortingKey() { + return sortingKey; + } + + public void setSortingKey(String sortingKey) { + this.sortingKey = sortingKey; + } + + @ApiModelProperty(value = "Clustering Order", notes = "") + public String getClusteringOrder() { + return clusteringOrder; + } + + public void setClusteringOrder(String clusteringOrder) { + this.clusteringOrder = clusteringOrder; + } + + @ApiModelProperty(value = "Primary Key") + public String getPrimaryKey() { + return primaryKey; + } + + public void setPrimaryKey(String primaryKey) { + this.primaryKey = primaryKey; + } + + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java new file mode 100644 index 00000000..3ab5ea0d --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java @@ -0,0 +1,132 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonTable", description = "Json model for table update") +@JsonIgnoreProperties(ignoreUnknown = true) +public class JsonUpdate implements Serializable { + private String keyspaceName; + private String tableName; + private Map values; + private String ttl, timestamp; + private Map consistencyInfo; + private Map conditions; + private Map row_specification; + + @ApiModelProperty(value = "Conditions") + public Map getConditions() { + return conditions; + } + + public void setConditions(Map conditions) { + this.conditions = conditions; + } + + @ApiModelProperty(value = "Information for selecting sepcific rows") + public Map getRow_specification() { + return row_specification; + } + + public void setRow_specification(Map row_specification) { + this.row_specification = row_specification; + } + + + @ApiModelProperty(value = "Keyspace name") + public String getKeyspaceName() { + return keyspaceName; + } + + public void setKeyspaceName(String keyspaceName) { + this.keyspaceName = keyspaceName; + } + + @ApiModelProperty(value = "Table name") + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic") + public Map getConsistencyInfo() { + return consistencyInfo; + } + + public void setConsistencyInfo(Map consistencyInfo) { + this.consistencyInfo = consistencyInfo; + } + + @ApiModelProperty(value = "Time to live value") + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + @ApiModelProperty(value = "Time stamp") + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + @ApiModelProperty(value = "Column values") + public Map getValues() { + return values; + } + + public void setValues(Map values) { + this.values = values; + } + + public byte[] serialize() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutput out = null; + try { + out = new ObjectOutputStream(bos); + out.writeObject(this); + } catch (IOException e) { + e.printStackTrace(); + } + return bos.toByteArray(); + } + +} diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java new file mode 100644 index 00000000..232353c1 --- /dev/null +++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.datastore.jsonobjects; + +import java.util.List; + + +public class NameSpace { + private String name; + private List admin; + + public List getAdmin() { + return admin; + } + + public String getName() { + return name; + } + + public void setAdmin(List admin) { + this.admin = admin; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java b/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java new file mode 100644 index 00000000..1f4abea1 --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java @@ -0,0 +1,175 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.healthcheck; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Iterator; + + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.mindrot.jbcrypt.BCrypt; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JsonOnboard; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.lockingservice.MusicLockingService; +import org.onap.music.main.CachingUtil; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; + + + + +/** + * @author inam + * + */ +public class MusicHealthCheck { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + + private String cassandrHost; + private String zookeeperHost; + + + + + + + + + public String getCassandraStatus() { + logger.info(EELFLoggerDelegate.applicationLogger,"Getting Status for Cassandra"); + if(this.getAdminKeySpace()) { + return "ACTIVE"; + }else { + logger.info(EELFLoggerDelegate.applicationLogger,"Cassandra Service is not responding"); + return "INACTIVE"; + } + } + + + private Boolean getAdminKeySpace() { + + String appName = ""; + + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select * from admin.keyspace_master"); + //pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + try { + ResultSet rs = MusicCore.get(pQuery); + + if(rs != null) { + return Boolean.TRUE; + }else { + return Boolean.FALSE; + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),AppMessages.CASSANDRACONNECTIVITY, ErrorTypes.CONNECTIONERROR, ErrorSeverity.CRITICAL); + } + + return Boolean.FALSE; + + + } + + public String getZookeeperStatus() { + + + String host = MusicUtil.getMyZkHost(); + logger.info(EELFLoggerDelegate.applicationLogger,"Getting Status for Zookeeper Host: "+host); + try { + MusicLockingService lockingService = MusicCore.getLockingServiceHandle(); + //additionally need to call the ZK to create,aquire and delete lock + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),AppMessages.LOCKINGERROR, ErrorTypes.CONNECTIONERROR, ErrorSeverity.CRITICAL); + return "INACTIVE"; + } + + logger.info(EELFLoggerDelegate.applicationLogger,"Zookeeper is Active and Running"); + return "ACTIVE"; + + //return "Zookeeper is not responding"; + + } + + + + + public String getCassandrHost() { + return cassandrHost; + } + + + + + public void setCassandrHost(String cassandrHost) { + this.cassandrHost = cassandrHost; + } + + + + + public String getZookeeperHost() { + return zookeeperHost; + } + + + + + public void setZookeeperHost(String zookeeperHost) { + this.zookeeperHost = zookeeperHost; + } + + + + + + + + + + + + + + + + + + + +} diff --git a/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java b/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java new file mode 100644 index 00000000..0c290b6f --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java @@ -0,0 +1,354 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.logging; + +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_SERVICE_NAME; +import java.net.InetAddress; +import java.text.MessageFormat; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import javax.servlet.http.HttpServletRequest; +import org.slf4j.MDC; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.configuration.SLF4jWrapper; + +public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger { + + public static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); + public static final EELFLogger applicationLogger = + EELFManager.getInstance().getApplicationLogger(); + public static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); + public static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + public static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); + + private String className; + private static ConcurrentMap classMap = new ConcurrentHashMap<>(); + + public EELFLoggerDelegate(final String className) { + super(className); + this.className = className; + } + + /** + * Convenience method that gets a logger for the specified class. + * + * @see #getLogger(String) + * + * @param clazz + * @return Instance of EELFLoggerDelegate + */ + public static EELFLoggerDelegate getLogger(Class clazz) { + return getLogger(clazz.getName()); + } + + /** + * Gets a logger for the specified class name. If the logger does not already exist in the map, + * this creates a new logger. + * + * @param className If null or empty, uses EELFLoggerDelegate as the class name. + * @return Instance of EELFLoggerDelegate + */ + public static EELFLoggerDelegate getLogger(final String className) { + String classNameNeverNull = className == null || "".equals(className) + ? EELFLoggerDelegate.class.getName() + : className; + EELFLoggerDelegate delegate = classMap.get(classNameNeverNull); + if (delegate == null) { + delegate = new EELFLoggerDelegate(className); + classMap.put(className, delegate); + } + return delegate; + } + + /** + * Logs a message at the lowest level: trace. + * + * @param logger + * @param msg + */ + public void trace(EELFLogger logger, String msg) { + if (logger.isTraceEnabled()) { + logger.trace(msg); + } + } + + /** + * Logs a message with parameters at the lowest level: trace. + * + * @param logger + * @param msg + * @param arguments + */ + public void trace(EELFLogger logger, String msg, Object... arguments) { + if (logger.isTraceEnabled()) { + logger.trace(msg, arguments); + } + } + + /** + * Logs a message and throwable at the lowest level: trace. + * + * @param logger + * @param msg + * @param th + */ + public void trace(EELFLogger logger, String msg, Throwable th) { + if (logger.isTraceEnabled()) { + logger.trace(msg, th); + } + } + + /** + * Logs a message at the second-lowest level: debug. + * + * @param logger + * @param msg + */ + public void debug(EELFLogger logger, String msg) { + if (logger.isDebugEnabled()) { + logger.debug(msg); + } + } + + /** + * Logs a message with parameters at the second-lowest level: debug. + * + * @param logger + * @param msg + * @param arguments + */ + public void debug(EELFLogger logger, String msg, Object... arguments) { + if (logger.isDebugEnabled()) { + logger.debug(msg, arguments); + } + } + + /** + * Logs a message and throwable at the second-lowest level: debug. + * + * @param logger + * @param msg + * @param th + */ + public void debug(EELFLogger logger, String msg, Throwable th) { + if (logger.isDebugEnabled()) { + logger.debug(msg, th); + } + } + + /** + * Logs a message at info level. + * + * @param logger + * @param msg + */ + public void info(EELFLogger logger, String msg) { + logger.info(className + " - "+msg); + } + + /** + * Logs a message with parameters at info level. + * + * @param logger + * @param msg + * @param arguments + */ + public void info(EELFLogger logger, String msg, Object... arguments) { + logger.info(msg, arguments); + } + + /** + * Logs a message and throwable at info level. + * + * @param logger + * @param msg + * @param th + */ + public void info(EELFLogger logger, String msg, Throwable th) { + logger.info(msg, th); + } + + /** + * Logs a message at warn level. + * + * @param logger + * @param msg + */ + public void warn(EELFLogger logger, String msg) { + logger.warn(msg); + } + + /** + * Logs a message with parameters at warn level. + * + * @param logger + * @param msg + * @param arguments + */ + public void warn(EELFLogger logger, String msg, Object... arguments) { + logger.warn(msg, arguments); + } + + /** + * Logs a message and throwable at warn level. + * + * @param logger + * @param msg + * @param th + */ + public void warn(EELFLogger logger, String msg, Throwable th) { + logger.warn(msg, th); + } + + /** + * Logs a message at error level. + * + * @param logger + * @param msg + */ + public void error(EELFLogger logger, String msg) { + logger.error(className+ " - " + msg); + } + + /** + * Logs a message with parameters at error level. + * + * @param logger + * @param msg + * @param arguments + */ + public void error(EELFLogger logger, String msg, Object... arguments) { + logger.warn(msg, arguments); + } + + /** + * Logs a message and throwable at error level. + * + * @param logger + * @param msg + * @param th + */ + public void error(EELFLogger logger, String msg, Throwable th) { + logger.warn(msg, th); + } + + /** + * Logs a message with the associated alarm severity at error level. + * + * @param logger + * @param msg + * @param severtiy + */ + public void error(EELFLogger logger, String msg, Object /* AlarmSeverityEnum */ severtiy) { + logger.error(msg); + } + + /** + * Initializes the logger context. + */ + public void init() { + setGlobalLoggingContext(); + final String msg = + "############################ Logging is started. ############################"; + // These loggers emit the current date-time without being told. + info(applicationLogger, msg); + error(errorLogger, msg); + debug(debugLogger, msg); + info(auditLogger, msg); + info(metricsLogger, msg); + } + + /** + * Builds a message using a template string and the arguments. + * + * @param message + * @param args + * @return + */ + private String formatMessage(String message, Object... args) { + StringBuilder sbFormattedMessage = new StringBuilder(); + if (args != null && args.length > 0 && message != null && message != "") { + MessageFormat mf = new MessageFormat(message); + sbFormattedMessage.append(mf.format(args)); + } else { + sbFormattedMessage.append(message); + } + + return sbFormattedMessage.toString(); + } + + /** + * Loads all the default logging fields into the MDC context. + */ + private void setGlobalLoggingContext() { + 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("setGlobalLoggingContext failed", e); + } + } + + public static void mdcPut(String key, String value) { + MDC.put(key, value); + } + + public static String mdcGet(String key) { + return MDC.get(key); + } + + public static void mdcRemove(String key) { + MDC.remove(key); + } + + /** + * Loads the RequestId/TransactionId into the MDC which it should be receiving with an each + * incoming REST API request. Also, configures few other request based logging fields into the + * MDC context. + * + * @param req + * @param appName + */ + public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, + String appName) { + // Load the default fields + setGlobalLoggingContext(); + + // Load the request based fields + if (req != null) { + // Rest Path + MDC.put(MDC_SERVICE_NAME, req.getServletPath()); + + // Client IPAddress i.e. IPAddress of the remote host who is making + // this request. + String clientIPAddress = req.getHeader("X-FORWARDED-FOR"); + if (clientIPAddress == null) { + clientIPAddress = req.getRemoteAddr(); + } + } + } +} diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java b/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java new file mode 100644 index 00000000..2c7952b2 --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java @@ -0,0 +1,183 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.logging.format; + +/** + * @author inam + * + */ +public enum AppMessages { + + + + /* + * 100-199 Security/Permission Related - Authentication problems + * [ERR100E] Missing Information + * [ERR101E] Authentication error occured + * + * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout + * [ERR200E] Connectivity + * [ERR201E] Host not available + * [ERR202E] Error while connecting to Cassandra cluster + * [ERR203E] IO Error has occured + * [ERR204E] Execution Interrupted + * [ERR205E] Session Expired + * [ERR206E] Cache not authenticated + * + * + * 300-399 Data Access/Integrity Related + * [ERR300E] Incorrect data + * + * 400-499 - Cassandra Query Related + * [ERR400E] Error while processing prepared query object + * [ERR401E] Executing Session Failure for Request + * [ERR402E] Ill formed queryObject for the request + * [ERR403E] Error processing Prepared Query Object + * + * 500-599 - Zookeepr/Locking Related + * [ERR500E] Invalid lock + * [ERR501E] Locking Error has occured + * [ERR502E] Zookeeper error has occured + * [ERR503E] Failed to aquire lock store handle + * [ERR504E] Failed to create Lock Reference + * [ERR505E] Lock does not exist + * [ERR506E] Failed to aquire lock + * [ERR507E] Lock not aquired + * [ERR508E] Lock state not set + * [ERR509E] Lock not destroyed + * [ERR510E] Lock not released + * [ERR511E] Lock not deleted + * [ERR512E] Failed to get ZK Lock Handle + * + * + * 600 - 699 - Music Service Errors + * [ERR600E] Error initializing the cache + * + * 700-799 Schema Interface Type/Validation - received Pay-load checksum is + * invalid - received JSON is not valid + * + * 800-899 Business/Flow Processing Related - check out to service is not + * allowed - Roll-back is done - failed to generate heat file + * + * + * 900-999 Unknown Errors - Unexpected exception + * [ERR900E] Unexpected error occured + * [ERR901E] Number format exception + * + * + * 1000-1099 Reserved - do not use + * + */ + + + + + MISSINGINFO("[ERR100E]", "Missing Information ","Details: NA", "Please check application credentials and/or headers"), + AUTHENTICATIONERROR("[ERR101E]", "Authentication error occured ","Details: NA", "Please verify application credentials"), + CONNCECTIVITYERROR("[ERR200E]"," Connectivity error","Details: NA ","Please check connectivity to external resources"), + HOSTUNAVAILABLE("[ERR201E]","Host not available","Details: NA","Please verify the host details"), + CASSANDRACONNECTIVITY("[ERR202E]","Error while connecting to Cassandra cluster",""," Please check cassandra cluster details"), + IOERROR("[ERR203E]","IO Error has occured","","Please check IO"), + EXECUTIONINTERRUPTED("[ERR204E]"," Execution Interrupted","",""), + SESSIONEXPIRED("[ERR205E]"," Session Expired","","Session has expired."), + CACHEAUTHENTICATION("[ERR206E]","Cache not authenticated",""," Cache not authenticated"), + + INCORRECTDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"), + MULTIPLERECORDS("[ERR301E]"," Multiple records found",""," Please verify the request payload and try again"), + ALREADYEXIST("[ERR302E]"," Record already exist",""," Please verify the request payload and try again"), + MISSINGDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"), + + QUERYERROR("[ERR400E]","Error while processing prepared query object",""," Please verify the query"), + SESSIONFAILED("[ERR401E]","Executing Session Failure for Request","","Please verify the session and request"), + + INVALIDLOCK("[ERR500E]"," Invalid lock or acquire failed",""," Lock is not valid to aquire"), + LOCKINGERROR("[ERR501E]"," Locking Error has occured",""," Locking Error has occured"), + KEEPERERROR("[ERR502E]"," Zookeeper error has occured","","Please check zookeeper details"), + LOCKHANDLE("[ERR503E]","Failed to aquire lock store handle",""," Failed to aquire lock store handle"), + CREATELOCK("[ERR504E]","Failed to aquire lock store handle ","","Failed to aquire lock store handle "), + LOCKSTATE("[ERR508E]"," Lock state not set",""," Lock state not set"), + DESTROYLOCK("[ERR509E]"," Lock not destroyed",""," Lock not destroyed"), + RELEASELOCK("[ERR510E]"," Lock not released",""," Lock not released"), + DELTELOCK("[ERR511E]",""," Lock not deleted "," Lock not deleted "), + CACHEERROR("[ERR600E]"," Error initializing the cache",""," Error initializing the cache"), + + UNKNOWNERROR("[ERR900E]"," Unexpected error occured",""," Please check logs for details"); + + + + ErrorTypes eType; + ErrorSeverity alarmSeverity; + ErrorSeverity errorSeverity; + String errorCode; + String errorDescription; + String details; + String resolution; + + + AppMessages(String errorCode, String errorDescription, String details,String resolution) { + + this.errorCode = errorCode; + this.errorDescription = errorDescription; + this.details = details; + this.resolution = resolution; + } + + + + + AppMessages(ErrorTypes eType, ErrorSeverity alarmSeverity, + ErrorSeverity errorSeverity, String errorCode, String errorDescription, String details, + String resolution) { + + this.eType = eType; + this.alarmSeverity = alarmSeverity; + this.errorSeverity = errorSeverity; + this.errorCode = errorCode; + this.errorDescription = errorDescription; + this.details = details; + this.resolution = resolution; + } + + public String getDetails() { + return this.details; + } + + public String getResolution() { + return this.resolution; + } + + public String getErrorCode() { + return this.errorCode; + } + + public String getErrorDescription() { + return this.errorDescription; + } + + + + + + + +} diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java new file mode 100644 index 00000000..b18c1771 --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java @@ -0,0 +1,106 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.logging.format; + + + +/** + * @author inam + * + */ +public enum ErrorCodes { + + + /* + * 100-199 Security/Permission Related - Authentication problems + * [ERR100E] Missing Information + * [ERR101E] Authentication error occured + * + * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout + * [ERR200E] Connectivity + * [ERR201E] Host not available + * [ERR202E] Error while connecting to Cassandra cluster + * [ERR203E] IO Error has occured + * [ERR204E] Execution Interrupted + * [ERR205E] Session Expired + * [ERR206E] Cache not authenticated + * + * + * 300-399 Data Access/Integrity Related + * + * 400-499 - Cassandra Query Related + * [ERR400E] Error while processing prepared query object + * [ERR401E] Executing Session Failure for Request + * [ERR402E] Ill formed queryObject for the request + * [ERR403E] Error processing Prepared Query Object + * + * 500-599 - Zookeepr/Locking Related + * [ERR500E] Invalid lock + * [ERR501E] Locking Error has occured + * [ERR502E] Zookeeper error has occured + * [ERR503E] Failed to aquire lock store handle + * [ERR504E] Failed to create Lock Reference + * [ERR505E] Lock does not exist + * [ERR506E] Failed to aquire lock + * [ERR507E] Lock not aquired + * [ERR508E] Lock state not set + * [ERR509E] Lock not destroyed + * [ERR510E] Lock not released + * [ERR511E] Lock not deleted + * [ERR512E] Failed to get ZK Lock Handle + * + * + * 600 - 699 - Music Service Errors + * [ERR600E] Error initializing the cache + * + * 700-799 Schema Interface Type/Validation - received Pay-load checksum is + * invalid - received JSON is not valid + * + * 800-899 Business/Flow Processing Related - check out to service is not + * allowed - Roll-back is done - failed to generate heat file + * + * + * 900-999 Unknown Errors - Unexpected exception + * [ERR900E] Unexpected error occured + * [ERR901E] Number format exception + * + * + * 1000-1099 Reserved - do not use + * + */ + + /*SUCCESS("Success"), FAILURE("Failure"); + + private String result; + + ResultType(String result) { + this.result = result; + } + + public String getResult() { + return result; + } +*/ + + + +} diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java new file mode 100644 index 00000000..cda5dd31 --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.logging.format; + +/** + * @author inam + * + */ +public enum ErrorSeverity { + INFO, + WARN, + ERROR, + FATAL, + CRITICAL, + MAJOR, + MINOR, + NONE, +} diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java new file mode 100644 index 00000000..2536f4a4 --- /dev/null +++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.eelf.logging.format; + +import com.att.eelf.i18n.EELFResolvableErrorEnum; + +/** + * @author inam + * + */ +public enum ErrorTypes implements EELFResolvableErrorEnum { + + + CONNECTIONERROR, + SESSIONEXPIRED, + AUTHENTICATIONERROR, + SERVICEUNAVAILABLE, + QUERYERROR, + DATAERROR, + GENERALSERVICEERROR, + MUSICSERVICEERROR, + LOCKINGERROR, + UNKNOWN, + +} diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java b/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java new file mode 100644 index 00000000..14a23d1f --- /dev/null +++ b/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.exceptions; + +import java.io.EOFException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import org.codehaus.jackson.map.exc.UnrecognizedPropertyException; +import org.onap.music.main.ResultType; +import org.onap.music.response.jsonobjects.JsonResponse; + +@Provider +public class MusicExceptionMapper implements ExceptionMapper { + @Override + public Response toResponse(Exception exception) { + if(exception instanceof UnrecognizedPropertyException) { + return Response.status(Response.Status.BAD_REQUEST). + entity(new JsonResponse(ResultType.FAILURE).setError("Unknown field :"+((UnrecognizedPropertyException) exception).getUnrecognizedPropertyName()).toMap()). + build(); + } + else if(exception instanceof EOFException) { + return Response.status(Response.Status.BAD_REQUEST). + entity(new JsonResponse(ResultType.FAILURE).setError("Request body cannot be empty").toMap()). + build(); + } + else { + return Response.status(Response.Status.BAD_REQUEST). + entity(new JsonResponse(ResultType.FAILURE).setError(exception.getMessage()).toMap()). + build(); + } + } +} diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java b/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java new file mode 100644 index 00000000..1a9e45d9 --- /dev/null +++ b/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.exceptions; + +/** + * @author inam + * + */ +public class MusicLockingException extends Exception { + + /** + * + */ + public MusicLockingException() { + + } + + /** + * @param message + */ + public MusicLockingException(String message) { + super(message); + + } + + /** + * @param cause + */ + public MusicLockingException(Throwable cause) { + super(cause); + + } + + /** + * @param message + * @param cause + */ + public MusicLockingException(String message, Throwable cause) { + super(message, cause); + + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public MusicLockingException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + + } + +} diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java b/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java new file mode 100644 index 00000000..bade21a4 --- /dev/null +++ b/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.exceptions; + +/** + * @author inam + * + */ +public class MusicPolicyVoilationException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public MusicPolicyVoilationException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public MusicPolicyVoilationException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public MusicPolicyVoilationException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public MusicPolicyVoilationException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public MusicPolicyVoilationException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java b/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java new file mode 100644 index 00000000..24b8568b --- /dev/null +++ b/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.exceptions; + + + +/** + * @author inam + * + */ +public class MusicQueryException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int errorCode; + + + /** + * + */ + public MusicQueryException() { + super(); + } + + /** + * @param message + */ + public MusicQueryException(String message) { + super(message); + } + + + + /** + * @param message + */ + public MusicQueryException(String message, int errorCode) { + super(message); + this.errorCode = errorCode; + } + + /** + * @param cause + */ + public MusicQueryException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public MusicQueryException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public MusicQueryException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java b/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java new file mode 100644 index 00000000..a3b1fc56 --- /dev/null +++ b/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java @@ -0,0 +1,84 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.exceptions; + +/** + * @author inam + * + */ +public class MusicServiceException extends Exception { + + + private int errorCode; + private String errorMessage; + + public int getErrorCode() { + return errorCode; + } + + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + + public String getErrorMessage() { + return errorMessage; + } + + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + + public MusicServiceException() { + super(); + } + + + public MusicServiceException(String message) { + super(message); + + } + + + public MusicServiceException(Throwable cause) { + super(cause); + + } + + + public MusicServiceException(String message, Throwable cause) { + super(message, cause); + + } + + + public MusicServiceException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + + } + +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/LockListener.java b/jar/src/main/java/org/onap/music/lockingservice/LockListener.java new file mode 100644 index 00000000..33188e60 --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/LockListener.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.lockingservice; + +/** + * This class has two methods which are call back methods when a lock is acquired and when the lock + * is released. + * + */ +public interface LockListener { + /** + * call back called when the lock is acquired + */ + public void lockAcquired(); + + /** + * call back called when the lock is released. + */ + public void lockReleased(); +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java b/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java new file mode 100644 index 00000000..6c31410f --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java @@ -0,0 +1,137 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.lockingservice; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; + +// the state variable that will be stored in zookeeper, capturing the transitions of +public class MusicLockState implements Serializable { + public enum LockStatus { + UNLOCKED, BEING_LOCKED, LOCKED + };// captures the state of the lock + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicLockState.class); + LockStatus lockStatus; + boolean needToSyncQuorum = false; + String lockHolder; + long leasePeriod = Long.MAX_VALUE, leaseStartTime = -1; + + private String errorMessage = null; + + public MusicLockState(String errorMessage) { + this.errorMessage = errorMessage; + } + + public MusicLockState(LockStatus lockStatus, String lockHolder) { + this.lockStatus = lockStatus; + this.lockHolder = lockHolder; + } + + public MusicLockState(LockStatus lockStatus, String lockHolder, boolean needToSyncQuorum) { + this.lockStatus = lockStatus; + this.lockHolder = lockHolder; + this.needToSyncQuorum = needToSyncQuorum; + } + + + public long getLeasePeriod() { + return leasePeriod; + } + + public boolean isNeedToSyncQuorum() { + return needToSyncQuorum; + } + + + + public void setLeasePeriod(long leasePeriod) { + this.leasePeriod = leasePeriod; + } + + + public long getLeaseStartTime() { + return leaseStartTime; + } + + + public void setLeaseStartTime(long leaseStartTime) { + this.leaseStartTime = leaseStartTime; + } + + + + public LockStatus getLockStatus() { + return lockStatus; + } + + public void setLockStatus(LockStatus lockStatus) { + this.lockStatus = lockStatus; + } + + public String getLockHolder() { + return lockHolder; + } + + public void setLockHolder(String lockHolder) { + this.lockHolder = lockHolder; + } + + public String getErrorMessage() { + return errorMessage; + } + + public byte[] serialize() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutput out = null; + try { + out = new ObjectOutputStream(bos); + out.writeObject(this); + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR); + } + return bos.toByteArray(); + } + + public static MusicLockState deSerialize(byte[] data) { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + Object o = null; + ObjectInput in = null; + try { + in = new ObjectInputStream(bis); + o = in.readObject(); + } catch (ClassNotFoundException | IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN); + } + return (MusicLockState) o; + } +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java b/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java new file mode 100644 index 00000000..ae026903 --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java @@ -0,0 +1,166 @@ +/* + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT 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.music.lockingservice; + + +import java.io.IOException; +import java.util.StringTokenizer; +import java.util.concurrent.CountDownLatch; + +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher; +import org.apache.zookeeper.Watcher.Event.KeeperState; +import org.apache.zookeeper.ZooKeeper; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicUtil; + + +public class MusicLockingService implements Watcher { + + + private static final int SESSION_TIMEOUT = 180000; + ZkStatelessLockService zkLockHandle = null; + private CountDownLatch connectedSignal = new CountDownLatch(1); + private static EELFLoggerDelegate logger = + EELFLoggerDelegate.getLogger(MusicLockingService.class); + + public MusicLockingService() throws MusicServiceException { + try { + ZooKeeper zk = new ZooKeeper(MusicUtil.getMyZkHost(), SESSION_TIMEOUT, this); + connectedSignal.await(); + zkLockHandle = new ZkStatelessLockService(zk); + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR); + throw new MusicServiceException("IO Error has occured" + e.getMessage()); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + throw new MusicServiceException("Exception Occured " + e.getMessage()); + } + } + + public ZkStatelessLockService getzkLockHandle() { + return zkLockHandle; + } + + public MusicLockingService(String lockServer) { + try { + ZooKeeper zk = new ZooKeeper(lockServer, SESSION_TIMEOUT, this); + connectedSignal.await(); + zkLockHandle = new ZkStatelessLockService(zk); + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR); + }catch( InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + } + + public void createLockaIfItDoesNotExist(String lockName) { + if (!zkLockHandle.checkIfLockExists(lockName)) { + String lockHolder = null; + MusicLockState ml = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder); + byte[] data = ml.serialize(); + zkLockHandle.createLock(lockName, data); + } + } + + public void setLockState(String lockName, MusicLockState mls) { + byte[] data = mls.serialize(); + zkLockHandle.setNodeData(lockName, data); + } + + public MusicLockState getLockState(String lockName) throws MusicLockingException { + + byte[] data = null; + try{ + data = zkLockHandle.getNodeData(lockName); + }catch (Exception ex){ + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + if(data !=null) + return MusicLockState.deSerialize(data); + else { + logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.INVALIDLOCK, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException("Invalid lock or acquire failed"); + } + } + + public String createLockId(String lockName) { + String lockIdWithSlash = zkLockHandle.createLockId(lockName); + return lockIdWithSlash.replace('/', '$'); + } + + public boolean isMyTurn(String lockIdWithDollar) { + String lockId = lockIdWithDollar.replace('$', '/'); + StringTokenizer st = new StringTokenizer(lockId); + String lockName = "/" + st.nextToken("/"); + try { + return zkLockHandle.lock(lockName, lockId); + } catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.LOCKINGERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch( InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + return false; + } + + public void unlockAndDeleteId(String lockIdWithDollar) throws KeeperException.NoNodeException { + String lockId = lockIdWithDollar.replace('$', '/'); + zkLockHandle.unlock(lockId); + } + + public void deleteLock(String lockName) throws MusicLockingException { + if(lockIdExists(lockName)) + zkLockHandle.deleteLock(lockName); + else{ + throw new MusicLockingException("Lock does not exist.Please check the lock: " + lockName + " and try again"); + } + } + + public String whoseTurnIsIt(String lockName) { + String lockHolder = zkLockHandle.currentLockHolder(lockName); + return lockHolder.replace('/', '$'); + + } + + public void process(WatchedEvent event) { // Watcher interface + if (event.getState() == KeeperState.SyncConnected) { + connectedSignal.countDown(); + } + } + + + public void close() { + zkLockHandle.close(); + } + + public boolean lockIdExists(String lockIdWithDollar) { + String lockId = lockIdWithDollar.replace('$', '/'); + return zkLockHandle.checkIfLockExists(lockId); + } + +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java b/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java new file mode 100644 index 00000000..4082b3b8 --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java @@ -0,0 +1,208 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.lockingservice; + +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.ZooDefs; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.ACL; +import org.apache.zookeeper.data.Stat; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.lockingservice.ZooKeeperOperation; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * A base class for protocol implementations which provides a number of higher level helper methods + * for working with ZooKeeper along with retrying synchronous operations if the connection to + * ZooKeeper closes such as {@link #retryOperation(ZooKeeperOperation)} + * + */ +class ProtocolSupport { + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ProtocolSupport.class); + + protected ZooKeeper zookeeper; + private AtomicBoolean closed = new AtomicBoolean(false); + private long retryDelay = 500L; + private int retryCount = 10; + private List acl = ZooDefs.Ids.OPEN_ACL_UNSAFE; + + /** + * Closes this strategy and releases any ZooKeeper resources; but keeps the ZooKeeper instance + * open + */ + public void close() { + if (closed.compareAndSet(false, true)) { + doClose(); + } + } + + /** + * return zookeeper client instance + * + * @return zookeeper client instance + */ + public ZooKeeper getZookeeper() { + return zookeeper; + } + + /** + * return the acl its using + * + * @return the acl. + */ + public List getAcl() { + return acl; + } + + /** + * set the acl + * + * @param acl the acl to set to + */ + public void setAcl(List acl) { + this.acl = acl; + } + + /** + * get the retry delay in milliseconds + * + * @return the retry delay + */ + public long getRetryDelay() { + return retryDelay; + } + + /** + * Sets the time waited between retry delays + * + * @param retryDelay the retry delay + */ + public void setRetryDelay(long retryDelay) { + this.retryDelay = retryDelay; + } + + /** + * Allow derived classes to perform some custom closing operations to release resources + */ + protected void doClose() { + throw new UnsupportedOperationException(); + } + + + /** + * Perform the given operation, retrying if the connection fails + * + * @return object. it needs to be cast to the callee's expected return type. + * @param operation FILL IN + * @throws KeeperException FILL IN + * @throws InterruptedException FILL IN + */ + protected Object retryOperation(ZooKeeperOperation operation) + throws KeeperException, InterruptedException { + KeeperException exception = null; + for (int i = 0; i < retryCount; i++) { + try { + return operation.execute(); + } catch (KeeperException.SessionExpiredException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONEXPIRED+" for: " + zookeeper + " so reconnecting due to: " + e, ErrorSeverity.ERROR, ErrorTypes.SESSIONEXPIRED); + throw e; + } catch (KeeperException.ConnectionLossException e) { + if (exception == null) { + exception = e; + } + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.CONNCECTIVITYERROR, ErrorSeverity.ERROR, ErrorTypes.SESSIONEXPIRED); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Attempt " + i + " failed with connection loss so attempting to reconnect: " + e); + + retryDelay(i); + } + } + throw exception; + } + + /** + * Ensures that the given path exists with no data, the current ACL and no flags + * + * @param path the lock path + */ + protected void ensurePathExists(String path) { + ensureExists(path, null, acl, CreateMode.PERSISTENT); + } + + /** + * Ensures that the given path exists with the given data, ACL and flags + * + * @param path the lock path + * @param data the data + * @param acl list of ACLs applying to the path + * @param flags create mode flags + */ + protected void ensureExists(final String path, final byte[] data, final List acl, + final CreateMode flags) { + try { + retryOperation(new ZooKeeperOperation() { + public boolean execute() throws KeeperException, InterruptedException { + Stat stat = zookeeper.exists(path, false); + if (stat != null) { + return true; + } + zookeeper.create(path, data, acl, flags); + return true; + } + }); + } catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + } + + /** + * Returns true if this protocol has been closed + * + * @return true if this protocol is closed + */ + protected boolean isClosed() { + return closed.get(); + } + + /** + * Performs a retry delay if this is not the first attempt + * + * @param attemptCount the number of the attempts performed so far + */ + protected void retryDelay(int attemptCount) { + if (attemptCount > 0) { + try { + Thread.sleep(attemptCount * retryDelay); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Thread failed to sleep: " + e); + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java b/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java new file mode 100644 index 00000000..0c190f14 --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java @@ -0,0 +1,118 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.lockingservice; + +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; + +/** + * Represents an ephemeral znode name which has an ordered sequence number and can be sorted in + * order + * + */ +class ZNodeName implements Comparable { + private final String name; + private String prefix; + private int sequence = -1; + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ZNodeName.class); + + public ZNodeName(String name) { + if (name == null) { + throw new NullPointerException("id cannot be null"); + } + this.name = name; + this.prefix = name; + int idx = name.lastIndexOf('-'); + if (idx >= 0) { + this.prefix = name.substring(0, idx); + try { + this.sequence = Integer.parseInt(name.substring(idx + 1)); + // If an exception occurred we misdetected a sequence suffix, + // so return -1. + } catch (NumberFormatException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Number format exception "+idx, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR); + } catch (ArrayIndexOutOfBoundsException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Array out of bounds for "+idx, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR); + } + } + } + + @Override + public String toString() { + return name.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ZNodeName sequence = (ZNodeName) o; + + if (!name.equals(sequence.name)) + return false; + + return true; + } + + @Override + public int hashCode() { + return name.hashCode() + 37; + } + + public int compareTo(ZNodeName that) { + int answer = this.prefix.compareTo(that.prefix); + if (answer == 0) { + int s1 = this.sequence; + int s2 = that.sequence; + if (s1 == -1 && s2 == -1) { + return this.name.compareTo(that.name); + } + answer = s1 == -1 ? 1 : s2 == -1 ? -1 : s1 - s2; + } + return answer; + } + + /** + * Returns the name of the znode + */ + public String getName() { + return name; + } + + /** + * Returns the sequence number + */ + public int getZNodeName() { + return sequence; + } + + /** + * Returns the text prefix before the sequence number + */ + public String getPrefix() { + return prefix; + } +} diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java b/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java new file mode 100644 index 00000000..e99df255 --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java @@ -0,0 +1,339 @@ +/* + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT 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.music.lockingservice; + + +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.KeeperException.NoNodeException; +import org.apache.zookeeper.ZooDefs; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.ACL; +import org.apache.zookeeper.data.Stat; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; + +/** + * A protocol to implement an exclusive write lock or to elect a leader. + *

+ * You invoke {@link #lock()} to start the process of grabbing the lock; you may get the lock then + * or it may be some time later. + *

+ * You can register a listener so that you are invoked when you get the lock; otherwise you can ask + * if you have the lock by calling {@link #isOwner()} + * + */ +public class ZkStatelessLockService extends ProtocolSupport { + public ZkStatelessLockService(ZooKeeper zk) { + zookeeper = zk; + } + + private static EELFLoggerDelegate logger = + EELFLoggerDelegate.getLogger(ZkStatelessLockService.class); + + protected void createLock(final String path, final byte[] data) { + final List acl = ZooDefs.Ids.OPEN_ACL_UNSAFE; + try { + retryOperation(new ZooKeeperOperation() { + public boolean execute() throws KeeperException, InterruptedException { + zookeeper.create(path, data, acl, CreateMode.PERSISTENT); + return true; + } + }); + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + } + + public void close() { + try { + zookeeper.close(); + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + } + + public void setNodeData(final String lockName, final byte[] data) { + try { + retryOperation(new ZooKeeperOperation() { + public boolean execute() throws KeeperException, InterruptedException { + zookeeper.getSessionId(); + zookeeper.setData("/" + lockName, data, -1); + return true; + } + }); + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + + } + + public byte[] getNodeData(final String lockName) { + try { + if (zookeeper.exists("/" + lockName, null) != null) + return zookeeper.getData("/" + lockName, false, null); + else + return null; + + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + return null; + } + + public boolean checkIfLockExists(String lockName) { + boolean result = false; + try { + Stat stat = zookeeper.exists(lockName, false); + if (stat != null) { + result = true; + } + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + return result; + } + + public void createNode(String nodeName) { + ensurePathExists(nodeName); + } + + public String createLockId(String dir) { + ensurePathExists(dir); + LockZooKeeperOperation zop = new LockZooKeeperOperation(dir); + try { + retryOperation(zop); + }catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + }catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + } + return zop.getId(); + } + + /** + * Attempts to acquire the exclusive write lock returning whether or not it was acquired. Note + * that the exclusive lock may be acquired some time later after this method has been invoked + * due to the current lock owner going away. + */ + public synchronized boolean lock(String dir, String lockId) + throws KeeperException, InterruptedException { + if (isClosed()) { + return false; + } + LockZooKeeperOperation zop = new LockZooKeeperOperation(dir, lockId); + return (Boolean) retryOperation(zop); + } + + /** + * Removes the lock or associated znode if you no longer require the lock. this also removes + * your request in the queue for locking in case you do not already hold the lock. + * + * @throws RuntimeException throws a runtime exception if it cannot connect to zookeeper. + * @throws NoNodeException + */ + public synchronized void unlock(String lockId) throws RuntimeException, KeeperException.NoNodeException { + final String id = lockId; + if (!isClosed() && id != null) { + try { + ZooKeeperOperation zopdel = new ZooKeeperOperation() { + public boolean execute() throws KeeperException, InterruptedException { + zookeeper.delete(id, -1); + return Boolean.TRUE; + } + }; + zopdel.execute(); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + // set that we have been interrupted. + Thread.currentThread().interrupt(); + } catch (KeeperException.NoNodeException e) { + // do nothing + throw new KeeperException.NoNodeException("Lock doesn't exists. Release lock operation failed."); + } catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e); + } + } + } + + public synchronized String currentLockHolder(String mainLock) { + final String id = mainLock; + if (!isClosed() && id != null) { + List names; + try { + names = zookeeper.getChildren(id, false); + if (names.isEmpty()) + return ""; + SortedSet sortedNames = new TreeSet(); + for (String name : names) { + sortedNames.add(new ZNodeName(id + "/" + name)); + } + return sortedNames.first().getName(); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + // set that we have been interrupted. + Thread.currentThread().interrupt(); + } catch (KeeperException.NoNodeException e) { + // do nothing + } catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e); + } + } + return "No lock holder!"; + } + + public synchronized void deleteLock(String mainLock) { + final String id = mainLock; + if (!isClosed() && id != null) { + try { + ZooKeeperOperation zopdel = new ZooKeeperOperation() { + public boolean execute() throws KeeperException, InterruptedException { + List names = zookeeper.getChildren(id, false); + for (String name : names) { + zookeeper.delete(id + "/" + name, -1); + } + zookeeper.delete(id, -1); + return Boolean.TRUE; + } + }; + zopdel.execute(); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + // set that we have been interrupted. + Thread.currentThread().interrupt(); + } catch (KeeperException.NoNodeException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + // do nothing + } catch (KeeperException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); + throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e); + } + } + + } + + /** + * a zoookeeper operation that is mainly responsible for all the magic required for locking. + */ + private class LockZooKeeperOperation implements ZooKeeperOperation { + + /** + * find if we have been created earlier if not create our node + * + * @param prefix the prefix node + * @param zookeeper the zookeeper client + * @param dir the dir parent + * @throws KeeperException + * @throws InterruptedException + */ + private String dir; + private String id = null; + + public String getId() { + return id; + } + + public LockZooKeeperOperation(String dir) { + this.dir = dir; + } + + public LockZooKeeperOperation(String dir, String id) { + this.dir = dir; + this.id = id; + } + + /** + * the command that is run and retried for actually obtaining the lock + * + * @return if the command was successful or not + */ + public boolean execute() throws KeeperException, InterruptedException { + do { + if (id == null) { + String prefix = "x-"; + byte[] data = {0x12, 0x34}; + id = zookeeper.create(dir + "/" + prefix, data, getAcl(), + CreateMode.PERSISTENT_SEQUENTIAL); + + if (logger.isDebugEnabled()) { + logger.debug(EELFLoggerDelegate.debugLogger, "Created id: " + id); + } + if (id != null) + break; + } + if (id != null) { + List names = zookeeper.getChildren(dir, false); + if (names.isEmpty()) { + logger.info(EELFLoggerDelegate.applicationLogger, "No children in: " + dir + + " when we've just " + "created one! Lets recreate it..."); + // lets force the recreation of the id + id = null; + return Boolean.FALSE; + + } else { + // lets sort them explicitly (though they do seem to come back in order + // ususally :) + ZNodeName idName = new ZNodeName(id); + SortedSet sortedNames = new TreeSet(); + for (String name : names) { + sortedNames.add(new ZNodeName(dir + "/" + name)); + } + if (!sortedNames.contains(idName)) + return Boolean.FALSE; + + SortedSet lessThanMe = sortedNames.headSet(idName); + if (!lessThanMe.isEmpty()) { + ZNodeName lastChildName = lessThanMe.last(); + String lastChildId = lastChildName.getName(); + if (logger.isDebugEnabled()) { + logger.debug(EELFLoggerDelegate.debugLogger, "watching less than me node: " + lastChildId); + } + Stat stat = zookeeper.exists(lastChildId, false); + if (stat != null) { + return Boolean.FALSE; + } else { + logger.info(EELFLoggerDelegate.applicationLogger, + "Could not find the" + " stats for less than me: " + + lastChildName.getName()); + } + } else + return Boolean.TRUE; + } + } + } while (id == null); + return Boolean.FALSE; + } + } + +} + diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java b/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java new file mode 100644 index 00000000..7020d14d --- /dev/null +++ b/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.lockingservice; + +import org.apache.zookeeper.KeeperException; + +/** + * A callback object which can be used for implementing retry-able operations in the + * {@link org.onap.music.lockingservice.ProtocolSupport} class + * + */ +public interface ZooKeeperOperation { + + /** + * Performs the operation - which may be involved multiple times if the connection + * to ZooKeeper closes during this operation + * + * @return the result of the operation or null + * @throws KeeperException FILL IN + * @throws InterruptedException FILL IN + */ + public boolean execute() throws KeeperException, InterruptedException; +} diff --git a/jar/src/main/java/org/onap/music/main/CachingUtil.java b/jar/src/main/java/org/onap/music/main/CachingUtil.java new file mode 100755 index 00000000..aa06aae2 --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/CachingUtil.java @@ -0,0 +1,420 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.jcs.JCS; +import org.apache.commons.jcs.access.CacheAccess; +import org.codehaus.jackson.map.ObjectMapper; +import org.mindrot.jbcrypt.BCrypt; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.AAFResponse; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicServiceException; + +import com.att.eelf.configuration.EELFLogger; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.exceptions.InvalidQueryException; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; + +/** + * All Caching related logic is handled by this class and a schedule cron runs to update cache. + * + * @author Vikram + * + */ +public class CachingUtil implements Runnable { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CachingUtil.class); + + private static CacheAccess musicCache = JCS.getInstance("musicCache"); + private static CacheAccess> aafCache = JCS.getInstance("aafCache"); + private static CacheAccess appNameCache = JCS.getInstance("appNameCache"); + private static CacheAccess> musicValidateCache = JCS.getInstance("musicValidateCache"); + private static Map userAttempts = new HashMap<>(); + private static Map lastFailedTime = new HashMap<>(); + + public boolean isCacheRefreshNeeded() { + if (aafCache.get("initBlankMap") == null) + return true; + return false; + } + + public void initializeMusicCache() { + logger.info(EELFLoggerDelegate.applicationLogger,"Initializing Music Cache..."); + musicCache.put("isInitialized", "true"); + } + + public void initializeAafCache() throws MusicServiceException { + logger.info(EELFLoggerDelegate.applicationLogger,"Resetting and initializing AAF Cache..."); + + String query = "SELECT uuid, application_name, keyspace_name, username, password FROM admin.keyspace_master WHERE is_api = ? allow filtering"; + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString(query); + try { + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), false)); + } catch (Exception e1) { + logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR, ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + e1.printStackTrace(); + } + ResultSet rs = MusicCore.get(pQuery); + Iterator it = rs.iterator(); + Map map = null; + while (it.hasNext()) { + Row row = it.next(); + String nameSpace = row.getString("keyspace_name"); + String userId = row.getString("username"); + String password = row.getString("password"); + String keySpace = row.getString("application_name"); + try { + userAttempts.put(nameSpace, 0); + AAFResponse responseObj = triggerAAF(nameSpace, userId, password); + if (responseObj.getNs().size() > 0) { + map = new HashMap<>(); + map.put(userId, password); + aafCache.put(nameSpace, map); + musicCache.put(keySpace, nameSpace); + logger.debug("Cronjob: Cache Updated with AAF response for namespace " + + nameSpace); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO, ErrorTypes.GENERALSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Something at AAF was changed for ns: " + nameSpace+" So not updating Cache for the namespace. "); + e.printStackTrace(); + } + } + + } + + @Override + public void run() { + logger.info(EELFLoggerDelegate.applicationLogger,"Scheduled task invoked. Refreshing Cache..."); + try { + initializeAafCache(); + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO, ErrorTypes.GENERALSERVICEERROR); + } + } + + public static boolean authenticateAAFUser(String nameSpace, String userId, String password, + String keySpace) throws Exception { + + if (aafCache.get(nameSpace) != null) { + if (keySpace != null && !musicCache.get(keySpace).equals(nameSpace)) { + logger.info(EELFLoggerDelegate.applicationLogger,"Create new application for the same namespace."); + } else if (aafCache.get(nameSpace).get(userId).equals(password)) { + logger.info(EELFLoggerDelegate.applicationLogger,"Authenticated with cache value.."); + // reset invalid attempts to 0 + userAttempts.put(nameSpace, 0); + return true; + } else { + // call AAF update cache with new password + if (userAttempts.get(nameSpace) == null) + userAttempts.put(nameSpace, 0); + if ((Integer) userAttempts.get(nameSpace) >= 3) { + logger.info(EELFLoggerDelegate.applicationLogger,"Reached max attempts. Checking if time out.."); + logger.info(EELFLoggerDelegate.applicationLogger,"Failed time: "+lastFailedTime.get(nameSpace).getTime()); + Calendar calendar = Calendar.getInstance(); + long delayTime = (calendar.getTimeInMillis()-lastFailedTime.get(nameSpace).getTimeInMillis()); + logger.info(EELFLoggerDelegate.applicationLogger,"Delayed time: "+delayTime); + if( delayTime > 120000) { + logger.info(EELFLoggerDelegate.applicationLogger,"Resetting failed attempt."); + userAttempts.put(nameSpace, 0); + } else { + logger.info(EELFLoggerDelegate.applicationLogger,"No more attempts allowed. Please wait for atleast 2 min."); + throw new Exception("No more attempts allowed. Please wait for atleast 2 min."); + } + } + logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.CACHEAUTHENTICATION,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + logger.info(EELFLoggerDelegate.applicationLogger,"Check AAF again..."); + } + } + + AAFResponse responseObj = triggerAAF(nameSpace, userId, password); + if (responseObj.getNs().size() > 0) { + if (responseObj.getNs().get(0).getAdmin().contains(userId)) { + //Map map = new HashMap<>(); + //map.put(userId, password); + //aafCache.put(nameSpace, map); + return true; + } + } + logger.info(EELFLoggerDelegate.applicationLogger,"Invalid user. Cache not updated"); + return false; + } + + private static AAFResponse triggerAAF(String nameSpace, String userId, String password) + throws Exception { + if (MusicUtil.getAafEndpointUrl() == null) { + logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + throw new Exception("AAF endpoint is not set. Please specify in the properties file."); + } + Client client = Client.create(); + // WebResource webResource = + // client.resource("https://aaftest.test.att.com:8095/proxy/authz/nss/"+nameSpace); + WebResource webResource = client.resource(MusicUtil.getAafEndpointUrl().concat(nameSpace)); + String plainCreds = userId + ":" + password; + byte[] plainCredsBytes = plainCreds.getBytes(); + byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); + String base64Creds = new String(base64CredsBytes); + + ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON) + .header("Authorization", "Basic " + base64Creds) + .header("content-type", "application/json").get(ClientResponse.class); + if (response.getStatus() != 200) { + if (userAttempts.get(nameSpace) == null) + userAttempts.put(nameSpace, 0); + if ((Integer) userAttempts.get(nameSpace) >= 2) { + lastFailedTime.put(nameSpace, Calendar.getInstance()); + userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1)); + throw new Exception( + "Reached max invalid attempts. Please contact admin and retry with valid credentials."); + } + userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1)); + throw new Exception( + "Unable to authenticate. Please check the AAF credentials against namespace."); + // TODO Allow for 2-3 times and forbid any attempt to trigger AAF with invalid values + // for specific time. + } + response.getHeaders().put(HttpHeaders.CONTENT_TYPE, + Arrays.asList(MediaType.APPLICATION_JSON)); + // AAFResponse output = response.getEntity(AAFResponse.class); + response.bufferEntity(); + String x = response.getEntity(String.class); + AAFResponse responseObj = new ObjectMapper().readValue(x, AAFResponse.class); + + return responseObj; + } + + public static void updateMusicCache(String keyspace, String nameSpace) { + logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for keyspace " + keyspace + " with nameSpace " + nameSpace); + musicCache.put(keyspace, nameSpace); + } + + public static void updateMusicValidateCache(String nameSpace, String userId, String password) { + logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for nameSpacce " + nameSpace + " with userId " + userId); + Map map = new HashMap<>(); + map.put(userId, password); + musicValidateCache.put(nameSpace, map); + } + + public static void updateisAAFCache(String namespace, String isAAF) { + appNameCache.put(namespace, isAAF); + } + + public static String isAAFApplication(String namespace) throws MusicServiceException { + String isAAF = appNameCache.get(namespace); + if (isAAF == null) { + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "SELECT is_aaf from admin.keyspace_master where application_name = '" + + namespace + "' allow filtering"); + Row rs = null; + try { + rs = MusicCore.get(pQuery).one(); + } catch(InvalidQueryException e) { + logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage()); + throw new MusicServiceException("Please make sure admin.keyspace_master table is configured."); + } + try { + isAAF = String.valueOf(rs.getBool("is_aaf")); + if(isAAF != null) + appNameCache.put(namespace, isAAF); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR,ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + e.printStackTrace(); + } + } + return isAAF; + } + + public static String getUuidFromMusicCache(String keyspace) throws MusicServiceException { + String uuid = null; + if (uuid == null) { + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "SELECT uuid from admin.keyspace_master where keyspace_name = '" + + keyspace + "' allow filtering"); + Row rs = MusicCore.get(pQuery).one(); + try { + uuid = rs.getUUID("uuid").toString(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,"Exception occured during uuid retrieval from DB."+e.getMessage()); + e.printStackTrace(); + } + } + return uuid; + } + + public static String getAppName(String keyspace) throws MusicServiceException { + String appName = null; + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "SELECT application_name from admin.keyspace_master where keyspace_name = '" + + keyspace + "' allow filtering"); + Row rs = MusicCore.get(pQuery).one(); + try { + appName = rs.getString("application_name"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); + e.printStackTrace(); + } + return appName; + } + + public static String generateUUID() { + String uuid = UUID.randomUUID().toString(); + logger.info(EELFLoggerDelegate.applicationLogger,"New AID generated: "+uuid); + return uuid; + } + + public static Map validateRequest(String nameSpace, String userId, + String password, String keyspace, String aid, String operation) { + Map resultMap = new HashMap<>(); + if (!"createKeySpace".equals(operation)) { + if (nameSpace == null) { + resultMap.put("Exception", "Application namespace is mandatory."); + } + } + return resultMap; + + } + + public static Map verifyOnboarding(String ns, String userId, String password) { + Map resultMap = new HashMap<>(); + if (ns == null || userId == null || password == null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: "+userId+" :: password: "+password); + resultMap.put("Exception", + "One or more required headers appName(ns), userId, password is missing. Please check."); + return resultMap; + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString( + "select * from admin.keyspace_master where application_name = ? allow filtering"); + try { + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns)); + } catch(Exception e) { + resultMap.put("Exception", + "Unable to process input data. Invalid input data type. Please check ns, userId and password values. "+e.getMessage()); + return resultMap; + } + Row rs = null; + try { + rs = MusicCore.get(queryObject).one(); + } catch (MusicServiceException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage()); + return resultMap; + } catch (InvalidQueryException e) { + logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage()); + resultMap.put("Exception", "Please make sure admin.keyspace_master table is configured."); + return resultMap; + } + if (rs == null) { + logger.error(EELFLoggerDelegate.errorLogger,"Application is not onboarded. Please contact admin."); + resultMap.put("Exception", "Application is not onboarded. Please contact admin."); + } else { + if(!(rs.getString("username").equals(userId)) || !(BCrypt.checkpw(password, rs.getString("password")))) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId); + resultMap.put("Exception", "Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId); + return resultMap; + } + } + return resultMap; + } + + public static Map authenticateAIDUser(String nameSpace, String userId, String password, + String keyspace) { + Map resultMap = new HashMap<>(); + String pwd = null; + if((musicCache.get(keyspace) != null) && (musicValidateCache.get(nameSpace) != null) + && (musicValidateCache.get(nameSpace).containsKey(userId))) { + if(!musicCache.get(keyspace).equals(nameSpace)) { + resultMap.put("Exception", "Namespace and keyspace doesn't match"); + return resultMap; + } + if(!BCrypt.checkpw(password,musicValidateCache.get(nameSpace).get(userId))) { + resultMap.put("Exception", "Namespace, userId and password doesn't match"); + return resultMap; + } + return resultMap; + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString( + "select * from admin.keyspace_master where keyspace_name = ? allow filtering"); + try { + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace)); + } catch (Exception e) { + e.printStackTrace(); + } + Row rs = null; + try { + rs = MusicCore.get(queryObject).one(); + } catch (MusicServiceException e) { + e.printStackTrace(); + resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage()); + return resultMap; + } + if(rs == null) { + resultMap.put("Exception", "Please make sure keyspace:"+keyspace+" exists."); + return resultMap; + } + else { + String user = rs.getString("username"); + pwd = rs.getString("password"); + String ns = rs.getString("application_name"); + if(!ns.equals(nameSpace)) { + resultMap.put("Exception", "Namespace and keyspace doesn't match"); + return resultMap; + } + if(!user.equals(userId)) { + resultMap.put("Exception", "Invalid userId :"+userId); + return resultMap; + } + if(!BCrypt.checkpw(password, pwd)) { + resultMap.put("Exception", "Invalid password"); + return resultMap; + } + } + CachingUtil.updateMusicCache(keyspace, nameSpace); + CachingUtil.updateMusicValidateCache(nameSpace, userId, pwd); + return resultMap; + } +} diff --git a/jar/src/main/java/org/onap/music/main/CronJobManager.java b/jar/src/main/java/org/onap/music/main/CronJobManager.java new file mode 100644 index 00000000..fb4a2ac3 --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/CronJobManager.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +@WebListener +public class CronJobManager implements ServletContextListener { + + private ScheduledExecutorService scheduler; + + @Override + public void contextInitialized(ServletContextEvent event) { + scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.scheduleAtFixedRate(new CachingUtil(), 0, 24, TimeUnit.HOURS); + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + scheduler.shutdownNow(); + } + +} diff --git a/jar/src/main/java/org/onap/music/main/MusicCore.java b/jar/src/main/java/org/onap/music/main/MusicCore.java new file mode 100644 index 00000000..cad384a3 --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/MusicCore.java @@ -0,0 +1,992 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.KeeperException.NoNodeException; +import org.onap.music.datastore.MusicDataStore; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JsonKeySpace; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.lockingservice.MusicLockState; +import org.onap.music.lockingservice.MusicLockState.LockStatus; +import org.onap.music.lockingservice.MusicLockingService; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.ColumnDefinitions.Definition; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.TableMetadata; + +/** + * This class ..... + * + * + */ +public class MusicCore { + + public static MusicLockingService mLockHandle = null; + public static MusicDataStore mDstoreHandle = null; + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class); + + public static class Condition { + Map conditions; + PreparedQueryObject selectQueryForTheRow; + + public Condition(Map conditions, PreparedQueryObject selectQueryForTheRow) { + this.conditions = conditions; + this.selectQueryForTheRow = selectQueryForTheRow; + } + + public boolean testCondition() throws Exception { + // first generate the row + ResultSet results = quorumGet(selectQueryForTheRow); + Row row = results.one(); + return getDSHandle().doesRowSatisfyCondition(row, conditions); + } + } + + + public static MusicLockingService getLockingServiceHandle() throws MusicLockingException { + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle"); + long start = System.currentTimeMillis(); + + if (mLockHandle == null) { + try { + mLockHandle = new MusicLockingService(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException("Failed to aquire Locl store handle " + e); + } + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms"); + return mLockHandle; + } + + /** + * + * @param remoteIp + * @return + */ + public static MusicDataStore getDSHandle(String remoteIp) { + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle"); + long start = System.currentTimeMillis(); + if (mDstoreHandle == null) { + try { + MusicUtil.loadProperties(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "No properties file defined. Falling back to default."); + } + mDstoreHandle = new MusicDataStore(remoteIp); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); + return mDstoreHandle; + } + + /** + * + * @return + * @throws MusicServiceException + */ + public static MusicDataStore getDSHandle() throws MusicServiceException { + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle"); + long start = System.currentTimeMillis(); + if (mDstoreHandle == null) { + try { + MusicUtil.loadProperties(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "No properties file defined. Falling back to default."); + } + // Quick Fix - Best to put this into every call to getDSHandle? + if (! MusicUtil.getMyCassaHost().equals("localhost") ) { + mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost()); + } else { + mDstoreHandle = new MusicDataStore(); + } + } + if(mDstoreHandle.getSession() == null) { + String message = "Connection to Cassandra has not been enstablished." + + " Please check connection properites and reboot."; + logger.info(EELFLoggerDelegate.applicationLogger, message); + throw new MusicServiceException(message); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); + return mDstoreHandle; + } + + public static String createLockReference(String lockName) { + logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName); + long start = System.currentTimeMillis(); + String lockId = null; + try { + lockId = getLockingServiceHandle().createLockId("/" + lockName); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms"); + return lockId; + } + + /** + * + * @param key + * @return + */ + public static boolean isTableOrKeySpaceLock(String key) { + String[] splitString = key.split("\\."); + if (splitString.length > 2) + return false; + else + return true; + } + + /** + * + * @param key + * @return + */ + public static MusicLockState getMusicLockState(String key) { + long start = System.currentTimeMillis(); + try { + String[] splitString = key.split("\\."); + String keyspaceName = splitString[0]; + String tableName = splitString[1]; + String primaryKey = splitString[2]; + MusicLockState mls; + String lockName = keyspaceName + "." + tableName + "." + primaryKey; + mls = getLockingServiceHandle().getLockState(lockName); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms"); + return mls; + } catch (NullPointerException | MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + return null; + } + + public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) { + try { + long start = System.currentTimeMillis(); + /* check if the current lock has exceeded its lease and if yes, release that lock */ + MusicLockState mls = getMusicLockState(key); + if (mls != null) { + if (mls.getLockStatus().equals(LockStatus.LOCKED)) { + logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder() + + ". Checking if it has exceeded lease"); + long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime(); + long currentLeasePeriod = mls.getLeasePeriod(); + if (currentLockPeriod > currentLeasePeriod) { + logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod + + " has exceeded lease period " + currentLeasePeriod); + boolean voluntaryRelease = false; + String currentLockHolder = mls.getLockHolder(); + mls = releaseLock(currentLockHolder, voluntaryRelease); + } + } + } else + logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + + /* + * call the traditional acquire lock now and if the result returned is true, set the + * begin time-stamp and lease period + */ + if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) { + mls = getMusicLockState(key);// get latest state + if ( mls == null ) { + logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null"); + return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null"); + } + if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already + mls.setLeaseStartTime(System.currentTimeMillis()); + mls.setLeasePeriod(leasePeriod); + getLockingServiceHandle().setLockState(key, mls); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms"); + return new ReturnType(ResultType.SUCCESS, "Accquired lock"); + } else { + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms"); + return new ReturnType(ResultType.FAILURE, "Could not acquire lock"); + } + } catch (Exception e) { + StringWriter sw = new StringWriter(); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + + String exceptionAsString = sw.toString(); + return new ReturnType(ResultType.FAILURE, + "Exception thrown in acquireLockWithLease:\n" + exceptionAsString); + } + } + + public static ReturnType acquireLock(String key, String lockId) throws MusicLockingException { + /* + * first check if I am on top. Since ids are not reusable there is no need to check + * lockStatus If the status is unlocked, then the above call will automatically return + * false. + */ + Boolean result = false; + try { + result = getLockingServiceHandle().isMyTurn(lockId); + } catch (MusicLockingException e2) { + logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2); + throw new MusicLockingException(); + } + if (!result) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock"); + try { + if (!getLockingServiceHandle().lockIdExists(lockId)) { + logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist"); + return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist"); + } + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException(); + } + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure"); + return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock"); + } + + + // this is for backward compatibility where locks could also be acquired on just + // keyspaces or tables. + if (isTableOrKeySpaceLock(key)) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true"); + return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true"); + } + + // read the lock name corresponding to the key and if the status is locked or being locked, + // then return false + MusicLockState currentMls = null; + MusicLockState newMls = null; + try { + currentMls = getMusicLockState(key); + String currentLockHolder = currentMls.getLockHolder(); + if (lockId.equals(currentLockHolder)) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!"); + return new ReturnType(ResultType.SUCCESS, "You already have the lock!"); + } + } catch (NullPointerException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + + // change status to "being locked". This state transition is necessary to ensure syncing + // before granting the lock + String lockHolder = null; + boolean needToSyncQuorum = false; + if (currentMls != null) + needToSyncQuorum = currentMls.isNeedToSyncQuorum(); + + + newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder, + needToSyncQuorum); + try { + getLockingServiceHandle().setLockState(key, newMls); + } catch (MusicLockingException e1) { + logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked"); + + // do syncing if this was a forced lock release + if (needToSyncQuorum) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!"); + try { + syncQuorum(key); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e); + } + } + + // change status to locked + lockHolder = lockId; + needToSyncQuorum = false; + newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum); + try { + getLockingServiceHandle().setLockState(key, newMls); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref " + + lockId + " as holder"); + + return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder"); + } + + + + /** + * + * @param keyspaceName + * @param kspObject + * @return + * @throws Exception + */ + public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception { + return true; + } + + + private static void syncQuorum(String key) throws Exception { + logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---"); + String[] splitString = key.split("\\."); + String keyspaceName = splitString[0]; + String tableName = splitString[1]; + String primaryKeyValue = splitString[2]; + PreparedQueryObject selectQuery = new PreparedQueryObject(); + PreparedQueryObject updateQuery = new PreparedQueryObject(); + + // get the primary key d + TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName); + String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single + // primary key + DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType(); + Object cqlFormattedPrimaryKeyValue = + MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue); + + // get the row of data from a quorum + selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE " + + primaryKeyName + "= ?" + ";"); + selectQuery.addValue(cqlFormattedPrimaryKeyValue); + ResultSet results = null; + try { + results = getDSHandle().executeCriticalGet(selectQuery); + // write it back to a quorum + Row row = results.one(); + ColumnDefinitions colInfo = row.getColumnDefinitions(); + int totalColumns = colInfo.size(); + int counter = 1; + StringBuilder fieldValueString = new StringBuilder(""); + for (Definition definition : colInfo) { + String colName = definition.getName(); + if (colName.equals(primaryKeyName)) + continue; + DataType colType = definition.getType(); + Object valueObj = getDSHandle().getColValue(row, colName, colType); + Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); + fieldValueString.append(colName + " = ?"); + updateQuery.addValue(valueString); + if (counter != (totalColumns - 1)) + fieldValueString.append(","); + counter = counter + 1; + } + updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET " + + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";"); + updateQuery.addValue(cqlFormattedPrimaryKeyValue); + + getDSHandle().executePut(updateQuery, "critical"); + } catch (MusicServiceException | MusicQueryException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR); + } + } + + + + + /** + * + * @param query + * @return ResultSet + */ + public static ResultSet quorumGet(PreparedQueryObject query) { + ResultSet results = null; + try { + results = getDSHandle().executeCriticalGet(query); + } catch (MusicServiceException | MusicQueryException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR); + + } + return results; + + } + + /** + * + * @param results + * @return + * @throws MusicServiceException + */ + public static Map> marshallResults(ResultSet results) throws MusicServiceException { + return getDSHandle().marshalData(results); + } + + /** + * + * @param lockName + * @return + */ + public static String whoseTurnIsIt(String lockName) { + + try { + return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + ""; + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + return null; + + + } + + /** + * + * @param lockId + * @return + */ + public static String getLockNameFromId(String lockId) { + StringTokenizer st = new StringTokenizer(lockId); + return st.nextToken("$"); + } + + public static void destroyLockRef(String lockId) { + long start = System.currentTimeMillis(); + try { + getLockingServiceHandle().unlockAndDeleteId(lockId); + } catch (MusicLockingException | NoNodeException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); + } + + public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) { + long start = System.currentTimeMillis(); + try { + getLockingServiceHandle().unlockAndDeleteId(lockId); + } catch (MusicLockingException e1) { + logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } catch (KeeperException.NoNodeException nne) { + logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockId + " " + nne); + MusicLockState mls = new MusicLockState("Lock doesn't exists. Release lock operation failed."); + return mls; + } + String lockName = getLockNameFromId(lockId); + MusicLockState mls; + String lockHolder = null; + if (voluntaryRelease) { + mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder); + logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId); + } else { + boolean needToSyncQuorum = true; + mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder, + needToSyncQuorum); + logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId); + } + try { + getLockingServiceHandle().setLockState(lockName, mls); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms"); + return mls; + } + + public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{ + try { + getLockingServiceHandle().unlockAndDeleteId(lockId); + } catch (KeeperException.NoNodeException e) { + // ??? No way + } + } + + /** + * + * @param lockName + * @throws MusicLockingException + */ + public static void deleteLock(String lockName) throws MusicLockingException { + long start = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName); + try { + getLockingServiceHandle().deleteLock("/" + lockName); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException(e.getMessage()); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms"); + } + + + + /** + * + * @param keyspace + * @param tablename + * @return + * @throws MusicServiceException + */ + public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException { + return getDSHandle().returnColumnMetadata(keyspace, tablename); + } + + + /** + * + * @param nodeName + */ + public static void pureZkCreate(String nodeName) { + try { + getLockingServiceHandle().getzkLockHandle().createNode(nodeName); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + } + + /** + * + * @param nodeName + * @param data + */ + public static void pureZkWrite(String nodeName, byte[] data) { + long start = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName); + try { + getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms"); + } + + /** + * + * @param nodeName + * @return + */ + public static byte[] pureZkRead(String nodeName) { + long start = System.currentTimeMillis(); + byte[] data = null; + try { + data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms"); + return data; + } + + + + // Prepared Query Additions. + + /** + * + * @param keyspaceName + * @param tableName + * @param primaryKey + * @param queryObject + * @return ReturnType + * @throws MusicServiceException + */ + public static ReturnType eventualPut(PreparedQueryObject queryObject) { + boolean result = false; + try { + result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL); + } catch (MusicServiceException | MusicQueryException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex); + return new ReturnType(ResultType.FAILURE, ex.getMessage()); + } + if (result) { + return new ReturnType(ResultType.SUCCESS, "Success"); + } else { + return new ReturnType(ResultType.FAILURE, "Failure"); + } + } + + /** + * + * @param keyspaceName + * @param tableName + * @param primaryKey + * @param queryObject + * @param lockId + * @return + */ + public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject, String lockId, Condition conditionInfo) { + long start = System.currentTimeMillis(); + + try { + MusicLockState mls = getLockingServiceHandle() + .getLockState(keyspaceName + "." + tableName + "." + primaryKey); + if (mls.getLockHolder().equals(lockId) == true) { + if (conditionInfo != null) + try { + if (conditionInfo.testCondition() == false) + return new ReturnType(ResultType.FAILURE, + "Lock acquired but the condition is not true"); + } catch (Exception e) { + return new ReturnType(ResultType.FAILURE, + "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n" + + e.getMessage()); + } + getDSHandle().executePut(queryObject, MusicUtil.CRITICAL); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms"); + return new ReturnType(ResultType.SUCCESS, "Update performed"); + } else + return new ReturnType(ResultType.FAILURE, + "Cannot perform operation since you are the not the lock holder"); + } catch (MusicQueryException | MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + return new ReturnType(ResultType.FAILURE, + "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n" + + e.getMessage()); + }catch(MusicLockingException ex){ + return new ReturnType(ResultType.FAILURE,ex.getMessage()); + } + + } + + /** + * + * @param queryObject + * @param consistency + * @return Boolean Indicates success or failure + * @throws MusicServiceException + * + * + */ + public static ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException { + // this is mainly for some functions like keyspace creation etc which does not + // really need the bells and whistles of Music locking. + boolean result = false; + try { + result = getDSHandle().executePut(queryObject, consistency); + } catch (MusicQueryException | MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + throw new MusicServiceException(ex.getMessage()); + } + return result?ResultType.SUCCESS:ResultType.FAILURE; + } + + /** + * This method performs DDL operation on cassandra. + * + * @param queryObject query object containing prepared query and values + * @return ResultSet + * @throws MusicServiceException + */ + public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException { + ResultSet results = null; + try { + results = getDSHandle().executeEventualGet(queryObject); + } catch (MusicQueryException | MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + throw new MusicServiceException(e.getMessage()); + } + return results; + } + + /** + * This method performs DDL operations on cassandra, if the the resource is available. Lock ID + * is used to check if the resource is free. + * + * @param keyspaceName name of the keyspace + * @param tableName name of the table + * @param primaryKey primary key value + * @param queryObject query object containing prepared query and values + * @param lockId lock ID to check if the resource is free to perform the operation. + * @return ResultSet + */ + public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject, String lockId) throws MusicServiceException { + ResultSet results = null; + try { + MusicLockState mls = getLockingServiceHandle() + .getLockState(keyspaceName + "." + tableName + "." + primaryKey); + if (mls.getLockHolder().equals(lockId)) { + results = getDSHandle().executeCriticalGet(queryObject); + } else + throw new MusicServiceException("YOU DO NOT HAVE THE LOCK"); + } catch (MusicQueryException | MusicServiceException | MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + } + return results; + } + + /** + * This method performs DML operation on cassandra, when the lock of the dd is acquired. + * + * @param keyspaceName name of the keyspace + * @param tableName name of the table + * @param primaryKey primary key value + * @param queryObject query object containing prepared query and values + * @return ReturnType + * @throws MusicLockingException + */ + public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { + + long start = System.currentTimeMillis(); + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long lockCreationTime = System.currentTimeMillis(); + ReturnType lockAcqResult = acquireLock(key, lockId); + long lockAcqTime = System.currentTimeMillis(); + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); + ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, + queryObject, lockId, conditionInfo); + long criticalPutTime = System.currentTimeMillis(); + voluntaryReleaseLock(lockId); + long lockDeleteTime = System.currentTimeMillis(); + String timingInfo = "|lock creation time:" + (lockCreationTime - start) + + "|lock accquire time:" + (lockAcqTime - lockCreationTime) + + "|critical put time:" + (criticalPutTime - lockAcqTime) + + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|"; + criticalPutResult.setTimingInfo(timingInfo); + return criticalPutResult; + } else { + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + destroyLockRef(lockId); + return lockAcqResult; + } + } + + /** + * this function is mainly for the benchmarks to see the effect of lock deletion. + * + * @param keyspaceName + * @param tableName + * @param primaryKey + * @param queryObject + * @param conditionInfo + * @return + * @throws MusicLockingException + */ + public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, + String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { + + long start = System.currentTimeMillis(); + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long lockCreationTime = System.currentTimeMillis(); + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + ReturnType lockAcqResult = acquireLock(key, lockId); + long lockAcqTime = System.currentTimeMillis(); + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); + ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, + queryObject, lockId, conditionInfo); + long criticalPutTime = System.currentTimeMillis(); + deleteLock(key); + long lockDeleteTime = System.currentTimeMillis(); + String timingInfo = "|lock creation time:" + (lockCreationTime - start) + + "|lock accquire time:" + (lockAcqTime - lockCreationTime) + + "|critical put time:" + (criticalPutTime - lockAcqTime) + + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|"; + criticalPutResult.setTimingInfo(timingInfo); + return criticalPutResult; + } else { + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + deleteLock(key); + return lockAcqResult; + } + } + + + + + /** + * This method performs DDL operation on cassasndra, when the lock for the resource is acquired. + * + * @param keyspaceName name of the keyspace + * @param tableName name of the table + * @param primaryKey primary key value + * @param queryObject query object containing prepared query and values + * @return ResultSet + * @throws MusicServiceException + * @throws MusicLockingException + */ + public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException { + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + ReturnType lockAcqResult = acquireLock(key, lockId); + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); + ResultSet result = + criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId); + voluntaryReleaseLock(lockId); + return result; + } else { + destroyLockRef(lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + return null; + } + } + + public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException { + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + + ReturnType lockAcqResult = acquireLock(key, lockId); + + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId); + ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId); + deleteLock(key); + return result; + } else { + deleteLock(key); + logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId); + return null; + } + } + + + + /** + * authenticate user logic + * + * @param nameSpace + * @param userId + * @param password + * @param keyspace + * @param aid + * @param operation + * @return + * @throws Exception + */ + public static Map autheticateUser(String nameSpace, String userId, + String password, String keyspace, String aid, String operation) + throws Exception { + Map resultMap = new HashMap<>(); + String uuid = null; + resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid, + operation); + if (!resultMap.isEmpty()) + return resultMap; + String isAAFApp = null; + try { + isAAFApp= CachingUtil.isAAFApplication(nameSpace); + } catch(MusicServiceException e) { + resultMap.put("Exception", e.getMessage()); + return resultMap; + } + if(isAAFApp == null) { + resultMap.put("Exception", "Namespace: "+nameSpace+" doesn't exist. Please make sure ns(appName)" + + " is correct and Application is onboarded."); + return resultMap; + } + boolean isAAF = Boolean.valueOf(isAAFApp); + if (userId == null || password == null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId + + " :: password: " + password); + resultMap.put("Exception", + "UserId and Password are mandatory for the operation " + operation); + return resultMap; + } + if(!isAAF && !(operation.equals("createKeySpace"))) { + resultMap = CachingUtil.authenticateAIDUser(nameSpace, userId, password, keyspace); + if (!resultMap.isEmpty()) + return resultMap; + + } + if (isAAF && nameSpace != null && userId != null && password != null) { + boolean isValid = true; + try { + isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace); + resultMap.put("Exception", e.getMessage()); + } + if (!isValid) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + resultMap.put("Exception", "User not authenticated..."); + } + if (!resultMap.isEmpty()) + return resultMap; + + } + + if (operation.equals("createKeySpace")) { + logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace."); + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + + try { + Row rs = MusicCore.get(pQuery).one(); + uuid = rs.getUUID("uuid").toString(); + resultMap.put("uuid", "existing"); + } catch (Exception e) { + logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID."); + uuid = CachingUtil.generateUUID(); + resultMap.put("uuid", "new"); + } + resultMap.put("aid", uuid); + } + + return resultMap; + } + + /** + * @param lockName + * @return + */ + public static Map validateLock(String lockName) { + Map resultMap = new HashMap<>(); + String[] locks = lockName.split("\\."); + if(locks.length < 3) { + resultMap.put("Exception", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey"); + return resultMap; + } + String keyspace= locks[0]; + if(keyspace.startsWith("$")) + keyspace = keyspace.substring(1); + resultMap.put("keyspace",keyspace); + return resultMap; + } +} diff --git a/jar/src/main/java/org/onap/music/main/MusicDigest.java b/jar/src/main/java/org/onap/music/main/MusicDigest.java new file mode 100644 index 00000000..893cb51f --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/MusicDigest.java @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +/** + * + * + */ +public class MusicDigest { + private String evPutStatus; + private String vectorTs; + + /** + * @param evPutStatus + * @param vectorTs + */ + public MusicDigest(String evPutStatus, String vectorTs) { + this.evPutStatus = evPutStatus; + this.vectorTs = vectorTs; + } + + /** + * @return + */ + public String getEvPutStatus() { + return evPutStatus; + } + + /** + * @param evPutStatus + */ + public void setEvPutStatus(String evPutStatus) { + this.evPutStatus = evPutStatus; + } + + /** + * @return + */ + public String getVectorTs() { + return vectorTs; + } + + /** + * @param vectorTs + */ + public void setVectorTs(String vectorTs) { + this.vectorTs = vectorTs; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + return vectorTs + "|" + evPutStatus; + } +} + diff --git a/jar/src/main/java/org/onap/music/main/MusicUtil.java b/jar/src/main/java/org/onap/music/main/MusicUtil.java new file mode 100755 index 00000000..fe799c4b --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/MusicUtil.java @@ -0,0 +1,560 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +import java.io.File; +import java.io.FileNotFoundException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.UUID; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import com.datastax.driver.core.DataType; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + + +/** + * @author nelson24 + * + * Properties This will take Properties and load them into MusicUtil. + * This is a hack for now. Eventually it would bebest to do this in + * another way. + * + */ +public class MusicUtil { + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + + public static final String ATOMIC = "atomic"; + public static final String EVENTUAL = "eventual"; + public static final String CRITICAL = "critical"; + public static final String ATOMICDELETELOCK = "atomic_delete_lock"; + public static final String DEFAULTKEYSPACENAME = "TBD"; + private static final String XLATESTVERSION = "X-latestVersion"; + private static final String XMINORVERSION = "X-minorVersion"; + private static final String XPATCHVERSION = "X-patchVersion"; + + private static final String LOCALHOST = "localhost"; + private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties"; + + private static int myId = 0; + private static ArrayList allIds = new ArrayList<>(); + private static String publicIp = ""; + private static ArrayList allPublicIps = new ArrayList<>(); + private static String myZkHost = LOCALHOST; + private static String myCassaHost = LOCALHOST; + private static String defaultMusicIp = LOCALHOST; + private static boolean debug = true; + private static String version = "2.3.0"; + private static String musicRestIp = LOCALHOST; + private static String musicPropertiesFilePath = PROPERTIES_FILE; + private static long defaultLockLeasePeriod = 6000; + private static final String[] propKeys = new String[] { "zookeeper.host", "cassandra.host", "music.ip", "debug", + "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", "public.ip", + "all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url" }; + + private static String cassName = "cassandra"; + private static String cassPwd = "cassandra"; + private static String aafEndpointUrl = null; + + private MusicUtil() { + throw new IllegalStateException("Utility Class"); + } + + + /** + * @return the cassName + */ + public static String getCassName() { + return cassName; + } + + /** + * @return the cassPwd + */ + public static String getCassPwd() { + return cassPwd; + } + + /** + * @return the aafEndpointUrl + */ + public static String getAafEndpointUrl() { + return aafEndpointUrl; + } + + /** + * + * @param aafEndpointUrl + */ + public static void setAafEndpointUrl(String aafEndpointUrl) { + MusicUtil.aafEndpointUrl = aafEndpointUrl; + } + + /** + * + * @return + */ + public static int getMyId() { + return myId; + } + + /** + * + * @param myId + */ + public static void setMyId(int myId) { + MusicUtil.myId = myId; + } + + /** + * + * @return + */ + public static List getAllIds() { + return allIds; + } + + /** + * + * @param allIds + */ + public static void setAllIds(List allIds) { + MusicUtil.allIds = (ArrayList) allIds; + } + + /** + * + * @return + */ + public static String getPublicIp() { + return publicIp; + } + + /** + * + * @param publicIp + */ + public static void setPublicIp(String publicIp) { + MusicUtil.publicIp = publicIp; + } + + /** + * + * @return + */ + public static List getAllPublicIps() { + return allPublicIps; + } + + /** + * + * @param allPublicIps + */ + public static void setAllPublicIps(List allPublicIps) { + MusicUtil.allPublicIps = (ArrayList) allPublicIps; + } + + /** + * Returns An array of property names that should be in the Properties + * files. + * + * @return + */ + public static String[] getPropkeys() { + return propKeys; + } + + /** + * Get MusicRestIp - default = localhost property file value - music.rest.ip + * + * @return + */ + public static String getMusicRestIp() { + return musicRestIp; + } + + /** + * Set MusicRestIp + * + * @param musicRestIp + */ + public static void setMusicRestIp(String musicRestIp) { + MusicUtil.musicRestIp = musicRestIp; + } + + /** + * Get MusicPropertiesFilePath - Default = /opt/music/music.properties + * property file value - music.properties + * + * @return + */ + public static String getMusicPropertiesFilePath() { + return musicPropertiesFilePath; + } + + /** + * Set MusicPropertiesFilePath + * + * @param musicPropertiesFilePath + */ + public static void setMusicPropertiesFilePath(String musicPropertiesFilePath) { + MusicUtil.musicPropertiesFilePath = musicPropertiesFilePath; + } + + /** + * Get DefaultLockLeasePeriod - Default = 6000 property file value - + * lock.lease.period + * + * @return + */ + public static long getDefaultLockLeasePeriod() { + return defaultLockLeasePeriod; + } + + /** + * Set DefaultLockLeasePeriod + * + * @param defaultLockLeasePeriod + */ + public static void setDefaultLockLeasePeriod(long defaultLockLeasePeriod) { + MusicUtil.defaultLockLeasePeriod = defaultLockLeasePeriod; + } + + /** + * Set Debug + * + * @param debug + */ + public static void setDebug(boolean debug) { + MusicUtil.debug = debug; + } + + /** + * Is Debug - Default = true property file value - debug + * + * @return + */ + public static boolean isDebug() { + return debug; + } + + /** + * Set Version + * + * @param version + */ + public static void setVersion(String version) { + MusicUtil.version = version; + } + + /** + * Return the version property file value - version + * + * @return + */ + public static String getVersion() { + return version; + } + + /** + * Get MyZkHost - Zookeeper Hostname - Default = localhost property file + * value - zookeeper.host + * + * @return + */ + public static String getMyZkHost() { + return myZkHost; + } + + /** + * Set MyZkHost - Zookeeper Hostname + * + * @param myZkHost + */ + public static void setMyZkHost(String myZkHost) { + MusicUtil.myZkHost = myZkHost; + } + + /** + * Get MyCassHost - Cassandra Hostname - Default = localhost property file + * value - cassandra.host + * + * @return + */ + public static String getMyCassaHost() { + return myCassaHost; + } + + /** + * Set MyCassHost - Cassandra Hostname + * + * @param myCassaHost + */ + public static void setMyCassaHost(String myCassaHost) { + MusicUtil.myCassaHost = myCassaHost; + } + + /** + * Get DefaultMusicIp - Default = localhost property file value - music.ip + * + * @return + */ + public static String getDefaultMusicIp() { + return defaultMusicIp; + } + + /** + * Set DefaultMusicIp + * + * @param defaultMusicIp + */ + public static void setDefaultMusicIp(String defaultMusicIp) { + MusicUtil.defaultMusicIp = defaultMusicIp; + } + + /** + * + * @return + */ + public static String getTestType() { + String testType = ""; + try { + Scanner fileScanner = new Scanner(new File("")); + testType = fileScanner.next();// ignore the my id line + String batchSize = fileScanner.next();// ignore the my public ip + // line + fileScanner.close(); + } catch (FileNotFoundException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + return testType; + + } + + /** + * + * @param time + */ + public static void sleep(long time) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + Thread.currentThread().interrupt(); + } + } + + /** + * Utility function to check if the query object is valid. + * + * @param withparams + * @param queryObject + * @return + */ + public static boolean isValidQueryObject(boolean withparams, PreparedQueryObject queryObject) { + if (withparams) { + int noOfValues = queryObject.getValues().size(); + int noOfParams = 0; + char[] temp = queryObject.getQuery().toCharArray(); + for (int i = 0; i < temp.length; i++) { + if (temp[i] == '?') + noOfParams++; + } + return (noOfValues == noOfParams); + } else { + return !queryObject.getQuery().isEmpty(); + } + + } + + public static void setCassName(String cassName) { + MusicUtil.cassName = cassName; + } + + public static void setCassPwd(String cassPwd) { + MusicUtil.cassPwd = cassPwd; + } + + public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception { + + String value = ""; + switch (type.getName()) { + case UUID: + value = valueObj + ""; + break; + case TEXT: + case VARCHAR: + String valueString = valueObj + ""; + valueString = valueString.replace("'", "''"); + value = "'" + valueString + "'"; + break; + case MAP: { + Map otMap = (Map) valueObj; + value = "{" + jsonMaptoSqlString(otMap, ",") + "}"; + break; + } + default: + value = valueObj + ""; + break; + } + return value; + } + + /** + * + * @param colType + * @param valueObj + * @return + * @throws MusicTypeConversionException + * @throws Exception + */ + public static Object convertToActualDataType(DataType colType, Object valueObj) throws Exception { + String valueObjString = valueObj + ""; + switch (colType.getName()) { + case UUID: + return UUID.fromString(valueObjString); + case VARINT: + return BigInteger.valueOf(Long.parseLong(valueObjString)); + case BIGINT: + return Long.parseLong(valueObjString); + case INT: + return Integer.parseInt(valueObjString); + case FLOAT: + return Float.parseFloat(valueObjString); + case DOUBLE: + return Double.parseDouble(valueObjString); + case BOOLEAN: + return Boolean.parseBoolean(valueObjString); + case MAP: + return (Map) valueObj; + default: + return valueObjString; + } + } + + /** + * + * Utility function to parse json map into sql like string + * + * @param jMap + * @param lineDelimiter + * @return + */ + + public static String jsonMaptoSqlString(Map jMap, String lineDelimiter) throws Exception{ + StringBuilder sqlString = new StringBuilder(); + int counter = 0; + for (Map.Entry entry : jMap.entrySet()) { + Object ot = entry.getValue(); + String value = ot + ""; + if (ot instanceof String) { + value = "'" + value.replace("'", "''") + "'"; + } + sqlString.append("'" + entry.getKey() + "':" + value); + if (counter != jMap.size() - 1) + sqlString.append(lineDelimiter); + counter = counter + 1; + } + return sqlString.toString(); + } + + @SuppressWarnings("unused") + public static String buildVersion(String major, String minor, String patch) { + if (minor != null) { + major += "." + minor; + if (patch != null) { + major += "." + patch; + } + } + return major; + } + + /** + * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion + * X-latestVerstion will be equal to the latest full version. + * X-minorVersion - will be equal to the latest minor version. + * X-pathVersion - will be equal to the latest patch version. + * Future plans will change this. + * @param response + * @param major + * @param minor + * @param patch + * @return + */ + public static ResponseBuilder buildVersionResponse(String major, String minor, String patch) { + ResponseBuilder response = Response.noContent(); + String versionIn = buildVersion(major,minor,patch); + String version = MusicUtil.getVersion(); + String[] verArray = version.split("\\.",3); + if ( minor != null ) { + response.header(XMINORVERSION,minor); + } else { + response.header(XMINORVERSION,verArray[1]); + } + if ( patch != null ) { + response.header(XPATCHVERSION,patch); + } else { + response.header(XPATCHVERSION,verArray[2]); + } + response.header(XLATESTVERSION,version); + logger.info(EELFLoggerDelegate.applicationLogger,"Version In:" + versionIn); + return response; + } + + + public static void loadProperties() throws Exception { + Properties prop = new Properties(); + InputStream input = null; + try { + // load the properties file + input = MusicUtil.class.getClassLoader().getResourceAsStream("music.properties"); + prop.load(input); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file."); + throw new Exception(); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + // get the property value and return it + MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host")); + String[] zkHost = prop.getProperty("zookeeper.host").split(","); + MusicUtil.setMyZkHost(zkHost[0]); + MusicUtil.setCassName(prop.getProperty("cassandra.user")); + MusicUtil.setCassPwd(prop.getProperty("cassandra.password")); + } + +} diff --git a/jar/src/main/java/org/onap/music/main/PropertiesListener.java b/jar/src/main/java/org/onap/music/main/PropertiesListener.java new file mode 100755 index 00000000..afd35387 --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/PropertiesListener.java @@ -0,0 +1,151 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Properties; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; + +@WebListener +public class PropertiesListener implements ServletContextListener { + private Properties prop; + + private static EELFLoggerDelegate logger = + EELFLoggerDelegate.getLogger(PropertiesListener.class); + + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) { + prop = new Properties(); + Properties projectProp = new Properties(); + URL resource = getClass().getResource("/"); + String musicPropertiesFilePath = resource.getPath().replace("WEB-INF/classes/", + "WEB-INF/classes/project.properties"); + + // Open the file + try { + InputStream musicProps = null; + projectProp.load(new FileInputStream(musicPropertiesFilePath)); + if (projectProp.containsKey("music.properties")) { + musicProps = new FileInputStream(projectProp.getProperty("music.properties")); + } else { + musicProps = new FileInputStream(MusicUtil.getMusicPropertiesFilePath()); + } + prop.load(musicProps); + musicProps.close(); + prop.putAll(projectProp); + String[] propKeys = MusicUtil.getPropkeys(); + for (int k = 0; k < propKeys.length; k++) { + String key = propKeys[k]; + if (prop.containsKey(key) && prop.get(key) != null) { + logger.info(key + " : " + prop.getProperty(key)); + switch (key) { + case "zookeeper.host": + MusicUtil.setMyZkHost(prop.getProperty(key)); + break; + case "cassandra.host": + MusicUtil.setMyCassaHost(prop.getProperty(key)); + break; + case "music.ip": + MusicUtil.setDefaultMusicIp(prop.getProperty(key)); + break; + case "debug": + MusicUtil.setDebug(Boolean + .getBoolean(prop.getProperty(key).toLowerCase())); + break; + case "version": + MusicUtil.setVersion(prop.getProperty(key)); + break; + case "music.rest.ip": + MusicUtil.setMusicRestIp(prop.getProperty(key)); + break; + case "music.properties": + MusicUtil.setMusicPropertiesFilePath(prop.getProperty(key)); + break; + case "lock.lease.period": + MusicUtil.setDefaultLockLeasePeriod( + Long.parseLong(prop.getProperty(key))); + break; + case "my.id": + MusicUtil.setMyId(Integer.parseInt(prop.getProperty(key))); + break; + case "all.ids": + String[] ids = prop.getProperty(key).split(":"); + MusicUtil.setAllIds(new ArrayList(Arrays.asList(ids))); + break; + case "public.ip": + MusicUtil.setPublicIp(prop.getProperty(key)); + break; + case "all.public.ips": + String[] ips = prop.getProperty(key).split(":"); + if (ips.length == 1) { + // Future use + } else if (ips.length > 1) { + MusicUtil.setAllPublicIps( + new ArrayList(Arrays.asList(ips))); + } + break; + case "cassandra.user": + MusicUtil.setCassName(prop.getProperty(key)); + break; + case "cassandra.password": + MusicUtil.setCassPwd(prop.getProperty(key)); + break; + case "aaf.endpoint.url": + MusicUtil.setAafEndpointUrl(prop.getProperty(key)); + break; + default: + logger.error(EELFLoggerDelegate.errorLogger, + "No case found for " + key); + } + } + } + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.IOERROR ,ErrorSeverity.CRITICAL, ErrorTypes.CONNECTIONERROR); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + + logger.info(EELFLoggerDelegate.applicationLogger, + "Starting MUSIC " + MusicUtil.getVersion() + " on node with id " + + MusicUtil.getMyId() + " and public ip " + + MusicUtil.getPublicIp() + "..."); + logger.info(EELFLoggerDelegate.applicationLogger, + "List of all MUSIC ids:" + MusicUtil.getAllIds().toString()); + logger.info(EELFLoggerDelegate.applicationLogger, + "List of all MUSIC public ips:" + MusicUtil.getAllPublicIps().toString()); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) { + prop = null; + } +} diff --git a/jar/src/main/java/org/onap/music/main/ResultType.java b/jar/src/main/java/org/onap/music/main/ResultType.java new file mode 100644 index 00000000..61ba0295 --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/ResultType.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +public enum ResultType { + SUCCESS("Success"), FAILURE("Failure"), + SYNTAXERROR("SyntaxError"), EXCEPTION("Exception"), + BODYMISSING("Incomplete Request body. Please correct your input request and retry."); + + private String result; + + ResultType(String result) { + this.result = result; + } + + public String getResult() { + return result; + } + +} + + diff --git a/jar/src/main/java/org/onap/music/main/ReturnType.java b/jar/src/main/java/org/onap/music/main/ReturnType.java new file mode 100644 index 00000000..1453a1bf --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/ReturnType.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.main; + +import java.util.HashMap; +import java.util.Map; + +public class ReturnType { + private ResultType result; + private String message; + + public ReturnType(ResultType result, String message) { + super(); + this.result = result; + this.message = message; + } + + public String getTimingInfo() { + return timingInfo; + } + + public void setTimingInfo(String timingInfo) { + this.timingInfo = timingInfo; + } + + private String timingInfo; + + public ResultType getResult() { + return result; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String toJson() { + return "{ \"result\":\"" + result.getResult() + "\", \"message\":\"" + message + "\"}"; + } + + public String toString() { + return result + " | " + message; + } + + public Map toMap() { + Map newMap = new HashMap<>(); + newMap.put("result", result.getResult()); + newMap.put("message", message); + return newMap; + } + +} diff --git a/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java b/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java new file mode 100644 index 00000000..a406afce --- /dev/null +++ b/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java @@ -0,0 +1,265 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.response.jsonobjects; + +import java.util.HashMap; +import java.util.Map; + +import org.onap.music.lockingservice.MusicLockState.LockStatus; +import org.onap.music.main.ResultType; +import org.powermock.core.spi.testresult.Result; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.ColumnDefinitions.Definition; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "JsonResponse", description = "General Response JSON") +public class JsonResponse { + + /* Status is required */ + private ResultType status; + + /* Standard informational fields */ + private String error; + private String message; + + /* versioning */ + private String musicVersion; + + /* Data Fields */ + private Map> dataResult; + + /* Locking fields */ + private String lock; + private LockStatus lockStatus; + private String lockHolder; + private String lockLease; + + + /** + * Create a JSONLock Response + * Use setters to provide more information as in + * JsonLockResponse(ResultType.SUCCESS).setMessage("We did it").setLock(mylockname) + * @param status + */ + public JsonResponse(ResultType status) { + this.status = status; + } + + /** + * + * @return + */ + @ApiModelProperty(value = "Overall status of the response.", + allowableValues = "Success,Failure") + public ResultType getStatus() { + return status; + } + + /** + * + * @param status + */ + public JsonResponse setStatus(ResultType status) { + this.status = status; + return this; + } + + /** + * + * @return the error + */ + @ApiModelProperty(value = "Error value") + public String getError() { + return error; + } + + /** + * + * @param error + */ + public JsonResponse setError(String error) { + this.error = error; + return this; + } + + /** + * + * @return the message + */ + @ApiModelProperty(value = "Message value") + public String getMessage() { + return message; + } + + /** + * + * @param message + */ + public JsonResponse setMessage(String message) { + this.message = message; + return this; + } + + + /** + * + * @return the music version + */ + public String getMusicVersion() { + return this.musicVersion; + } + + /** + * + * @param version of music + * @return + */ + public JsonResponse setMusicVersion(String version) { + this.musicVersion = version; + return this; + } + + public Map> getDataResult() { + return this.dataResult; + } + + public JsonResponse setDataResult(Map> map) { + this.dataResult = map; + return this; + } + + /** + * + * @return + */ + public String getLock() { + return lock; + } + + /** + * + * @param lock + */ + public JsonResponse setLock(String lock) { + this.lock = lock; + return this; + } + + /** + * + * @return the lockStatus + */ + @ApiModelProperty(value = "Status of the lock") + public LockStatus getLockStatus() { + return lockStatus; + } + + /** + * + * @param lockStatus + */ + public JsonResponse setLockStatus(LockStatus lockStatus) { + this.lockStatus = lockStatus; + return this; + } + + /** + * + * + * @return the lockHolder + */ + @ApiModelProperty(value = "Holder of the Lock") + public String getLockHolder() { + return lockHolder; + } + + /** + * + * @param lockHolder + */ + public JsonResponse setLockHolder(String lockHolder) { + this.lockHolder = lockHolder; + return this; + } + + + + /** + * @return the lockLease + */ + public String getLockLease() { + return lockLease; + } + + /** + * @param lockLease the lockLease to set + */ + public JsonResponse setLockLease(String lockLease) { + this.lockLease = lockLease; + return this; + } + + /** + * Convert to Map + * + * @return + */ + public Map toMap() { + Map fullMap = new HashMap<>(); + fullMap.put("status", status); + if (error!=null) {fullMap.put("error", error);} + if (message!=null) {fullMap.put("message", message);} + + if (musicVersion!=null) {fullMap.put("version", musicVersion);} + + if (dataResult!=null) { + fullMap.put("result", dataResult); + } + + if (lock!=null) { + Map lockMap = new HashMap<>(); + if (lock!=null) {lockMap.put("lock", lock);} + if (lockStatus!=null) {lockMap.put("lock-status", lockStatus);} + if (lockHolder!=null) {lockMap.put("lock-holder", lockHolder);} + if (lockLease!=null) {lockMap.put("lock-lease", lockLease);} + fullMap.put("lock", lockMap); + } + + return fullMap; + } + + /** + * Convert to String + */ + @Override + public String toString() { + return "JsonLockResponse [status=" + status + ", error=" + error + ", message=" + message + + ", lock=" + lock + ", lockStatus=" + lockStatus + ", lockHolder=" + + lockHolder + "]"; + } + +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java new file mode 100755 index 00000000..e7c7fb6c --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java @@ -0,0 +1,372 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +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.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + +import org.mindrot.jbcrypt.BCrypt; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JsonOnboard; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.main.CachingUtil; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + +@Path("/v2/admin") +// @Path("/v{version: [0-9]+}/admin") +// @Path("/admin") +@Api(value = "Admin Api", hidden = true) +public class RestMusicAdminAPI { + private static EELFLoggerDelegate logger = + EELFLoggerDelegate.getLogger(RestMusicAdminAPI.class); + + /* + * API to onboard an application with MUSIC. This is the mandatory first step. + * + */ + @POST + @Path("/onboardAppWithMusic") + @ApiOperation(value = "Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response onboardAppWithMusic(JsonOnboard jsonObj) throws Exception { + ResponseBuilder response = + Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + Map resultMap = new HashMap<>(); + String appName = jsonObj.getAppname(); + String userId = jsonObj.getUserId(); + String isAAF = jsonObj.getIsAAF(); + String password = jsonObj.getPassword(); + if (appName == null || userId == null || isAAF == null || password == null) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO, + ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + resultMap.put("Exception", + "Unauthorized: Please check the request parameters. Some of the required values appName(ns), userId, password, isAAF are missing."); + return Response.status(Status.UNAUTHORIZED).entity(resultMap).build(); + } + + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select uuid from admin.keyspace_master where application_name = ? allow filtering"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + ResultSet rs = MusicCore.get(pQuery); + if (!rs.all().isEmpty()) { + resultMap.put("Exception", "Application " + appName + + " has already been onboarded. Please contact admin."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + pQuery = new PreparedQueryObject(); + String uuid = CachingUtil.generateUUID(); + pQuery.appendQueryString( + "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " + + "password, username, is_aaf) VALUES (?,?,?,?,?,?,?)"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + + String returnStr = MusicCore.eventualPut(pQuery).toString(); + if (returnStr.contains("Failure")) { + resultMap.put("Exception", + "Oops. Something wrong with onboarding process. Please retry later or contact admin."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + CachingUtil.updateisAAFCache(appName, isAAF); + resultMap.put("Success", "Your application " + appName + " has been onboarded with MUSIC."); + resultMap.put("Generated AID", uuid); + return Response.status(Status.OK).entity(resultMap).build(); + } + + + @POST + @Path("/search") + @ApiOperation(value = "Search Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getOnboardedInfoSearch(JsonOnboard jsonObj) throws Exception { + Map resultMap = new HashMap<>(); + ResponseBuilder response = + Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + String appName = jsonObj.getAppname(); + String uuid = jsonObj.getAid(); + String isAAF = jsonObj.getIsAAF(); + + if (appName == null && uuid == null && isAAF == null) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO, + ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + resultMap.put("Exception", + "Unauthorized: Please check the request parameters. Enter atleast one of the following parameters: appName(ns), aid, isAAF."); + return Response.status(Status.UNAUTHORIZED).entity(resultMap).build(); + } + + PreparedQueryObject pQuery = new PreparedQueryObject(); + String cql = "select uuid, keyspace_name from admin.keyspace_master where "; + if (appName != null) + cql = cql + "application_name = ? AND "; + if (uuid != null) + cql = cql + "uuid = ? AND "; + if (isAAF != null) + cql = cql + "is_aaf = ?"; + + if (cql.endsWith("AND ")) + cql = cql.trim().substring(0, cql.length() - 4); + System.out.println("Query is: " + cql); + cql = cql + " allow filtering"; + System.out.println("Get OnboardingInfo CQL: " + cql); + pQuery.appendQueryString(cql); + if (appName != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + if (uuid != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + if (isAAF != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), + Boolean.parseBoolean(isAAF))); + ResultSet rs = MusicCore.get(pQuery); + Iterator it = rs.iterator(); + while (it.hasNext()) { + Row row = (Row) it.next(); + resultMap.put(row.getUUID("uuid").toString(), row.getString("keyspace_name")); + } + if (resultMap.isEmpty()) { + if (uuid != null) { + resultMap.put("Exception", + "Please make sure Aid is correct and application is onboarded."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } else { + resultMap.put("Exception", + "Application is not onboarded. Please make sure all the information is correct."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + } + return Response.status(Status.OK).entity(resultMap).build(); + } + + + @DELETE + @Path("/onboardAppWithMusic") + @ApiOperation(value = "Delete Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteOnboardApp(JsonOnboard jsonObj) throws Exception { + Map resultMap = new HashMap<>(); + ResponseBuilder response = + Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + String appName = jsonObj.getAppname(); + String aid = jsonObj.getAid(); + PreparedQueryObject pQuery = new PreparedQueryObject(); + String consistency = MusicUtil.EVENTUAL;; + if (appName == null && aid == null) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + resultMap.put("Exception", "Please make sure either appName(ns) or Aid is present"); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + if (aid != null) { + pQuery.appendQueryString( + "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString(aid))); + Row row = MusicCore.get(pQuery).one(); + if (row != null) { + String ks = row.getString("keyspace_name"); + if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) { + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("DROP KEYSPACE IF EXISTS " + ks + ";"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + } + } + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ? IF EXISTS"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString(aid))); + ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency); + if (result == ResultType.SUCCESS) { + resultMap.put("Success", "Your application has been deleted successfully"); + } else { + resultMap.put("Exception", + "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded"); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + + } + return Response.status(Status.OK).entity(resultMap).build(); + } + + pQuery.appendQueryString( + "select uuid from admin.keyspace_master where application_name = ? allow filtering"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + ResultSet rs = MusicCore.get(pQuery); + List rows = rs.all(); + String uuid = null; + if (rows.size() == 0) { + resultMap.put("Exception", + "Application not found. Please make sure Application exists."); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } else if (rows.size() == 1) { + uuid = rows.get(0).getUUID("uuid").toString(); + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString(uuid))); + Row row = MusicCore.get(pQuery).one(); + String ks = row.getString("keyspace_name"); + if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) { + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("DROP KEYSPACE " + ks + ";"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + } + + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString(uuid))); + MusicCore.eventualPut(pQuery); + resultMap.put("Success", "Your application " + appName + " has been deleted."); + return Response.status(Status.OK).entity(resultMap).build(); + } else { + resultMap.put("Failure", + "More than one Aid exists for this application, so please provide Aid."); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MULTIPLERECORDS, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + } + + + @PUT + @Path("/onboardAppWithMusic") + @ApiOperation(value = "Update Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateOnboardApp(JsonOnboard jsonObj) throws Exception { + Map resultMap = new HashMap<>(); + ResponseBuilder response = + Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + String aid = jsonObj.getAid(); + String appName = jsonObj.getAppname(); + String userId = jsonObj.getUserId(); + String isAAF = jsonObj.getIsAAF(); + String password = jsonObj.getPassword(); + String consistency = "eventual"; + PreparedQueryObject pQuery; + + if (aid == null) { + resultMap.put("Exception", "Please make sure Aid is present"); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + if (appName == null && userId == null && password == null && isAAF == null) { + resultMap.put("Exception", + "No parameters found to update. Please update atleast one parameter."); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + if (appName != null) { + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select uuid from admin.keyspace_master where application_name = ? allow filtering"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + ResultSet rs = MusicCore.get(pQuery); + if (!rs.all().isEmpty()) { + resultMap.put("Exception", "Application " + appName + + " has already been onboarded. Please contact admin."); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.ALREADYEXIST, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + } + + pQuery = new PreparedQueryObject(); + StringBuilder preCql = new StringBuilder("UPDATE admin.keyspace_master SET "); + if (appName != null) + preCql.append(" application_name = ?,"); + if (userId != null) + preCql.append(" username = ?,"); + if (password != null) + preCql.append(" password = ?,"); + if (isAAF != null) + preCql.append(" is_aaf = ?,"); + preCql.deleteCharAt(preCql.length() - 1); + preCql.append(" WHERE uuid = ? IF EXISTS"); + pQuery.appendQueryString(preCql.toString()); + if (appName != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + if (userId != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + if (password != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); + if (isAAF != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), UUID.fromString(aid))); + ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency); + + if (result == ResultType.SUCCESS) { + resultMap.put("Success", "Your application has been updated successfully"); + } else { + resultMap.put("Exception", + "Oops. Something went wrong. Please make sure Aid is correct and application is onboarded"); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + return Response.status(Status.OK).entity(resultMap).build(); + } +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java new file mode 100644 index 00000000..55eb47f2 --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java @@ -0,0 +1,307 @@ +/* + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT 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.music.rest; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +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.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriInfo; +import org.onap.music.datastore.jsonobjects.JsonInsert; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; +import org.onap.music.datastore.PreparedQueryObject; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.TableMetadata; +import io.swagger.annotations.Api; +//import io.swagger.annotations.ApiOperation; +//import io.swagger.annotations.ApiParam; + +/* + * These are functions created purely for benchmarking purposes. Commented out Swagger - This should + * be undocumented API + * + */ +@Path("/v{version: [0-9]+}/benchmarks/") +@Api(value = "Benchmark API", hidden = true) +public class RestMusicBmAPI { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicBmAPI.class); + + // pure zk calls... + + /** + * + * @param nodeName + * @throws Exception + */ + @POST + @Path("/purezk/{name}") + @Consumes(MediaType.APPLICATION_JSON) + public void pureZkCreate(@PathParam("name") String nodeName) throws Exception { + MusicCore.pureZkCreate("/" + nodeName); + } + + + /** + * + * @param insObj + * @param nodeName + * @throws Exception + */ + @PUT + @Path("/purezk/{name}") + @Consumes(MediaType.APPLICATION_JSON) + public void pureZkUpdate(JsonInsert insObj, @PathParam("name") String nodeName) + throws Exception { + logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zk normal update-------------------------"); + long start = System.currentTimeMillis(); + MusicCore.pureZkWrite(nodeName, insObj.serialize()); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk normal update:" + (end - start) + " ms"); + } + + /** + * + * @param nodeName + * @return + * @throws Exception + */ + @GET + @Path("/purezk/{name}") + @Consumes(MediaType.TEXT_PLAIN) + public byte[] pureZkGet(@PathParam("name") String nodeName) throws Exception { + return MusicCore.pureZkRead(nodeName); + } + + /** + * + * @param insObj + * @param lockName + * @param nodeName + * @throws Exception + */ + @PUT + @Path("/purezk/atomic/{lockname}/{name}") + @Consumes(MediaType.APPLICATION_JSON) + public void pureZkAtomicPut(JsonInsert updateObj, @PathParam("lockname") String lockname, + @PathParam("name") String nodeName) throws Exception { + long startTime = System.currentTimeMillis(); + String operationId = UUID.randomUUID().toString();// just for debugging purposes. + String consistency = updateObj.getConsistencyInfo().get("type"); + + logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zookeeper " + consistency + " update-" + operationId + + "-------------------------"); + + byte[] data = updateObj.serialize(); + long jsonParseCompletionTime = System.currentTimeMillis(); + + String lockId = MusicCore.createLockReference(lockname); + + long lockCreationTime = System.currentTimeMillis(); + + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockname, lockId, leasePeriod); + long lockAcqTime = System.currentTimeMillis(); + long zkPutTime = 0, lockReleaseTime = 0; + + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); + MusicCore.pureZkWrite(lockname, data); + zkPutTime = System.currentTimeMillis(); + boolean voluntaryRelease = true; + if (consistency.equals("atomic")) + MusicCore.releaseLock(lockId, voluntaryRelease); + else if (consistency.equals("atomic_delete_lock")) + MusicCore.deleteLock(lockname); + lockReleaseTime = System.currentTimeMillis(); + } else { + MusicCore.destroyLockRef(lockId); + } + + long actualUpdateCompletionTime = System.currentTimeMillis(); + + + long endTime = System.currentTimeMillis(); + + String lockingInfo = "|lock creation time:" + (lockCreationTime - jsonParseCompletionTime) + + "|lock accquire time:" + (lockAcqTime - lockCreationTime) + + "|zk put time:" + (zkPutTime - lockAcqTime); + + if (consistency.equals("atomic")) + lockingInfo = lockingInfo + "|lock release time:" + (lockReleaseTime - zkPutTime) + "|"; + else if (consistency.equals("atomic_delete_lock")) + lockingInfo = lockingInfo + "|lock delete time:" + (lockReleaseTime - zkPutTime) + "|"; + + String timingString = "Time taken in ms for Zookeeper " + consistency + " update-" + + operationId + ":" + "|total operation time:" + (endTime - startTime) + + "|json parsing time:" + (jsonParseCompletionTime - startTime) + + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime) + + lockingInfo; + + logger.info(EELFLoggerDelegate.applicationLogger,timingString); + } + + /** + * + * @param insObj + * @param lockName + * @param nodeName + * @throws Exception + */ + @GET + @Path("/purezk/atomic/{lockname}/{name}") + @Consumes(MediaType.APPLICATION_JSON) + public void pureZkAtomicGet(JsonInsert insObj, @PathParam("lockname") String lockName, + @PathParam("name") String nodeName) throws Exception { + logger.info("--------------Zk atomic read-------------------------"); + long start = System.currentTimeMillis(); + String lockId = MusicCore.createLockReference(lockName); + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockName, lockId, leasePeriod); + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info("acquired lock with id " + lockId); + MusicCore.pureZkRead(nodeName); + boolean voluntaryRelease = true; + MusicCore.releaseLock(lockId, voluntaryRelease); + } else { + MusicCore.destroyLockRef(lockId); + } + + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk atomic read:" + (end - start) + " ms"); + } + + /** + * + * doing an update directly to cassa but through the rest api + * + * @param insObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @PUT + @Path("/cassa/keyspaces/{keyspace}/tables/{tablename}/rows") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public boolean updateTableCassa(JsonInsert insObj, @PathParam("keyspace") String keyspace, + @PathParam("tablename") String tablename, @Context UriInfo info) + throws Exception { + long startTime = System.currentTimeMillis(); + String operationId = UUID.randomUUID().toString();// just for debugging purposes. + String consistency = insObj.getConsistencyInfo().get("type"); + logger.info(EELFLoggerDelegate.applicationLogger,"--------------Cassandra " + consistency + " update-" + operationId + + "-------------------------"); + PreparedQueryObject queryObject = new PreparedQueryObject(); + Map valuesMap = insObj.getValues(); + TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename); + String vectorTs = "'" + Thread.currentThread().getId() + System.currentTimeMillis() + "'"; + String fieldValueString = "vector_ts= ? ,"; + queryObject.addValue(vectorTs); + + int counter = 0; + for (Map.Entry entry : valuesMap.entrySet()) { + Object valueObj = entry.getValue(); + DataType colType = tableInfo.getColumn(entry.getKey()).getType(); + Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); + fieldValueString = fieldValueString + entry.getKey() + "= ?"; + queryObject.addValue(valueString); + if (counter != valuesMap.size() - 1) + fieldValueString = fieldValueString + ","; + counter = counter + 1; + } + + // get the row specifier + String rowSpec = ""; + counter = 0; + queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " "); + MultivaluedMap rowParams = info.getQueryParameters(); + String primaryKey = ""; + for (MultivaluedMap.Entry> entry : rowParams.entrySet()) { + String keyName = entry.getKey(); + List valueList = entry.getValue(); + String indValue = valueList.get(0); + DataType colType = tableInfo.getColumn(entry.getKey()).getType(); + Object formattedValue = MusicUtil.convertToActualDataType(colType, indValue); + primaryKey = primaryKey + indValue; + rowSpec = rowSpec + keyName + "= ? "; + queryObject.addValue(formattedValue); + if (counter != rowParams.size() - 1) + rowSpec = rowSpec + " AND "; + counter = counter + 1; + } + + + String ttl = insObj.getTtl(); + String timestamp = insObj.getTimestamp(); + + if ((ttl != null) && (timestamp != null)) { + + logger.info(EELFLoggerDelegate.applicationLogger,"both there"); + queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?"); + queryObject.addValue(Integer.parseInt(ttl)); + queryObject.addValue(Long.parseLong(timestamp)); + } + + if ((ttl != null) && (timestamp == null)) { + logger.info(EELFLoggerDelegate.applicationLogger,"ONLY TTL there"); + queryObject.appendQueryString(" USING TTL ?"); + queryObject.addValue(Integer.parseInt(ttl)); + } + + if ((ttl == null) && (timestamp != null)) { + logger.info(EELFLoggerDelegate.applicationLogger,"ONLY timestamp there"); + queryObject.appendQueryString(" USING TIMESTAMP ?"); + queryObject.addValue(Long.parseLong(timestamp)); + } + queryObject.appendQueryString(" SET " + fieldValueString + " WHERE " + rowSpec + ";"); + + long jsonParseCompletionTime = System.currentTimeMillis(); + + boolean operationResult = true; + MusicCore.getDSHandle().executePut(queryObject, insObj.getConsistencyInfo().get("type")); + + long actualUpdateCompletionTime = System.currentTimeMillis(); + + long endTime = System.currentTimeMillis(); + + String timingString = "Time taken in ms for Cassandra " + consistency + " update-" + + operationId + ":" + "|total operation time:" + (endTime - startTime) + + "|json parsing time:" + (jsonParseCompletionTime - startTime) + + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime) + + "|"; + logger.info(EELFLoggerDelegate.applicationLogger,timingString); + + return operationResult; + } +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java new file mode 100755 index 00000000..47d1eae7 --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java @@ -0,0 +1,1289 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; + +import org.mindrot.jbcrypt.BCrypt; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JsonDelete; +import org.onap.music.datastore.jsonobjects.JsonInsert; +import org.onap.music.datastore.jsonobjects.JsonKeySpace; +import org.onap.music.datastore.jsonobjects.JsonTable; +import org.onap.music.datastore.jsonobjects.JsonUpdate; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.CachingUtil; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicCore.Condition; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; +import org.onap.music.response.jsonobjects.JsonResponse; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.TableMetadata; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; + +/* Version 2 Class */ +//@Path("/v{version: [0-9]+}/keyspaces") +@Path("/v2/keyspaces") +@Api(value = "Data Api") +public class RestMusicDataAPI { + /* + * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR + * version back from the client to the server, and from the server back to the client - This + * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR + * version (if not specified by the client on the request) - Contains a single position value + * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on + * request; however, this header should be provided if the client needs to take advantage of + * MINOR incremented version functionality - Is mandatory for the server on response + * + *** X-patchVersion *** - Used only to communicate a PATCH version in a response for + * troubleshooting purposes only, and will not be provided by the client on request - This will + * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version + * of the MAJOR (if not specified by the client on the request) - Contains a single position + * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the + * server on response (CURRENTLY NOT USED) + * + *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the + * server on response, and shall include the entire version of the API (e.g. if the full version + * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are + * not using the latest version of the API (CURRENTLY NOT USED) + * + */ + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class); + private static final String XMINORVERSION = "X-minorVersion"; + private static final String XPATCHVERSION = "X-patchVersion"; + private static final String NS = "ns"; + private static final String USERID = "userId"; + private static final String PASSWORD = "password"; + private static final String VERSION = "v2"; + + private class RowIdentifier { + public String primarKeyValue; + public StringBuilder rowIdString; + @SuppressWarnings("unused") + public PreparedQueryObject queryObject;// the string with all the row + // identifiers separated by AND + + public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString, + PreparedQueryObject queryObject) { + this.primarKeyValue = primaryKeyValue; + this.rowIdString = rowIdString; + this.queryObject = queryObject; + } + } + + + /** + * Create Keyspace REST + * + * @param kspObject + * @param keyspaceName + * @return + * @throws Exception + */ + @POST + @Path("/{name}") + @ApiOperation(value = "Create Keyspace", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + //public Map createKeySpace( + public Response createKeySpace( + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + JsonKeySpace kspObject, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = CachingUtil.verifyOnboarding(ns, userId, password); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + response.status(Status.UNAUTHORIZED); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + if(kspObject == null || kspObject.getReplicationInfo() == null) { + authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult()); + response.status(Status.BAD_REQUEST); + return response.entity(authMap).build(); + } + + try { + authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "createKeySpace"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + response.status(Status.BAD_REQUEST); + return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build(); + } + String newAid = null; + if (!authMap.isEmpty()) { + if (authMap.containsKey("aid")) { + newAid = (String) authMap.get("aid"); + } else { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + response.status(Status.UNAUTHORIZED); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + } + + String consistency = MusicUtil.EVENTUAL;// for now this needs only + // eventual consistency + + PreparedQueryObject queryObject = new PreparedQueryObject(); + long start = System.currentTimeMillis(); + Map replicationInfo = kspObject.getReplicationInfo(); + String repString = null; + try { + repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}"; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + + } + queryObject.appendQueryString( + "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString); + if (kspObject.getDurabilityOfWrites() != null) { + queryObject.appendQueryString( + " AND durable_writes = " + kspObject.getDurabilityOfWrites()); + } + + queryObject.appendQueryString(";"); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger, + "Time taken for setting up query in create keyspace:" + (end - start)); + + ResultType result = ResultType.FAILURE; + try { + result = MusicCore.nonKeyRelatedPut(queryObject, consistency); + logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result); + } catch ( MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build(); + } + + try { + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId + + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName + + " to '" + userId + "'"); + queryObject.appendQueryString(";"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + } + + try { + boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns)); + String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt()); + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString( + "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " + + "password, username, is_aaf) values (?,?,?,?,?,?,?)"); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + CachingUtil.updateMusicCache(keyspaceName, ns); + CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd); + MusicCore.eventualPut(queryObject); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build(); + } + + /** + * + * @param kspObject + * @param keyspaceName + * @return + * @throws Exception + */ + @DELETE + @Path("/{name}") + @ApiOperation(value = "Delete Keyspace", response = String.class) + @Produces(MediaType.APPLICATION_JSON) + //public Map dropKeySpace( + public Response dropKeySpace( + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + return response.status(Status.UNAUTHORIZED).entity(authMap).build(); + } + + String consistency = MusicUtil.EVENTUAL;// for now this needs only + // eventual + // consistency + String appName = CachingUtil.getAppName(keyspaceName); + String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName); + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + Row row = MusicCore.get(pQuery).one(); + long count = row.getLong(0); + + if (count == 0) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build(); + // Admin Functions: + } else if (count == 1) { + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + MusicCore.nonKeyRelatedPut(pQuery, consistency); + } else { + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + MusicCore.nonKeyRelatedPut(pQuery, consistency); + } + + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";"); + ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency); + if ( result.equals(ResultType.FAILURE) ) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build(); + } + + /** + * + * @param tableObj + * @param version + * @param keyspace + * @param tablename + * @param headers + * @return + * @throws Exception + */ + @POST + @Path("/{keyspace}/tables/{tablename}") + @ApiOperation(value = "Create Table", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + //public Map createTable( + public Response createTable( + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + JsonTable tableObj, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, + aid, "createTable"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + String consistency = MusicUtil.EVENTUAL; + // for now this needs only eventual consistency + PreparedQueryObject queryObject = new PreparedQueryObject(); + // first read the information about the table fields + Map fields = tableObj.getFields(); + StringBuilder fieldsString = new StringBuilder("(vector_ts text,"); + int counter = 0; + String primaryKey; + for (Map.Entry entry : fields.entrySet()) { + + if (entry.getKey().equals("PRIMARY KEY")) { + if(! entry.getValue().contains("(")) + primaryKey = entry.getValue(); + else { + primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1); + primaryKey = primaryKey.substring(0, primaryKey.indexOf(')')); + } + fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")"); + } else + fieldsString.append("" + entry.getKey() + " " + entry.getValue() + ""); + if (counter == fields.size() - 1) + fieldsString.append(")"); + else + fieldsString.append(","); + counter = counter + 1; + } + // information about the name-value style properties + Map propertiesMap = tableObj.getProperties(); + StringBuilder propertiesString = new StringBuilder(); + if (propertiesMap != null) { + counter = 0; + for (Map.Entry entry : propertiesMap.entrySet()) { + Object ot = entry.getValue(); + String value = ot + ""; + if (ot instanceof String) { + value = "'" + value + "'"; + } else if (ot instanceof Map) { + @SuppressWarnings("unchecked") + Map otMap = (Map) ot; + value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}"; + } + + propertiesString.append(entry.getKey() + "=" + value + ""); + if (counter != propertiesMap.size() - 1) + propertiesString.append(" AND "); + + counter = counter + 1; + } + } + + queryObject.appendQueryString( + "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString); + + if (propertiesMap != null) + queryObject.appendQueryString(" WITH " + propertiesString); + + queryObject.appendQueryString(";"); + ResultType result = ResultType.FAILURE; + + try { + result = MusicCore.nonKeyRelatedPut(queryObject, consistency); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR); + response.status(Status.BAD_REQUEST); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + if ( result.equals(ResultType.FAILURE) ) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build(); + } + + /** + * + * @param keyspace + * @param tablename + * @param fieldName + * @param info + * @throws Exception + */ + @POST + @Path("/{keyspace}/tables/{tablename}/index/{field}") + @ApiOperation(value = "Create Index", response = String.class) + @Produces(MediaType.APPLICATION_JSON) + public Response createIndex( + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename, + @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName, + @Context UriInfo info) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + response.status(Status.UNAUTHORIZED); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + MultivaluedMap rowParams = info.getQueryParameters(); + String indexName = ""; + if (rowParams.getFirst("index_name") != null) + indexName = rowParams.getFirst("index_name"); + PreparedQueryObject query = new PreparedQueryObject(); + query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "." + + tablename + " (" + fieldName + ");"); + + ResultType result = ResultType.FAILURE; + try { + result = MusicCore.nonKeyRelatedPut(query, "eventual"); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + response.status(Status.BAD_REQUEST); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + if ( result.equals(ResultType.SUCCESS) ) { + return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build(); + } else { + return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build(); + } + } + + /** + * + * @param insObj + * @param keyspace + * @param tablename + * @return + * @throws Exception + */ + @POST + @Path("/{keyspace}/tables/{tablename}/rows") + @ApiOperation(value = "Insert Into Table", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response insertIntoTable( + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + JsonInsert insObj, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename) { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = null; + + try { + authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, + aid, "insertIntoTable"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + + Map valuesMap = insObj.getValues(); + PreparedQueryObject queryObject = new PreparedQueryObject(); + TableMetadata tableInfo = null; + try { + tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename); + if(tableInfo == null) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build(); + } + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName(); + StringBuilder fieldsString = new StringBuilder("(vector_ts,"); + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + StringBuilder valueString = new StringBuilder("(" + "?" + ","); + queryObject.addValue(vectorTs); + int counter = 0; + String primaryKey = ""; + + for (Map.Entry entry : valuesMap.entrySet()) { + fieldsString.append("" + entry.getKey()); + Object valueObj = entry.getValue(); + if (primaryKeyName.equals(entry.getKey())) { + primaryKey = entry.getValue() + ""; + primaryKey = primaryKey.replace("'", "''"); + } + DataType colType = null; + try { + colType = tableInfo.getColumn(entry.getKey()).getType(); + } catch(NullPointerException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build(); + } + + Object formattedValue = null; + try { + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + } + valueString.append("?"); + queryObject.addValue(formattedValue); + + if (counter == valuesMap.size() - 1) { + fieldsString.append(")"); + valueString.append(")"); + } else { + fieldsString.append(","); + valueString.append(","); + } + counter = counter + 1; + } + + if(primaryKey == null || primaryKey.length() <= 0) { + logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName ); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build(); + } + + queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " " + + fieldsString + " VALUES " + valueString); + + String ttl = insObj.getTtl(); + String timestamp = insObj.getTimestamp(); + + if ((ttl != null) && (timestamp != null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "both there"); + queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?"); + queryObject.addValue(Integer.parseInt(ttl)); + queryObject.addValue(Long.parseLong(timestamp)); + } + + if ((ttl != null) && (timestamp == null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there"); + queryObject.appendQueryString(" USING TTL ?"); + queryObject.addValue(Integer.parseInt(ttl)); + } + + if ((ttl == null) && (timestamp != null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there"); + queryObject.appendQueryString(" USING TIMESTAMP ?"); + queryObject.addValue(Long.parseLong(timestamp)); + } + + queryObject.appendQueryString(";"); + + ReturnType result = null; + String consistency = insObj.getConsistencyInfo().get("type"); + try { + if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) { + result = MusicCore.eventualPut(queryObject); + } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { + String lockId = insObj.getConsistencyInfo().get("lockId"); + if(lockId == null) { + logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or" + + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock " + + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); + } + result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null); + } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { + result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null); + + } + else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) { + result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null); + + } + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + + if (result==null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build(); + } + + /** + * + * @param insObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @PUT + @Path("/{keyspace}/tables/{tablename}/rows") + @ApiOperation(value = "Update Table", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateTable( + @ApiParam(value = "Major Version", + required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam(PASSWORD) String password, + JsonUpdate updateObj, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename, + @Context UriInfo info) { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap; + try { + authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, + aid, "updateTable"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + long startTime = System.currentTimeMillis(); + String operationId = UUID.randomUUID().toString();// just for infoging + // purposes. + String consistency = updateObj.getConsistencyInfo().get("type"); + logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency + + " update-" + operationId + "-------------------------"); + // obtain the field value pairs of the update + + PreparedQueryObject queryObject = new PreparedQueryObject(); + Map valuesMap = updateObj.getValues(); + + TableMetadata tableInfo; + try { + tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename); + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + if (tableInfo == null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Table information not found. Please check input for table name= " + + keyspace + "." + tablename).toMap()).build(); + } + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + StringBuilder fieldValueString = new StringBuilder("vector_ts=?,"); + queryObject.addValue(vectorTs); + int counter = 0; + for (Map.Entry entry : valuesMap.entrySet()) { + Object valueObj = entry.getValue(); + DataType colType = null; + try { + colType = tableInfo.getColumn(entry.getKey()).getType(); + } catch(NullPointerException ex) { + logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey()); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build(); + } + Object valueString = null; + try { + valueString = MusicUtil.convertToActualDataType(colType, valueObj); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + } + fieldValueString.append(entry.getKey() + "= ?"); + queryObject.addValue(valueString); + if (counter != valuesMap.size() - 1) + fieldValueString.append(","); + counter = counter + 1; + } + String ttl = updateObj.getTtl(); + String timestamp = updateObj.getTimestamp(); + + queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " "); + if ((ttl != null) && (timestamp != null)) { + + logger.info("both there"); + queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?"); + queryObject.addValue(Integer.parseInt(ttl)); + queryObject.addValue(Long.parseLong(timestamp)); + } + + if ((ttl != null) && (timestamp == null)) { + logger.info("ONLY TTL there"); + queryObject.appendQueryString(" USING TTL ?"); + queryObject.addValue(Integer.parseInt(ttl)); + } + + if ((ttl == null) && (timestamp != null)) { + logger.info("ONLY timestamp there"); + queryObject.appendQueryString(" USING TIMESTAMP ?"); + queryObject.addValue(Long.parseLong(timestamp)); + } + // get the row specifier + RowIdentifier rowId = null; + try { + rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject); + if(rowId == null || rowId.primarKeyValue.isEmpty()) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build(); + } + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + + queryObject.appendQueryString( + " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";"); + + // get the conditional, if any + Condition conditionInfo; + if (updateObj.getConditions() == null) + conditionInfo = null; + else {// to avoid parsing repeatedly, just send the select query to + // obtain row + PreparedQueryObject selectQuery = new PreparedQueryObject(); + selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE " + + rowId.rowIdString + ";"); + selectQuery.addValue(rowId.primarKeyValue); + conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery); + } + + ReturnType operationResult = null; + long jsonParseCompletionTime = System.currentTimeMillis(); + + if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) + operationResult = MusicCore.eventualPut(queryObject); + else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { + String lockId = updateObj.getConsistencyInfo().get("lockId"); + if(lockId == null) { + logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or" + + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock " + + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); + } + operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue, + queryObject, lockId, conditionInfo); + } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) { + // this function is mainly for the benchmarks + try { + operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, + rowId.primarKeyValue, queryObject, conditionInfo); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { + try { + operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue, + queryObject, conditionInfo); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + } + long actualUpdateCompletionTime = System.currentTimeMillis(); + + long endTime = System.currentTimeMillis(); + String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId + + ":" + "|total operation time:" + (endTime - startTime) + + "|json parsing time:" + (jsonParseCompletionTime - startTime) + + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime) + + "|"; + + if (operationResult != null && operationResult.getTimingInfo() != null) { + String lockManagementTime = operationResult.getTimingInfo(); + timingString = timingString + lockManagementTime; + } + logger.info(EELFLoggerDelegate.applicationLogger, timingString); + + if (operationResult==null) { + logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build(); + } + if ( operationResult.getResult() == ResultType.SUCCESS ) { + return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build(); + } else { + logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build(); + } + + } + + /** + * + * @param delObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @DELETE + @Path("/{keyspace}/tables/{tablename}/rows") + @ApiOperation(value = "Delete From table", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteFromTable( + @ApiParam(value = "Major Version", + required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam(PASSWORD) String password, + JsonDelete delObj, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename, + @Context UriInfo info) { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = null; + try { + authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, + aid, "deleteFromTable"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + if(delObj == null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build(); + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder columnString = new StringBuilder(); + + int counter = 0; + ArrayList columnList = delObj.getColumns(); + if (columnList != null) { + for (String column : columnList) { + columnString.append(column); + if (counter != columnList.size() - 1) + columnString.append(","); + counter = counter + 1; + } + } + + // get the row specifier + RowIdentifier rowId = null; + try { + rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + String rowSpec = rowId.rowIdString.toString(); + + if ((columnList != null) && (!rowSpec.isEmpty())) { + queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "." + + tablename + " WHERE " + rowSpec + ";"); + } + + if ((columnList == null) && (!rowSpec.isEmpty())) { + queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE " + + rowSpec + ";"); + } + + if ((columnList != null) && (rowSpec.isEmpty())) { + queryObject.appendQueryString( + "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";"); + } + // get the conditional, if any + Condition conditionInfo; + if (delObj.getConditions() == null) + conditionInfo = null; + else {// to avoid parsing repeatedly, just send the select query to + // obtain row + PreparedQueryObject selectQuery = new PreparedQueryObject(); + selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE " + + rowId.rowIdString + ";"); + selectQuery.addValue(rowId.primarKeyValue); + conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery); + } + + String consistency = delObj.getConsistencyInfo().get("type"); + + ReturnType operationResult = null; + try { + if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) + operationResult = MusicCore.eventualPut(queryObject); + else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { + String lockId = delObj.getConsistencyInfo().get("lockId"); + if(lockId == null) { + logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or" + + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock " + + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); + } + operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue, + queryObject, lockId, conditionInfo); + } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { + operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue, + queryObject, conditionInfo); + } + else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) { + operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, + queryObject, conditionInfo); + } + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Unable to perform Delete operation. Exception from music").toMap()).build(); + } + if (operationResult==null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build(); + } + if (operationResult.getResult().equals(ResultType.SUCCESS)) { + return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build(); + } else { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build(); + } + } + + /** + * + * @param tabObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @DELETE + @Path("/{keyspace}/tables/{tablename}") + @ApiOperation(value = "Drop Table", response = String.class) + @Produces(MediaType.APPLICATION_JSON) + public Response dropTable( + @ApiParam(value = "Major Version", + required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = + MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + String consistency = "eventual";// for now this needs only eventual + // consistency + PreparedQueryObject query = new PreparedQueryObject(); + query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";"); + try { + return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build(); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + + } + + /** + * + * @param selObj + * @param keyspace + * @param tablename + * @param info + * @return + */ + @PUT + @Path("/{keyspace}/tables/{tablename}/rows/criticalget") + @ApiOperation(value = "Select Critical", response = Map.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response selectCritical( + @ApiParam(value = "Major Version", + required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam(PASSWORD) String password, + JsonInsert selObj, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + String lockId = selObj.getConsistencyInfo().get("lockId"); + + PreparedQueryObject queryObject = new PreparedQueryObject(); + + RowIdentifier rowId = null; + try { + rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + queryObject.appendQueryString( + "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";"); + + ResultSet results = null; + + String consistency = selObj.getConsistencyInfo().get("type"); + + if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { + if(lockId == null) { + logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or" + + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock " + + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); + } + results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject, + lockId); + } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { + results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject); + } + + else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) { + results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject); + } + + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build(); + } + + /** + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/{keyspace}/tables/{tablename}/rows") + @ApiOperation(value = "Select All or Select Specific", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response select( + @ApiParam(value = "Major Version", + required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam(USERID) String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Keyspace Name", + required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", + required = true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + + Map authMap = + MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select"); + if (authMap.containsKey("aid")) + authMap.remove("aid"); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + + if (info.getQueryParameters().isEmpty())// select all + queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";"); + else { + int limit = -1; // do not limit the number of results + try { + queryObject = selectSpecificQuery(VERSION, minorVersion, patchVersion, aid, ns, + userId, password, keyspace, tablename, info, limit); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + } + + try { + ResultSet results = MusicCore.get(queryObject); + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build(); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + + } + + /** + * + * @param keyspace + * @param tablename + * @param info + * @param limit + * @return + * @throws MusicServiceException + */ + public PreparedQueryObject selectSpecificQuery(String version, String minorVersion, + String patchVersion, String aid, String ns, String userId, String password, + String keyspace, String tablename, UriInfo info, int limit) + throws MusicServiceException { + + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), + queryObject).rowIdString; + + queryObject.appendQueryString( + "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString); + + if (limit != -1) { + queryObject.appendQueryString(" LIMIT " + limit); + } + + queryObject.appendQueryString(";"); + return queryObject; + + } + + /** + * + * @param keyspace + * @param tablename + * @param rowParams + * @param queryObject + * @return + * @throws MusicServiceException + */ + private RowIdentifier getRowIdentifier(String keyspace, String tablename, + MultivaluedMap rowParams, PreparedQueryObject queryObject) + throws MusicServiceException { + StringBuilder rowSpec = new StringBuilder(); + int counter = 0; + TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename); + if (tableInfo == null) { + logger.error(EELFLoggerDelegate.errorLogger, + "Table information not found. Please check input for table name= " + + keyspace + "." + tablename); + throw new MusicServiceException( + "Table information not found. Please check input for table name= " + + keyspace + "." + tablename); + } + StringBuilder primaryKey = new StringBuilder(); + for (MultivaluedMap.Entry> entry : rowParams.entrySet()) { + String keyName = entry.getKey(); + List valueList = entry.getValue(); + String indValue = valueList.get(0); + DataType colType = null; + Object formattedValue = null; + try { + colType = tableInfo.getColumn(entry.getKey()).getType(); + formattedValue = MusicUtil.convertToActualDataType(colType, indValue); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + } + primaryKey.append(indValue); + rowSpec.append(keyName + "= ?"); + queryObject.addValue(formattedValue); + if (counter != rowParams.size() - 1) + rowSpec.append(" AND "); + counter = counter + 1; + } + return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject); + } +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java new file mode 100644 index 00000000..752a538b --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java @@ -0,0 +1,113 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + +import java.util.HashMap; +/** + * @author inam + * + */ +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; +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.Consumes; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + + +import org.onap.music.response.jsonobjects.JsonResponse; +import org.onap.music.eelf.healthcheck.MusicHealthCheck; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + + + + +@Path("/v{version: [0-9]+}/service") +@Api(value="Healthcheck Api") +public class RestMusicHealthCheckAPI { + + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + + + @GET + @Path("/cs") + @ApiOperation(value = "Get Health Status", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response cassandraStatus(@Context HttpServletResponse response) { + logger.info(EELFLoggerDelegate.applicationLogger,"Replying to request for MUSIC Health Check status for Cassandra"); + + Map resultMap = new HashMap<>(); + + MusicHealthCheck cassHealthCheck = new MusicHealthCheck(); + String status = cassHealthCheck.getCassandraStatus(); + if(status.equals("ACTIVE")) { + resultMap.put("ACTIVE", "Cassandra Running and Listening to requests"); + return Response.status(Status.OK).entity(resultMap).build(); + }else { + resultMap.put("INACTIVE", "Cassandra Service is not responding"); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + + + } + + @GET + @Path("/zk") + @ApiOperation(value = "Get Health Status", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response ZKStatus(@Context HttpServletResponse response) { + logger.info(EELFLoggerDelegate.applicationLogger,"Replying to request for MUSIC Health Check status for Zookeeper"); + Map resultMap = new HashMap<>(); + MusicHealthCheck ZKHealthCheck = new MusicHealthCheck(); + String status = ZKHealthCheck.getZookeeperStatus(); + if(status.equals("ACTIVE")) { + resultMap.put("ACTIVE", "Zookeeper is Active and Running"); + return Response.status(Status.OK).entity(resultMap).build(); + }else { + resultMap.put("INACTIVE", "Zookeeper is not responding"); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + } + + + + + + + +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java new file mode 100644 index 00000000..22112ddf --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java @@ -0,0 +1,423 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +import org.onap.music.datastore.jsonobjects.JsonLeasedLock; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.lockingservice.MusicLockState; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; +import org.onap.music.response.jsonobjects.JsonResponse; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; + + +@Path("/v2/locks/") +@Api(value="Lock Api") +public class RestMusicLocksAPI { + + private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class); + private static final String XMINORVERSION = "X-minorVersion"; + private static final String XPATCHVERSION = "X-patchVersion"; + private static final String VERSION = "v2"; + + /** + * Puts the requesting process in the q for this lock. The corresponding + * node will be created in zookeeper if it did not already exist + * + * @param lockName + * @return + * @throws Exception + */ + @POST + @Path("/create/{lockname}") + @ApiOperation(value = "Create Lock", + notes = "Puts the requesting process in the q for this lock." + + " The corresponding node will be created in zookeeper if it did not already exist." + + " Lock Name is the \"key\" of the form keyspaceName.tableName.rowId", + response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response createLockReference( + @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockName); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "createLockReference"); + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + return response.status(Status.UNAUTHORIZED).entity(resultMap).build(); + } + ResultType status = ResultType.SUCCESS; + String lockId = MusicCore.createLockReference(lockName); + + if (lockId == null) { + status = ResultType.FAILURE; + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError("Lock Id is null").toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(status).setLock(lockId).toMap()).build(); + } + + /** + * + * Checks if the node is in the top of the queue and hence acquires the lock + * + * @param lockId + * @return + * @throws Exception + */ + @GET + @Path("/acquire/{lockreference}") + @ApiOperation(value = "Aquire Lock", + notes = "Checks if the node is in the top of the queue and hence acquires the lock", + response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response accquireLock( + @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockId); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "accquireLock"); + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + try { + String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$')); + ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId); + if ( lockStatus.getResult().equals(ResultType.SUCCESS)) { + response.status(Status.OK); + } else { + response.status(Status.BAD_REQUEST); + } + return response.entity(new JsonResponse(lockStatus.getResult()).setLock(lockId).setMessage(lockStatus.getMessage()).toMap()).build(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap()).build(); + } + } + + + + + @POST + @Path("/acquire-with-lease/{lockreference}") + @ApiOperation(value = "Aquire Lock with Lease", response = Map.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response accquireLockWithLease(JsonLeasedLock lockObj, + @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockId); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "accquireLockWithLease"); + + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$')); + ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, lockObj.getLeasePeriod()); + if ( lockLeaseStatus.getResult().equals(ResultType.SUCCESS)) { + response.status(Status.OK); + } else { + response.status(Status.BAD_REQUEST); + } + return response.entity(new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName) + .setMessage(lockLeaseStatus.getMessage()) + .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap()).build(); + } + + + @GET + @Path("/enquire/{lockname}") + @ApiOperation(value = "Get Lock Holder", + notes = "Gets the current Lock Holder", + response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response currentLockHolder( + @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockName); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "currentLockHolder"); + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String who = MusicCore.whoseTurnIsIt(lockName); + ResultType status = ResultType.SUCCESS; + String error = ""; + if ( who == null ) { + status = ResultType.FAILURE; + error = "There was a problem getting the lock holder"; + logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build(); + } + + @GET + @Path("/{lockname}") + @ApiOperation(value = "Lock State", + notes = "Returns current Lock State and Holder.", + response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response currentLockState( + @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockName); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "currentLockState"); + + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + MusicLockState mls = MusicCore.getMusicLockState(lockName); + Map returnMap = null; + JsonResponse jsonResponse = new JsonResponse(ResultType.FAILURE).setLock(lockName); + if(mls == null) { + jsonResponse.setError(""); + jsonResponse.setMessage("No lock object created yet.."); + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(jsonResponse.toMap()).build(); + } else { + jsonResponse.setStatus(ResultType.SUCCESS); + jsonResponse.setLockStatus(mls.getLockStatus()); + jsonResponse.setLockHolder(mls.getLockHolder()); + return response.status(Status.OK).entity(jsonResponse.toMap()).build(); + } + } + + /** + * + * deletes the process from the zk queue + * + * @param lockId + * @throws Exception + */ + @DELETE + @Path("/release/{lockreference}") + @ApiOperation(value = "Release Lock", + notes = "deletes the process from the zk queue", + response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response unLock(@PathParam("lockreference") String lockId, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockId); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "unLock"); + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + boolean voluntaryRelease = true; + MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease); + if(mls.getErrorMessage() != null) { + resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage()); + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + Map returnMap = null; + if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) { + returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId) + .setLockStatus(mls.getLockStatus()).toMap(); + response.status(Status.OK); + } + if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId) + .setLockStatus(mls.getLockStatus()).toMap(); + response.status(Status.BAD_REQUEST); + } + return response.entity(returnMap).build(); + } + + /** + * + * @param lockName + * @throws Exception + */ + @DELETE + @Path("/delete/{lockname}") + @ApiOperation(value = "Delete Lock", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteLock(@PathParam("lockname") String lockName, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", + required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "userId", + required = true) @HeaderParam("userId") String userId, + @ApiParam(value = "Password", + required = true) @HeaderParam("password") String password) throws Exception{ + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map resultMap = MusicCore.validateLock(lockName); + if (resultMap.containsKey("Exception")) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + String keyspaceName = (String) resultMap.get("keyspace"); + resultMap.remove("keyspace"); + resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, + "deleteLock"); + if (resultMap.containsKey("aid")) + resultMap.remove("aid"); + if (!resultMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + try{ + MusicCore.deleteLock(lockName); + }catch (Exception e) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).toMap()).build(); + } + +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java new file mode 100755 index 00000000..e08adaf7 --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java @@ -0,0 +1,251 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + + + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.onap.music.datastore.jsonobjects.JsonDelete; +import org.onap.music.datastore.jsonobjects.JsonInsert; +import org.onap.music.datastore.jsonobjects.JsonTable; +import org.onap.music.datastore.jsonobjects.JsonUpdate; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicCore; + +import org.onap.music.datastore.PreparedQueryObject; +import com.datastax.driver.core.ResultSet; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; + +//@Path("/v{version: [0-9]+}/priorityq/") +@Path("/priorityq/") +@Api(value="Q Api") +public class RestMusicQAPI { + + private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicDataAPI.class); + + + /** + * + * @param tableObj + * @param keyspace + * @param tablename + * @throws Exception + */ + + @POST + @Path("/keyspaces/{keyspace}/{qname}") + @ApiOperation(value = "", response = Void.class) + @Consumes(MediaType.APPLICATION_JSON) + public Response createQ( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, + @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonTable tableObj, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ + return new RestMusicDataAPI().createTable(version,minorVersion,patchVersion,aid, ns, userId, password, tableObj, keyspace, tablename); + } + + /** + * + * @param insObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @POST + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "", response = Void.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response insertIntoQ( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonInsert insObj, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ + return new RestMusicDataAPI().insertIntoTable(version,minorVersion,patchVersion,aid, ns, userId, password, insObj, keyspace, tablename); + } + + /** + * + * @param updateObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @PUT + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateQ( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonUpdate updateObj, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception{ + return new RestMusicDataAPI().updateTable(version,minorVersion,patchVersion,aid, ns, userId, password, updateObj, keyspace, tablename, info); + } + + /** + * + * @param delObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @DELETE + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteFromQ( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, + @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonDelete delObj, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception{ + return new RestMusicDataAPI().deleteFromTable(version,minorVersion,patchVersion,aid, ns, userId, password, delObj, keyspace, tablename, info); + } + + /** + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/peek") + @ApiOperation(value = "", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Map> peek( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, + @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception{ + int limit =1; //peek must return just the top row + PreparedQueryObject query = new RestMusicDataAPI().selectSpecificQuery(version,minorVersion,patchVersion,aid, ns, userId, password,keyspace,tablename,info,limit); + ResultSet results = MusicCore.get(query); + return MusicCore.marshallResults(results); + + } + + /** + * + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/filter") + @ApiOperation(value = "", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Map> filter( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, + @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, + @Context UriInfo info) throws Exception{ + int limit =-1; + PreparedQueryObject query = new RestMusicDataAPI().selectSpecificQuery(version,minorVersion,patchVersion,aid, ns, userId, password,keyspace,tablename,info,limit); + ResultSet results = MusicCore.get(query); + return MusicCore.marshallResults(results); + } + + /** + * + * @param tabObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @DELETE + @ApiOperation(value = "", response = Void.class) + @Path("/keyspaces/{keyspace}/{qname}") + public Response dropQ( + @ApiParam(value="Major Version",required=true) @PathParam("version") String version, + @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, + @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, + @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, + @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonTable tabObj, + @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, + @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ + return new RestMusicDataAPI().dropTable(version,minorVersion,patchVersion,aid, ns, userId, password, keyspace, tablename); + } +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java new file mode 100644 index 00000000..287fa176 --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java @@ -0,0 +1,67 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; +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 org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicUtil; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + + +@Path("/v{version: [0-9]+}/test") +@Api(value="Test Api") +public class RestMusicTestAPI { + + @SuppressWarnings("unused") + private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicTestAPI.class); + + /** + * Returns a test JSON. This will confirm that REST is working. + * @return + */ + @GET + @ApiOperation(value = "Get Test", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Map> simpleTests( + @Context HttpServletResponse response) { + response.addHeader("X-latestVersion",MusicUtil.getVersion()); + Map> testMap = new HashMap<>(); + for(int i=0; i < 3; i++){ + HashMap innerMap = new HashMap<>(); + innerMap.put(i+"", i+1+""); + innerMap.put(i+1+"", i+2+""); + testMap.put(i+"", innerMap); + } + return testMap; + } +} diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java new file mode 100644 index 00000000..a5f2ac49 --- /dev/null +++ b/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.rest; + +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; +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 org.onap.music.response.jsonobjects.JsonResponse; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; + + +@Path("/v{version: [0-9]+}/version") +@Api(value="Version Api") +public class RestMusicVersionAPI { + + private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicVersionAPI.class); + + /** + * Get the version of MUSIC + * @return + */ + @GET + @ApiOperation(value = "Get Version", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Map version(@Context HttpServletResponse response) { + logger.info("Replying to request for MUSIC version with MUSIC:" + MusicUtil.getVersion()); + response.addHeader("X-latestVersion",MusicUtil.getVersion()); + return new JsonResponse(ResultType.SUCCESS).setMusicVersion("MUSIC:" + MusicUtil.getVersion()).toMap(); + } +} \ No newline at end of file diff --git a/jar/src/main/resources/LICENSE.txt b/jar/src/main/resources/LICENSE.txt new file mode 100644 index 00000000..cc6cdea5 --- /dev/null +++ b/jar/src/main/resources/LICENSE.txt @@ -0,0 +1,24 @@ + +The following license applies to all files in this and sub-directories. Licenses +are included in individual source files where appropriate, and if it differs +from this text, it supersedes this. Any file that does not have license text +defaults to being covered by this text; not all files support the addition of +licenses. +# +# ------------------------------------------------------------------------- +# Copyright (c) 2017 AT&T Intellectual Property +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------- +# \ No newline at end of file diff --git a/jar/src/main/resources/Resources.properties b/jar/src/main/resources/Resources.properties new file mode 100644 index 00000000..72269cb8 --- /dev/null +++ b/jar/src/main/resources/Resources.properties @@ -0,0 +1,50 @@ +#============LICENSE_START========================================== +#org.onap.music +#=================================================================== +# Copyright (c) 2017 AT&T Intellectual Property +#=================================================================== +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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============================================= +#==================================================================== +#Resource key=Error Code|Message text|Resolution text |Description text +LOADING_DEFAULT_LOG_CONFIGURATION=\ + EELF0001I|\ + Loading default logging configuration from system resource file "{0}"|\ + No external logging configurations were defined or found, So verify the default logging configuration from system resource file (../logback.xml). |\ + Loading default logging configuration from system resource file +LOADING_LOG_CONFIGURATION=EELF0002I|\ + Loading logging configuration from file "{0}"|\ + Verify the correct logging configuration file is loaded. |\ + Loading logging configuration for specific file +LOGGING_ALREADY_INITIALIZED=\ + EELF0003W|\ + Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.|\ + Verify the container logging definitions to ensure they represent your desired logging configuration. |\ + Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration. +NO_LOG_CONFIGURATION=\ + EELF0004E|\ + No log configuration could be found or defaulted!|\ + No external and default logging configuration file. |\ + No log configuration could be found or defaulted! +SEARCHING_LOG_CONFIGURATION=\ + EELF0005I|\ + Searching path "{0}" for log configuration file "{1}"|\ + Verify the correct Path({user.home};etc;../etc) and filename (eelf.logging.file).|\ + Searching path for specific log configuration file. +UNSUPPORTED_LOGGING_FRAMEWORK=\ + EELF0006E|\ + An unsupported logging framework is bound to SLF4J. |\ + Verify your logging frameworks.|\ + An unsupported logging framework is bound to SLF4J. + diff --git a/jar/src/main/resources/cache.ccf b/jar/src/main/resources/cache.ccf new file mode 100644 index 00000000..acc6831c --- /dev/null +++ b/jar/src/main/resources/cache.ccf @@ -0,0 +1,56 @@ +# DEFAULT CACHE REGION +jcs.default= +jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.default.cacheattributes.MaxObjects=1000 +jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.default.cacheattributes.UseMemoryShrinker=false +jcs.default.cacheattributes.MaxMemoryIdleTime=3600 +jcs.default.cacheattributes.ShrinkerInterval=60 +jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.default.elementattributes.IsEternal=false +jcs.default.elementattributes.MaxLife=21600 +jcs.default.elementattributes.IdleTime=1800 +jcs.default.elementattributes.IsSpool=true +jcs.default.elementattributes.IsRemote=true +jcs.default.elementattributes.IsLateral=true + +# PRE-DEFINED CACHE REGIONS +jcs.region.musicCache= +jcs.region.musicCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.musicCache.cacheattributes.MaxObjects=1000 +jcs.region.musicCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.musicCache.cacheattributes.UseMemoryShrinker=false +jcs.region.musicCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.musicCache.cacheattributes.ShrinkerInterval=60 +jcs.region.musicCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.musicCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.musicCache.elementattributes.IsEternal=false + + +# PRE-DEFINED CACHE REGIONS +jcs.region.aafCache= +jcs.region.aafCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.aafCache.cacheattributes.MaxObjects=1000 +jcs.region.aafCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.aafCache.cacheattributes.UseMemoryShrinker=false +jcs.region.aafCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.aafCache.cacheattributes.ShrinkerInterval=60 +jcs.region.aafCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.aafCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.aafCache.elementattributes.IsEternal=false + +# PRE-DEFINED CACHE REGIONS +jcs.region.appNameCache= +jcs.region.appNameCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.appNameCache.cacheattributes.MaxObjects=1000 +jcs.region.appNameCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.appNameCache.cacheattributes.UseMemoryShrinker=false +jcs.region.appNameCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.appNameCache.cacheattributes.ShrinkerInterval=60 +jcs.region.appNameCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.appNameCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.appNameCache.elementattributes.IsEternal=false + + + + diff --git a/jar/src/main/resources/logback.xml b/jar/src/main/resources/logback.xml new file mode 100644 index 00000000..fe7f54ae --- /dev/null +++ b/jar/src/main/resources/logback.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + ${logDirectory}/${generalLogName}.log + + ${logDirectory}/${generalLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${applicationLoggerPattern} + + + + + 256 + true + + + + + + ${logDirectory}/${securityLogName}.log + + ${logDirectory}/${securityLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + 256 + 0 + + + + + + + + + + ${logDirectory}/${auditLogName}.log + + ${logDirectory}/${auditLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${auditLoggerPattern} + + + + 256 + + + + + ${logDirectory}/${metricsLogName}.log + + ${logDirectory}/${metricsLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + + ${metricsLoggerPattern} + + + + + + 256 + + + + + ${logDirectory}/${errorLogName}.log + + ${logDirectory}/${errorLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${errorLoggerPattern} + + + + + 256 + + + + + ${debugLogDirectory}/${debugLogName}.log + + ${debugLogDirectory}/${debugLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${debugLoggerPattern} + + + + + 256 + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jar/src/main/resources/project.properties b/jar/src/main/resources/project.properties new file mode 100644 index 00000000..199afa33 --- /dev/null +++ b/jar/src/main/resources/project.properties @@ -0,0 +1,4 @@ +version=${project.version} +artifactId=${project.artifactId} +music.properties=/opt/app/music/etc/music.properties + diff --git a/jar/src/main/webapp/WEB-INF/classes/LICENSE.txt b/jar/src/main/webapp/WEB-INF/classes/LICENSE.txt new file mode 100644 index 00000000..cc6cdea5 --- /dev/null +++ b/jar/src/main/webapp/WEB-INF/classes/LICENSE.txt @@ -0,0 +1,24 @@ + +The following license applies to all files in this and sub-directories. Licenses +are included in individual source files where appropriate, and if it differs +from this text, it supersedes this. Any file that does not have license text +defaults to being covered by this text; not all files support the addition of +licenses. +# +# ------------------------------------------------------------------------- +# Copyright (c) 2017 AT&T Intellectual Property +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------- +# \ No newline at end of file diff --git a/jar/src/main/webapp/WEB-INF/classes/Resources.properties b/jar/src/main/webapp/WEB-INF/classes/Resources.properties new file mode 100644 index 00000000..72269cb8 --- /dev/null +++ b/jar/src/main/webapp/WEB-INF/classes/Resources.properties @@ -0,0 +1,50 @@ +#============LICENSE_START========================================== +#org.onap.music +#=================================================================== +# Copyright (c) 2017 AT&T Intellectual Property +#=================================================================== +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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============================================= +#==================================================================== +#Resource key=Error Code|Message text|Resolution text |Description text +LOADING_DEFAULT_LOG_CONFIGURATION=\ + EELF0001I|\ + Loading default logging configuration from system resource file "{0}"|\ + No external logging configurations were defined or found, So verify the default logging configuration from system resource file (../logback.xml). |\ + Loading default logging configuration from system resource file +LOADING_LOG_CONFIGURATION=EELF0002I|\ + Loading logging configuration from file "{0}"|\ + Verify the correct logging configuration file is loaded. |\ + Loading logging configuration for specific file +LOGGING_ALREADY_INITIALIZED=\ + EELF0003W|\ + Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.|\ + Verify the container logging definitions to ensure they represent your desired logging configuration. |\ + Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration. +NO_LOG_CONFIGURATION=\ + EELF0004E|\ + No log configuration could be found or defaulted!|\ + No external and default logging configuration file. |\ + No log configuration could be found or defaulted! +SEARCHING_LOG_CONFIGURATION=\ + EELF0005I|\ + Searching path "{0}" for log configuration file "{1}"|\ + Verify the correct Path({user.home};etc;../etc) and filename (eelf.logging.file).|\ + Searching path for specific log configuration file. +UNSUPPORTED_LOGGING_FRAMEWORK=\ + EELF0006E|\ + An unsupported logging framework is bound to SLF4J. |\ + Verify your logging frameworks.|\ + An unsupported logging framework is bound to SLF4J. + diff --git a/jar/src/main/webapp/WEB-INF/classes/cache.ccf b/jar/src/main/webapp/WEB-INF/classes/cache.ccf new file mode 100644 index 00000000..acc6831c --- /dev/null +++ b/jar/src/main/webapp/WEB-INF/classes/cache.ccf @@ -0,0 +1,56 @@ +# DEFAULT CACHE REGION +jcs.default= +jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.default.cacheattributes.MaxObjects=1000 +jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.default.cacheattributes.UseMemoryShrinker=false +jcs.default.cacheattributes.MaxMemoryIdleTime=3600 +jcs.default.cacheattributes.ShrinkerInterval=60 +jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.default.elementattributes.IsEternal=false +jcs.default.elementattributes.MaxLife=21600 +jcs.default.elementattributes.IdleTime=1800 +jcs.default.elementattributes.IsSpool=true +jcs.default.elementattributes.IsRemote=true +jcs.default.elementattributes.IsLateral=true + +# PRE-DEFINED CACHE REGIONS +jcs.region.musicCache= +jcs.region.musicCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.musicCache.cacheattributes.MaxObjects=1000 +jcs.region.musicCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.musicCache.cacheattributes.UseMemoryShrinker=false +jcs.region.musicCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.musicCache.cacheattributes.ShrinkerInterval=60 +jcs.region.musicCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.musicCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.musicCache.elementattributes.IsEternal=false + + +# PRE-DEFINED CACHE REGIONS +jcs.region.aafCache= +jcs.region.aafCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.aafCache.cacheattributes.MaxObjects=1000 +jcs.region.aafCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.aafCache.cacheattributes.UseMemoryShrinker=false +jcs.region.aafCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.aafCache.cacheattributes.ShrinkerInterval=60 +jcs.region.aafCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.aafCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.aafCache.elementattributes.IsEternal=false + +# PRE-DEFINED CACHE REGIONS +jcs.region.appNameCache= +jcs.region.appNameCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes +jcs.region.appNameCache.cacheattributes.MaxObjects=1000 +jcs.region.appNameCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache +jcs.region.appNameCache.cacheattributes.UseMemoryShrinker=false +jcs.region.appNameCache.cacheattributes.MaxMemoryIdleTime=3600 +jcs.region.appNameCache.cacheattributes.ShrinkerInterval=60 +jcs.region.appNameCache.cacheattributes.MaxSpoolPerRun=500 +jcs.region.appNameCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes +jcs.region.appNameCache.elementattributes.IsEternal=false + + + + diff --git a/jar/src/main/webapp/WEB-INF/classes/logback.xml b/jar/src/main/webapp/WEB-INF/classes/logback.xml new file mode 100644 index 00000000..fe7f54ae --- /dev/null +++ b/jar/src/main/webapp/WEB-INF/classes/logback.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + ${logDirectory}/${generalLogName}.log + + ${logDirectory}/${generalLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${applicationLoggerPattern} + + + + + 256 + true + + + + + + ${logDirectory}/${securityLogName}.log + + ${logDirectory}/${securityLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + 256 + 0 + + + + + + + + + + ${logDirectory}/${auditLogName}.log + + ${logDirectory}/${auditLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${auditLoggerPattern} + + + + 256 + + + + + ${logDirectory}/${metricsLogName}.log + + ${logDirectory}/${metricsLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + + ${metricsLoggerPattern} + + + + + + 256 + + + + + ${logDirectory}/${errorLogName}.log + + ${logDirectory}/${errorLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${errorLoggerPattern} + + + + + 256 + + + + + ${debugLogDirectory}/${debugLogName}.log + + ${debugLogDirectory}/${debugLogName}.%i.log.zip + + 1 + 9 + + + 5MB + + + ${debugLoggerPattern} + + + + + 256 + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/MusicDataStore$1.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/MusicDataStore$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5590b259d243683928f85725f8400871a127481f GIT binary patch literal 1145 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 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/PreparedQueryObject.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/PreparedQueryObject.class new file mode 100644 index 0000000000000000000000000000000000000000..9ddc7a03a4f72925f468b0b9da5f789e0667c95e GIT binary patch literal 1269 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 QYuX9vKJJ3igCFVPKbxyL761SM literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonInsert.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonInsert.class new file mode 100644 index 0000000000000000000000000000000000000000..bc835fb3bb7e919c0d16f13d0dc14c107bc958e2 GIT binary patch literal 3605 zcmb7H{ae#k6h3K71EsFQ`~Wv*b(`{~nQnee91fWuXaN;uLpL>qOAVw+m)y2?|ImJ% zd!9|7&F9%4us>?sdv4MaLYVSHZ*J~6_nh~<=Ogg)(ffTOQo^v<6 zefo<6V}JRpwrk62I368a(I_|Ttpk0jV!L9YQCk!KGKbE*c$Vp`n7+;L(P2(Lx531@ zisx4i&o%2ttr6Ikv2IE;ke)A$&A@X#64(1Pyj>RbHazFf_ z;W8U5c3{KvjO%(*u>i+o727j{mRYR|-!Qi&#!TIwMbu48xDI^-Zbj%~Fbptw%AKY!V*&(9 zW~=srEkH`K1*GUt$NmWon;RW_d|e|A+rwc|qgUn@Z@jQXoreg|nl%qibi6CQ-j-s< z_s#ZVL)IG-6(`IZ>v;{yrJyDwtb}2ON)R7dlBTtV5vaOAjn?Nn1sJ#*6_&h)Z;6{W z&ydpg1USpKG&=FN28Q`QzNJiS)W0qQRI>^|qmwKt*SOIYJCe)4+;mLLXOt698jUVh zEU#v4U>*toMa?lbffd(c<02ePRTuLrnisYRI4(?coIP~6T(9M3@eR_7RHhR}Iz)$y zbcC0WXsAdZ@a{uij`HgW4QVveAuE+sjgEEXaWX^3*@*;!MQTt}qxU6Br*L4JlAS5L4E*|6Fl!#Vg@d!#@;k$@d? zB&qv;oDO1-EMh$gZ39mY&z|wur2VR{e~dM+4o}f1*cU?u`jk%LO{3E^3a2|S|3;aY ziOc6wE{{Q{A121}n+RwUk27=@D_fg})eN5b@rmClvyG*oPA^aoT~sEIgjx|E#>xb7 z7)C0xY!ca(wIlA zaCd<&26PGUm+4EKFoE~*>=Kw`m|5avh6LUM%-egw3@hXcbi-ul(b&gfJM=w;-PKfT zdy)ZEQUXXM{VQ0TPN%jfN$ovgzP|@%u6m~SS}L-964}GIBl{ZGX3~-6lgL(q?9m>` zxDOfG_0**6Nn}q_kcGt0s-(vn<{MbOk)CfoneR0qwDv$4PLO!MkJ2&N4&C0w?p7-H z-X!+wyJNo%t8?ktdz09=fZf>xdpO@asYV~8WJti zfRmPjISw};;a8z~+=RnuI`yKB7HCn~9YKTMM}t0q95d`+7|H6iq|>ra4@uK$B?sxZ dkY?yRmHA=pR`El-KcdG0eNR8Y(vwH@^gmVZ$#hgzKzaVES#=&rYKBc;2W4mBg$3zRRcGI~!R8%Q#>#Hzr1 zB6`rN?W?X9Hi=;5-stVtKW*kD&kj$dZ#TDLqji)-;!p+3_MaVpA1NzixblsTRcxj9 z`4`uYNI1Ew_j4y%%5h*?ogcbXv z0-E)XiMpQAqUVK4tbFfCSP@$jN$(^!+N8n6-q+ZFBm4VIEC<$=cDESD+;V%ACn#! zCV~Vc%;oU9fjpA|s1iY7&Y6@0R)Xc%aiMJ@f>j^sLWu;c!kSR|h&dh;b8EQ}GACl8 zGs1Vjcft9Cg7*I;gKaY7FN#%rMRs$Qc_U}bRcL`IOv%l{%w1*`dNtseei-;XfIlA7 z2G=htW3)BvLtTgJHcI5`u?S)$a31^*FNgg!KOi-4haETJ7$uvV1v3{%SEsX~35yq^ zY+BU!O%nO?OT}$7moNG?9wQDd{a59o;%fYE&}G+-WQuek13XRQ)>EsZ_W`^Vl~s1zMmRIH6N%k;;X~FRAo% z;cE6@(agQ1N)h|!80-boSDEzNFu9f%0h`>0=}Xcp!)nM# ze+b}@CIIJB<3jp)EWBzF-s1`Ia+KbIwY%eyRg1{J0m U;X~%`(?(1W=u_x?_5*GH4YG6lV*mgE literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonLeasedLock.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonLeasedLock.class new file mode 100644 index 0000000000000000000000000000000000000000..498e3296de03b87a079c898fefd36e1e4dd5ddcc GIT binary patch literal 1172 zcmbVKTTc@~6#k|cYTM;vxhUScRnfK>Hjx+~G$h2tM6x0Q;la1*c37uuXPVh9$d5A7 z1Y+WYKfoVlJhLqnD~7~u=FH65Ip_P%ch1jW-+usD#gh{9cw9sdb!!?0Gz(Z}C`W?F zVoMmQ+YD@jp{R5s_m6i?#8B}&{E&MQSE09)7^%V+3==PaUjl%+kKVDuGo{YB&>BsHSk1gMNkc2YA-(GVJM8p zM}NHao_tHxqb;L*!X(F(K7YugK2dj4442%gEK~6qYOcOvOLvIP=18r%dgC&^D!bdh zn`pNs+*DdANNI;sUI?A9{~c)&N;|r50`Xc}L1+JzW5xD{p>|b$R9DeP4m(h8i#RZ{ zXXRm-?^+4meQn%y654J=N;5q71KsuZsVBmG>PB9N2M3hnf`Dmr-h_&JHdIiGn6M^g z>f2QZN*}2#O&@bmLfOFt3J$KJ$guh!-Dj8?4dc6XKv1Jm&J#k07G)<33qUpx5)Wmv z4&6N3ne{fmfqkVz29snbQfC!Yban<0FpU|yFvNqcqvh)#lvwDimh)XFgqCv!)Y08CRQ3F1ft1Zx$v4~se%+AU>LH5fS zvz4ov-KK1JaQB>9W`NmTK1Ft%*;8V+`VVGSaz?TDQVLaA0T$`*(jozBxF6#I9@3ko H4|wz&*O&Ol literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonOnboard.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonOnboard.class new file mode 100644 index 0000000000000000000000000000000000000000..8785a467c4187545a3153d5e3a0525a6a4440691 GIT binary patch literal 1855 zcmb7@+foxj5QcjLIgms}L=;af9s>gF`7BmSON|v34{+h#kPKm9Gqbg`5q&GI(z416 zAHavQ{Cg8jTsK8|vE4JXJ>B2T-}Cd=_a8)bmF^d*K-b48PdC`yWOIwnZ8mrEbT?1; z9LkFz(4s9Jny7Dy_rmjqZh3E_Q0dlPhjJY&!&=j!LLjW&F(HOoWvkW44vh$fS?-?F zDq6<0GPmZ?=tI*)vIBLc<%>>xU50PPx*w-E4dJheQ1QICI2vs#>(G_D30t1gBJkQB zs~TQYM8ZZUl-`y#+N^KMMr6Hb7{Ao(MubhEm0B`d`2#gsnM>oJe%;ZLYRffc70On% zHj#*w(Wp9CSH`nDqScb2C;ET9YM`Fu6#hzR0vSdhQ7rpj_#K>LvKj=wYQ!nre)W#HHMJg z)dC`FUA-o1)`f8HKye5qeBbP_Bx`&^TuUhmJ95F@5WdBM3&_>mUwmUaVM9JvEa&)u z7)#tZ4$ba$pDfzIHq4sRHbND!AP#wt|uH>$_Otb9;D#;H`YktEsWy~$>f%}pm8 zNs?U$*^MD&eC13wn@TpCB)hXW*=b}ulTJ38BwGgAgCS(xEKGJbl`NYid$>2*Ib=JZ zPL@rQJptL%A!OXXOm-oaESDs!4o&nh%$X&&>7>3F#$-U{$u4Z-8r6bnQ1Xm_?WX literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonSelect.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/JsonSelect.class new file mode 100644 index 0000000000000000000000000000000000000000..edf472f873fa1abe14192c85eca852c071bcea21 GIT binary patch literal 1603 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 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/NameSpace.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/datastore/jsonobjects/NameSpace.class new file mode 100644 index 0000000000000000000000000000000000000000..b388220bb077bcae6dfe7daf4f6ab43c8f9a01ae GIT binary patch literal 1024 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 UnvWJ1r>*?AgeyMGIUhdqKN%J_TL1t6 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/AppMessages.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/AppMessages.class new file mode 100644 index 0000000000000000000000000000000000000000..b0b4c81cc77e759b49da14c9572bedb36ee0b786 GIT binary patch literal 6182 zcmd5=d3+ny5uWGxc$PQu<~f%`jwJ`!4n$6zgoK1ckrg7MNI{ZKOv3z|g-Zw3!rFTo2nU(By;{GuCtMFsLyifCH=FRn9 zc>c8~p8$U;pY;5 zA>o%q{7S;L5`Hb=Hxhm;;djKnB;h&}zM+w(UctygWX!U0aH%NF@!e1o( zm59GdxKYC2CHzCeKZ*F4gqtM%Tf%=Nyhg--CEP3pNFi_~Y9!nu#Uv?eX;mlTR>FD- zw@J|;g_NR^2%m)8rD&2ulVUOvQzYCWMY9yT6jO;%67H0uMT%*(nl9lkDP~A9Q;Jzc zv`V;JirG>eCB+;f=1SNn#XKqI)5?%=j}%8sv4BKF<4NpY+cZM15a zaK98CQY@j>aS|So;&>^R(#kL4K`A<=SSH1CBDxyH3IR=B|KEK&26wCpuuvS1zpeMO86itSMfn+!q z4aMWJxBwN5MWew`Fd6O*C;KX7^Tt>r*%J-)2EviR`bbE?^k5*72t>Q%0g|tZ3up+( zDto4dwuXW|q&XZ-BG#qacqa=DUXxQtmzCTtlgHA zDGm!*K4A^jJ*31Ul~qDOBd>#Y8eLM69p-M+pEa?P5=93K3ODF1&}|h`P9|T>*g4F7 z+A5lvYyl(XSOq&T|tEbtqRFS~rnUc_+fjID32vyX2&-4H;@=-Sg{GO1cIgqBqYYnpi1T30V5(E=CRZ zixV_BC{}CmK6t+d57XxZ^!Xrt-UaX0;63n=2JeN3u+g^RIA7M;89H0Qw9T190jHx8 z&bb#ZPDO)m2RE`O8d1E+y0&C3vtSviK`XV>F!T9rCS}r~G*XV0wsOUcnJpM*F73A+ zW6(0wmQz4?;0X<`fGbA~E+d0;1Eu01ZK-JBk!;wh6!v`@EibOvqMMJA44O z(JmB?oLw|9Z<(w+ndgo58c%2pl33+-(cl`7n&lLSC0vKb`GZ&xM%59_1G*73@x7Bv zJEoD!mI~;S01$AjG1m7(g+^^%>#^0vNe;&h*W934sKy%KCu0!a@qJm1Sf!RID~`1bZ|0(rH;1#f znWmyOiVoJ7=fETqMXs`Mw}%KGwWav zUxlFU*WKg1`OiBx7900r-m&r~wF3Hye%af1;DIO-hgTR&XmFcH zHT%4{k~6HPY6do7rDB7j?+$v&AvmnnC_IHq4k;{^P-$@ch=G-^@AEO#_!P;cjjW9W z0d<TrG_uRHS)S(5VRfp(ogQh9^c>?X z+umtedCPJ8+!#~W)n;_Z)!q@&k!HNhqmUb90mTPnKH{Q#utL$sGYw)eXlO4q-dIY5 zyFI$Og%-W>F2m4ZpJ(4{>WUUOgoUD6bbF&_O5tW%Ol4H?V-ZRMyU6QpR5V zG42+;ZC83gWbsm%1PzGuI+n~i2=yJuAAp9A*4hIgJ6h`wKx0R1 z{Q>Ziq^or{`T=<;RabFEz_a6S_8q$Up>a2V zV%*IQhi-m&+|8dHce6Zn^CRPImhdU~w0q`BHb(_&UVaK{`_z<4s#)o3s!|7`Wj{<~ za(b1=UB~Q6%$}?_s#Dad z$Of2Q&umclscsb-VK*>)n%<-~s_+PVI*JeX26mc4Sk`rkS;LrTWzXvV+WK znBAebsGTZ{Y?j#}W^?*9Wve{0d1iMp>*&)}K^2iLGFxJHw?0Fiul69jhuL9f_v$m% zTamj!UBK*x%wD9=Qg2fiBY!comoWQwy;Z$KU5e~GnY~P({WR9iq%uB;`)bS3n&_)5 z!~8^FeHj)d`Wnj6k?50U@F)6oq`DB0TaAF^NeGQ)SdV}+bpt|E8BRyg$`C=AT!u3c zrj(%L5L(M{ zSz$A#dC1JcoFu9S7Eru2YYJ_xS(bgj<=f1==ltM K7VXx+=UxXe+gf!1 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorCodes.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorCodes.class new file mode 100644 index 0000000000000000000000000000000000000000..a2694e7fea707ff1cc28e7733a5e6824aaeddf06 GIT binary patch literal 979 zcmb7CO>fgc5Ph4t*~FNngi=Z=rIZ3m5t#CEN>ourK|-?VA&?8Fjd6^twT;$xe-|GT zAS6)F{3yh%v4|tM*p}Aboj32j*_ofezWo632zOdAaLvRvu5+|Fc1&>G(915zO$NR< zJ#t=+Ckzi>JF)WZI1=ydFiQg0_B=VaW$gPwSk&WSh`wiM)Gk}5JX=vTJcbz)b@sZfFD zFGP$;grwE|SAgmo22qe6GOYhc|9OAPV5DyYs@tyYr8NosNTit}?RrmBHHWS&;a z#!(gyE7BiQPs~Z2Dc5@z=$q^;+I3%Fq=lv)f|i9n++w&_so@sdxNYGg))?B0wrHaa zE3S+qQe5lxOGO;dPCPdyS5L|pIg%nt1|`_v&MvbKo*vNfa++hdx~ZMhpFyjMb6~J& zw@Y9Bm>3=29Qx(VK`3XPuH^?;EbgDVlkd zs!^eI;eT@o_%^MoRofEi|Br-Bbf4N-duvhke%&fpjauEMlROc2XqzRwxp}AM=v1{{ z*}T5?ExO}??$q6qnYOq);VToc#Qh0knrCw+h!oNS%hw&FAR>4g#2qXJF@)hDM%aw9 z8DlffW`fNmn<)$nbY5NzS4Lx2vYjgF>y1QPs?HxAnWY-lu+iGbq-`7@$6Lbw-tE;> z-Gx$D9cWb)K?J8m{9m_Ii1sYaq`-SjdR0uyGzCkI5RnHl;Q}`tbD3Y{G z67)*aAxWoCk}gR?swCZ#gf&TeB272^jh?e>YXl+10h2SDDdOAnl1Wi>34;9VSJdM;kO;mzzB1iZ0n(pR^ PMz5_|^cs1&zZ-u5{b)5q literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorTypes.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/eelf/logging/format/ErrorTypes.class new file mode 100644 index 0000000000000000000000000000000000000000..8afdf70bdd67a0c3f427ae53bb1d839a2a62f405 GIT binary patch literal 1695 zcmb7ET~pgu5IxrxmTW|9Og;*sBoGp8lAw^1hSroKgdi@8oLIJ7Px>NU;fj&1jBGRM zAL#FCotdW7PCI$-OaD=)d#^RcO#4vVGkbLQ?!CKb?@E9C^~>)7K0-AO37=)Ki_c}O z%h=0c5jr>f3YIdoxX&XD1-CgKC|KrbDp=uosNfFABL%A*pDDP@v8>=8$1fDDaXeN~ z;AqKsF2iQX8Wr0%jas>4o7HNi%Ai?c)YihT`&#P^dVWjuyx>#|!gky5wzbnR>bQN) zjG{2AefQeyl^Cu#rsMDfzIsuvngGhT`&6r99GC5*I7F`7$9CmQ(k8DqbgOPU z43Az-EGl*G1_Q6h@VHQ%e79tT-+0tr%kO&jpmX9yHTNVSk1UR@oH7^%>&!iOwZNse zI{k>cTPjXmX5I>0ZqRTepPwHmk-Bb&a^?S>fFZTxcm4h@!}b5jUoJKnr2e-)=}tR- zyX*D`5uKDQ@C9Y36~vo^v7^oIptCb!;kzZP6?QbY-ye;azq#GjOw&57dc80>=UT*w z@v~{dGEO*%THc}0TbR8Vz75_%6-EBWtgEQt1;fLM##e=gmnydKM8y(rskqI}GB+#S z+~H=Go4efH<7SPU0&dadU)&(Cl%e>)RWVGpg0M?^t`>@8-K?CPd96NaelmVPM&R~( zrLnMo2Ig`FrM*phyBERmA*T1{xg>y)R0$+u0!f=dk|&T93M7#NNvA-PDv;Cyxdq;7 z`dmp!<31ixmWRYv2>CBF1p5hz_elOgjA4UpN~|qWyoN_{{1y_zo5@S-KV#}WBp#o* z6u(Ixbrgli^m*j#bVp=)#!V#Y56J8H7vCZEqgWnKcd=c@$Gmhr6*1dT@Cmj@g|I9M z;lDqBh1AT;$#+oRA}vTp5@cEsbxM#KL9V0($qJH_1(_8juLv?H$kp5^?wVlNq& zeUKYP&I`7XON)IsbD7_$j^vQuyrwk7w9}j#V#aBvhR8Zid5Br3sSGjaG;`#-MnJwB z1mv72NDpz-c?-tdG3x#Xrs;VZGjvA_G|Fo<$y+qYI?b_7>}#6hGrH3^bgSRftR&(# LeTow8OJL`3MYDMQ literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicExceptionMapper.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicExceptionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..31d6334aeff7e794bfbbd69c85c78e9c824a83f8 GIT binary patch literal 2230 zcmb7G*-{%v6g>?>gT`ZnF__?0#^4Ar42Ep1wg8bp1lU?g$VNt^juC^J0<@|3FN zC;S(VA4DpyN+qxUAU~#ZTN{!hn@Ul1-|oKaxy$JFKY#oQU>01(dze%(6@rdw6%R0@ zU^avg@S%z>e5BxG72TNZ#wT*0Q_+EWNiE3dMY$}gSjI!SJW>$t#)^sotSVSjF^HIg zbp@X)_>3XAXxWxnX6THJ?J@*boh)bQiCZ?`_6r&Ari@IUZu;VmY2a9padWz38%4d~dzPv5W0Mz!<=CFSB`;#N^OjL8a(9726;6VCMdBdcGm-eA@yyWk zhMm*vybELH+hhI6(_K$D9hd7h8PX7{8(|n|E6;E-DGc)|8Lj%;WGHpuI!7{?^9&`e zoNWl-B~LdS4DDnNxhWQ!oaD#iEPzU|iwz=Yu`Npsl8*11eBF}x4z&YnO2R^K3Evi0 zf$v(LMgB%@+Yv??UWRM`vH#e0o>^H!S;IA4XPB4CF)6JFhVSWz1c>L@dV!Kf26=8?GNmA)A&Hc9 zCe1K-mguB#Ejzd3TX}MpN-k|bwVfk7{DZ~w+3>uEU3{V8OYCX*N-kgH8x7y$I|ch1 zzK5Y91Cyb@tkH7x*v@+0afTZS{-e)55zaW-ldx$>%)%KS=7pj-(U8R+!<92<>XI7n zV3=X5B~F6sT@}sHd#0;W7!0@NRjqv6R0c!1k)x@=N2qdzPrVha5!!}rb9Xgwcpj(w z3oFsJ{Y30ZI+jc^3^!FlJ55w?LvOW4X1uDso?7DSiP@=iXDyJn%HPqdBP|Naky|a` z77WXlt?lPU>ZC}`psYtX;^{<;5NaJQExe@dZsa^3IoN`7^4M91$;M$*sln<1sLY?H zvLyA_b6m7*l5L|vp7uv7p*PBsP`7X@dWiJ6h`FvqCBEL)bPE{nc^yUSyM#l-h2e6| zx-YD}PFM6c_SP)7W`aQBG*`q4!^1|;s)OzS<+Lj!8=2u|)up!OLhh*q=N9)oBgd)J z2I)gbg-Kt%PTFZ)(RzbUI_-@1uJKc_--zhIO-DjQ46KrfR$t9qwX;A|9nTig#(WH%b`Xt70%q+!BM(I7K*6!qpda vXaw<21Bjuj(g3+7xgr=V@8jf31@!y0e@_2>^s19%n~#R*r^N$24ut*%ICE=v literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicLockingException.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicLockingException.class new file mode 100644 index 0000000000000000000000000000000000000000..9fdf6912d8d7f72e4b4d2f477ad22e21fe395df1 GIT binary patch literal 987 zcmb7?%}(1u6ot&9dcU+r^GR`9#Gk zI~6GI?OzHw?~^Z)K((df=uboME8Oumcw9> zrz#AhhcFsuDv8tJf(z7ptK#0-@A9#Lzt_5vcQWY9xEHiDO^=T`fIEoNRQAk{e;5ST zrrSE#I=SaKrn3~vJf%K=3jF90XiT@-9p_p(#=*auyIr=gL^0=R=fk0<{PgAmqDxb| z*D5nlG8x`>vx;}S6Z}`fW9NkIO~{@l^Prz&%_Q*f Of>sXgvrha1Hhuv~rMGwh literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicPolicyVoilationException.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicPolicyVoilationException.class new file mode 100644 index 0000000000000000000000000000000000000000..a4f5de8312feb9239f62d384078ea13d25577a98 GIT binary patch literal 1075 zcmbW0ZBNrs7>4h&wX0T;*8vVuK*c!-HNp52491`);4mhe`>;d83TwaaNM`m_AB z#1H-ef0Xfgx;mDL#<(W;dFlOJ=ibxy`;V{R0PLXZ!oeELI?D}~n=H2+Y&f_rFdZwS zWzbS4)=~K8;F*9p6qwwP!Z?v((vm@{Y=ZGm2$UY{P$zo=#p<1wfVCgJQvy?U9jaGp z_gI;xJPv4QwjTL}l?11CzG)>VIu>|Tk4(plLfP}WX{>!ueezW=q4Q(!h&NtGf%ZSQ zA{|KHeg5nAu0Xk3e=k2uFOXr!Ya~X8om~#%bX6S7PImHd27#r~vgV12PB~UqY5Ovb zsjfT%K641vMoaS(&$V)lt$#JQ+iagvA?IkMy`G``^k1p{ZR*~s(MfhEk^YCKkv;`< z8&PU}^+I!h*ZpSQxl+0{KzK0x_7icpj@b&bm*mhksx#;Y!Y`nYE=2jopIP3`p zc$&dh2ex4_Cl5xYU~D0axSV6(QV9O`T*9uDtv>8=@=NOWQAWNua1P1tknHAUZuC{G SWC>hcqnSnLTqk}3t3LsaK+l5! literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicQueryException.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/exceptions/MusicQueryException.class new file mode 100644 index 0000000000000000000000000000000000000000..4ece8eb57d1e77c5a2c60a709c9cca92adfa412f GIT binary patch literal 1199 zcmb7@+iuf95QhIvoVayDkEAU)xX+~sg@8Yb>@R^_n6!8TDdQ5TpC zmG)%6qjcy6{;TGZfOsZw?J)4eNcvGn_G48bBL9TIw9-1zhrwG#!lpoR-}AlbKp%Ykzqho0-GkFFX- zzYeVEN6CR>KC77_3sxkuGSiucqFl#kq9g`+c+ET)@*S{b? z2F@f)4Fc|yy~hc3JC%>1r3^}l0u9veDoKq>)0R$Tiwi9O{&aR zO}kbfqHr1ZoX*#puxO4fnj?!Q7@Jz$%CK+91pnnN!fsTIA&QsD9lF-n3Hec~9FeUN Z*~-X#kK6Pl*rfgc5Qg7PoP?M_=toLPX=$NAzKE&P1E^3ARgt2$2$8CXoN$em8WKBNJ1swo z14vYnIPe4bQHYt1}-|qi)yH=@YnF%oVQ2F*5nWah+gSfF4M0 zsxvIg@_54Wne;CBWjh>{u*{xMkIs!DM-c+0@zk)OQ$rb6`PblPlf&n1mvuCH-L535 zR77fNlX`d|ok0BwOzYFJG%XUSH@u#-?AH#rC_lBwYB_>&W#M+<1x`%c35SpxzRY#mYAXO??`bbW~>eQA41zR74 zMeRyqAdFJM*cbt6RzvK25|QAh6LvMH^^uw+zonUbr^wrb$cU^*WIZJF@I1h#QlR4@ N?KHaQk(!6ce*mB}??3?EHExGAxw=^*R6VV+Vh1lTr5vNcwoaaBv>9@=N0d?VZywMLZw5?mi@Ysy(Fxh zuZ6SnE^b}WN~BF~>%hL(ip9S{m?cLTX=|}RH>}#6Kp4bZz#xkkkO47ADPxl-j^YdG CCNG%) literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState$LockStatus.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState$LockStatus.class new file mode 100644 index 0000000000000000000000000000000000000000..171ce2b4955955fa5f242589b6ded2f9335e7bb7 GIT binary patch literal 1301 zcmbtTZBG+H5Pr73_O8cK@LEw`e6P|Leq_+45O zF&Yh@{ZYo*rIix>BHc}Pc6Oefd1iL@=dZ6n04(5P3K9w`ikOixCgZM(H0JnXC>T-6 zXmG?m1sN{q6=b=*FJpm0+1WC;*EXt88C0|BytmqRJ8Cg#>p|d#YrfrTxuiZan_=B( z2KEP|5w$$W@CoY$^_CkRc#dmq^26SJH`m)mtrEFw?K#E-PreB&~Vm|oy+MU9#pzOZXPoya1<_FIO{yt!{5*oJQhb;D|h zRDe=p0O~r`$@X{c(BqN1;iSNBP*nZzPz=ek7kKRzhOvJzSugA|NbPqX)goni^?+V7 zBv0`?Hz;Mt?_S>Mb6pLhM)}++tkCnSRx=76_nF6Ql{wo8bG%#{F7mb<)3Aso84nni z&)G~GCb6vHI&NqffvzFLmn?LK^y$O!lo%3@-wcRRHecvVce}RlI&ES-`#%&Imip^0 zenqLz>z`IQOQKYnr+=2FPbyW$Ibnb#aTbzj1EUkXI2?f#F5xm5#!0(Lk`J{5_8GBb z#6Ob8FhOfl*ro|TiK#Ar5ixP9>QeCw6337@K6VCwg-)~+6t3c$uu~-o#UsumP7{!e zGgC)MeiG*XaHrR0qDRzmOJH(Pa2vTUkyn%mAFJOW?dfv-2+AQ+LQy553<*U`2xU0= zopA9E_3NJ0!H~6==wR471mgrw@>Pi;kjFI5csJ-B+VlMKxIj`Rq=Z?FR>pq=Z`nFj literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockState.class new file mode 100644 index 0000000000000000000000000000000000000000..91b65fabcdb7f6886e92beab5a281ec24111d14b GIT binary patch literal 4553 zcmb_gX?qjb89ieygQPJA15QlAnBA5Qq9iQ=J5IpZ#UM)oIV6TQ?N}NsV`Pmp8W~KR z(2}it(|zCD(1omxmtxorTSX;u<+l4H4xEVhaa(*<#j+@ti(+NBNabZ5KmkA3pq!3sucy=M7eC(qb0pkG58rRS;eAZD>#t0 z>|)9)>kFy*YQ@Z_45Kug61Qf#m>L^PkEbQ&aie4ub;lT@+)_a9;bwkuN!E&CFPeEH zH7SJpK#X1fZ`BF~tt%TwVam!amGh^omR+4!pq%sMpRh^=fv+^ddi_!)DoZMigx7yHjBQSq0%y zt3bMrv{^PX)%h92p3-MZJn1B4y>wQ$P4Vp=hMgBpdU5|l8BgGuzK7xnx~nzp?Eh2X zIpK)4MZ-x4-5cubr-M7qO6HDe@rvKa`D096{<_JP zW?HFr2_Hvru(d3Wh!}=&Y)vpsPlgotZQ8 zj!VSrcKSJgVNzd^iOUYbcBJAb>_4ocf|09ZI@ovq*u(jq;yv`TI)muL1>MmVv>I z#dB8G&Ku*VDCG@}&1k=fqlQB$Ye?Y$6S*GPv{f!@Z2OOE_=H$KiGv#UVZVltLyh zQ_x#SAje3?a>lJ{xloHcBcS1Zyscpc*A)yl4VKcq27`uG+*Gj92jeHE+k+21jHp1< z3!MQxCNxVW&aP7%dH2*hYuWR0Ri@yXGubou zdlcNsOVtPNWuwO-8)D8_WYck$6hu622b;TngMV7_Qs2G@)i<@YARas&quESmY;UWxK#kg^IXn zUVJh`v`e|Ox5}NJQ||1la%W@Z-X?l0_jTkygeSNj=GPoTya9G3Z$e3iR?wE*i0}%c z+|(7slFAC=$pJ3!N*PDEZbp>rV+d1oj2-7bxS%T?4RJx=0b~#8@Fb0p%$V z%3Guk^KS6Lpd`1_Np(Csu!g+DO?aLpo)O}Cia~l>VoJI?YM2IVmY+2iBlf)2rU=I5)}oJXa+JvAo;rh5hW^sq%rBq3IfrZ zfy}l9lBrc~1CT&*xS^RNkPCMKBGO*~$+iR%Zw69s3FH}^_N@3ft5MX>_${*(;Mw*c+7==0sax1G&EBw; z#wnRw=n>{^%k29Qy$U9;q5lXi5%zV5SFyu4aA&~4UBbY@e`5Cys&A*>UbY8!_YK`c z)xaxUuOPvHF0|t+LB2}bH%R>&d+6&dr#Gdsj}z7o?4q%smCiqf&p{`5jFmsb6y&>x z4Ws}=Y8$~Uigb!FyIYvui?E6pRhTN~R3-{7FYTs>=TY`7-_Bk9#5#9>fIaVFgGhBH Z(02wX+2UCn7Leo~=WQQnQ~%T5{{vgrHZ%YL literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockingService.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/MusicLockingService.class new file mode 100644 index 0000000000000000000000000000000000000000..7acbed85a509ca9a3940cb1dcbb4d560b2c82ad0 GIT binary patch literal 7236 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 SFK0+Pm!r<{R*HMFq3Qqdnnk<- literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZNodeName.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZNodeName.class new file mode 100644 index 0000000000000000000000000000000000000000..dfb9b7724ee309e0a3299acc3f9acbf413cebb49 GIT binary patch literal 3399 zcma)8S$7j<7=FGiog^Kg6bdM<1{FyYAc%-)X%R}Q)wIP1s|69J$s`>}XX0eS;=YUf zuIJ#5H_8nc>XG2l<8r0vc;oN!9FO>XGifqS3-luIx4rB0E|b6h`{`EzcjJo~x{-?_ zh{FmVi(v|n%fk~2rXx5KLkEt^^OKSsi{U98m*j*bS`0JDD=0)MrN^)eMFk}VvoWke zE&@ZYCnY&0NjZu+m{C}$NHb3>uw&>&F@mbpR+f%9a#xe&v?OO@w0c&-If0O=&FKQ& z*^}C7EnU{kQab0@hFKaA=&0Cw(Kss*sp?PHbTdyzG0OY0RVwMWz>chCm(rH0Rnl{{ zs*z9YdbyaEuT+rEWU?b!m-C=r)=QeBOPzZS({P3adJ>CG_D|8FVXHtptFnfvkJsjA zbo;P2Q+8dn@>+RHvkiG}TnavH@+tBpMl5?yb24Z1dc`p;lV+1Xp8dA1of|a^`q_z^ zGf_NX)yzWG&m3}QjjBL@dvs+he~N)sb^ElD*V9MF>FGG(qyC^#AWkcCj+Q?)rd3?; zn0E!wFpta#F?1{sSb?>PexExnxCydWrr`z9Ow63r^Ugs35n^vGOjP5Ex@WcOtcP1L z(a#J;^VVENv-QK2*qT^&98xq;y-Sjv%!D(mIn0=5R?o<6D<$2L;R>kSHKV6B9uGB2 zWl7(qM>(TpYEI3jc+MAnBL?5ium!CNmX%HSw#&j+u?^3v z=tojuOIyueE2|2gQ}H}rP?5q`fm>P)GF~f}4_Suk=ytPg1Xde`cwRG2%ZbnEag#jK z>UI@(VvC9dwy+pfyoi@nyo^^Qc~!w{DqhDM0=N3L%c5^9VHI!Uyo$HL&gp9LdguwP zZ(Vuibf9LG3o>aNypD($-Ij>!^F0w)@iyL(f)7=EgpXBxf=>k! zEydSw8-bf#hPYL8;#M&}<93xa8>gwy@VSb8ctFK44ywrD4M|4W3N8Juye|lGzG+z4 zoDSRDl6QlFQ@3r)o)2zImOY==9LF2NdCM#s zrJAkD0q7gWvQgNsV|ul!mDng9TBV|!1%YjTaOSNn^0rY|)Y7|DFsF28rluJNf4MwEEE4lkPaO6UCmE>mU@I~a*LGCF8E-0m5VsP;oT6}j1X528UF7G z$T{P#9Chx>*~K+VKF%W2G$1}egfhUd$tw`az-0uI-N7Fbx{Pq@PptSE9n;;)6-0hZ zrY<8YNi5a1t&YyY-Y@Y^G8OEtL*->M)f+ld$BG}Zk~%J;GM@Ya;qM`NS9kn^?&;vq zSTlVEYrA{uSVyV#b!^B@hrY*6xoI-qoU3EwMeOm(^(~aU<=S%JG1`3?!y*1blIwZ? z=?P*7<9e8QfH;J32P5CiQv&Na{NtSDn~6t~SlmT4?jaicxEsSBYT1QHdGk8==dqiU z_Fnvg`}qpKg!#4$JNdsZ$QQZW#T^l(#BQ!~Co>?({~jfi^lcAsnVYLL8&GhcLS?v0 zi$U+e&$)tuGYaQuGFr#2-*O*t!|HJFhg_FbkEdZ?$l1ypCKngT zEnQ0|Q{NyQx|I3@E0cA^Q~Z66aPU&4=n_Rd^loEyfO9&GgHSl7 z*I@)3@DTclYYLALyD`@VS${OsL?Dg*I6x=*h<86x@et@lNLeZV#ac$qM~?r7pZAbK z#@Xq`d0W@!6VeBNsFS`>JDZ{MyU|ebH@U-<$x=lu#a|t_5B6TbAkTpzUIccB`T}2} zrzb?ZN*dxNLB0KwyjDUNvD$r7SiDMKPpB~1+m6E&R6LF@Jb@leVz}NS9(wm6vmPWznph>>{>nD7$zqg<@Q)MI^l-B}Rw4W!b_yXP(P8lq0}+IGz7Enn zNqoZ6?e-!l`j81Xk;yi}^$Q2uVVzr2cx*|_v3ASOV&Sg+tdem$E6eY0<|M$CV}o^8 Z#~tm~H~ADq8?Fa1L6HEP@KJZ2{2!I|9vT1u literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$1.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a914addb008ce3cc6d9f73c1660fd8e70b11b11b GIT binary patch literal 1421 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 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$LockZooKeeperOperation.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZkStatelessLockService$LockZooKeeperOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..3ad2abfc6992e09a0635148be44da89e851414ca GIT binary patch literal 4331 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 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZooKeeperOperation.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/lockingservice/ZooKeeperOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..26b0d20cd7c1c00bc8adef7afe9bdc66502ba01a GIT binary patch literal 274 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 GDc~1ZwO!Ky literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore$Condition.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore$Condition.class new file mode 100644 index 0000000000000000000000000000000000000000..60fb682ef3f9990992e0246e8b093ea13bc87187 GIT binary patch literal 1541 zcmb7E+foxj5IvJbmV|{MAgBl;qU3@sig*iBR)vd}i5Eigz}v7H!eX);XJ@(mlP^|@ zq7Qz6A7$CQi6LwiQ66@-yQio7^y!}Y_4~(90P|Q%AdWk6bmOkSOec^+x(69#eQ73v zdzjT=XqaP2n2uexl;zkiL$a{P_qpLIt7;T^J;x9)SrwZrPYQ;Gv%8B8waV>^QBu;f zE4eny+wDDJs@xLA7;;6Gt#lYdja#-+^y|t~MN_Sl#K-X26i4;HX?8+& z{U^iW)SY?stM669RV_#i(NubiL6gGus*0+aDws~K*$;kbl%=&Vq+$B4Sr2?lLQx@6 z>GyHGgR^r$Zi$scQ`CbI({P{klH*BJtXe+beJze={n^vej|Vyu=+V)Kq=tDN53!)( zk&efBqT?x^X~^kV#B+w}&;*@FIzxXj*ukte=80kO)YJkPP(cKZbqq|C@X>RmS6dT` zVIy_H26W)7joit9w}8+(HgPzSN_U7E^q{9A)N<)1x63~1SvnA^@N{T`hAh)vEcthl z`WI&TJXeO1vLjr&+$F9ocju^W!sb$)5r!^wdJDJc<%-jD7NL*E0d(a8t(R7sj6kNo z;xc&*koJN8QTit{-@r22V?;7D$B2F=Qxt==4j@MBGOa5Vc$I>zVTddfjbpfitE5qY zW;$Q;6Gd>1tU3W`?De*wTqkK1H<|!A#qj}*X1*YLf> literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicCore.class new file mode 100644 index 0000000000000000000000000000000000000000..9e97857964f9525a276f217862ded05800916dc4 GIT binary patch literal 28476 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 M48x#cLyrmmAO617i~s-t literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicDigest.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicDigest.class new file mode 100644 index 0000000000000000000000000000000000000000..7cde4e1728d9ef796e5ea9e8ff8194250a030756 GIT binary patch literal 1062 zcmaiy+iuf95QhJ?Qzvyy(}p&j(*}A-48<3~RZuTlKuCmwlqym$H_6J~DzPKS&J_;@ z5^W`rcmN&>F>6~%lo+9vW_D+1XTJHhzyJLB1>gm26DF#wSjDz7J9*ShRPn<@>t_aR}cR-PH%kS|)hX+!f(_k*VkkqHv@&niLJw9@V(OCAJ zA(x)>QElHySByi#T60DCb{>AS-dIMUyzxTbRtCEwEmFbGbkrg}o1F@wpXkA0w*4sR ziFZ;Bu|CK2Txn-v4F?vAuq@ny#c*d)(c?%C`XaDUM}vWVvG4#DhVB1MOuc56K6Nh% zltHg6aD$IV!s{~}W=*!FNea+JjedtoUq+)v!10cl$r~WuP$Iidr*pd3$(QUKF#G8h zH2c{V^l$Nl4YFnWQNS+QJu11cB%m0ulRU$1Y|@De#BEr-Q;jrgu!Tz6#v!lnR_yQ4 zzS2g6Dy~?7!?>W8B%}pNT->FIVmzX3O=ZV?Gc+@fzQhV%#T6<^))dJ|kr?h}g6NAN z%}kK{*&uToB_PKHa`F!lrHE31zC$|HdxBNNSAQaReiI9$U&AQp$taP?U8Ar__+gH) MI+f}n)zR?iFNrq2U;qFB literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil$1.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil$1.class new file mode 100644 index 0000000000000000000000000000000000000000..61edc7dad7d95ed3e38728a19869936e66c3573f GIT binary patch literal 1166 zcma)+T~8B16o%iSrQ6m56;TmIKvpQCtbD5=(l4~JAB47O!i~dr1B=_;X1hhbGtnPl zqBq`|7~{2?7-I}Sz#nBir>G@{C`spi=Q%s)?DWiJzyJ8U2VfehFwSEjgf0w*Xg0)n zLBTMC%5srqgk_W^#xlloiDjJSvVtoLG=WLA_{jA1?VPNsx>Hpv(vx*hK2|HPxofx- za}6~`!P1kOq2^`P5NO-T2m}{(%d|~zNx&ByTNm&roeDkd%9^&3Z&Wu8wi$yten~)CkFO=~#MdaCi?0dn%Y+;x%dSLZ2<^#(k%m>zYFo#cE2yDP?%^q(kw3=^yd-~xH+W0#!zudv0d9hL zO_hN*8oe}T&~s108RQO;JjV_bs@K=7aTe#u{pcs1pwUfryT}m@(zjz0)61csqnQ5@ literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/MusicUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..46eb8b6c43512fdb782352af33d9c31264be87c9 GIT binary patch literal 12499 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 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/PropertiesListener.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/main/PropertiesListener.class new file mode 100644 index 0000000000000000000000000000000000000000..19d572d5ce064157a984a51da8f83c0434a332f0 GIT binary patch literal 6316 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 BklO$N literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/response/jsonobjects/JsonResponse.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/response/jsonobjects/JsonResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..bb4c16c2edb203021efeb1e87974a9f859e36fd1 GIT binary patch literal 4990 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 bk^Vr}q1%g=YjJ3PvReKN$n$)|O5gth7rsK4 literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicBmAPI.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicBmAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..b501f3ac42328b0535526b7c296a17ecc0db2d37 GIT binary patch literal 11103 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 JRn;F7{67I^M1=qV literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicHealthCheckAPI.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicHealthCheckAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..e298e0648050d2f840d964c9d8184d8bc2b5aba1 GIT binary patch literal 3351 zcmb_fX;;)%7=8i+vk(`?rA4%kYeB(SmsW+UIE;!6i)>b0L%0l)kc>$NL2LK@AM{_e z_8heJoc@6RpMLf9xyb}(Mxff$`EYY{?|a|nd7t;anZI8B@h5DBnZzV+rEnW}Qn-tIa=4#>p1_pc zF%p=T$3y}%2^8X(m72{s9>g)HpwV&)1>q_@6h39J{90sHpSA}l*v)Nf;%=HZS(dHII_dMO6cJ)zT_e<1}Ys){- z7xYEV6Yhc~d~MeEi`rEVqu~OT6&>3XUF~JTN1o<-n&G%Y8VdImBxpI9D|lm#3X(ik zvit$PC?l7SXeHmYG%iHmR>Yv-L~XnQ%(Fq5h741yjavfkm19kZ7A&198TDOehPykf z;aw_55TCC0r~CE86)Qti4}{@&ou|T0gw~j21VO6eut>i+<`uMzlx*Le7ZavuGLt>F z?a(ok;3{YibS-KjxL0yxR1~@!tqtq`EEgLVbgM*G)N2Nh9m<=I<~`CS2{nCHq1ID0 zhl;`t)bmvH72#(>Br{RwcUGAkcAe>xAv_9i)r&>TG=j6*1JAJ)?5}oxSaT>#uRUfdCAtl(To9>Ir{o&qvMK4mnT*>%O#uX1sbSE?8xS4_R(Y|a1YEWaDkZ8efHYzj~55We}yh`q?x;Gmz{`guw zV+p6mx38~@{7UNh_@hP6h z@tFz@U&QgHim&jsif`~O)6q8=T2XLdRlDp71U6%O8IqT9$eN#~Jr&>K>3;@m(sAa5 zAYWB{F9Y1WvLG$>7{0k6f{4n|G3`|n)xId$Qv>Y0ZrWjI7-x4;@dJJ&Xf;9%X5H4w zq6qRAw2rXWS?H@N4boX55_T5_$7*c+%dJ3~RMcL0V<>n(Z#eUs?)%}TVmS7USty0I zU2(OL&oR@UaTIj7z2S+923GEe@+L|bgujyVsA#vhh5cWv?w*Y-2;E{Q+7WjBaJ$?M z+b7wliX|rW%o@8D#v}RHmlR|q%25-nx^)glzBNV@wa>PNo3&Vbfp-&MGgF#Ibz8S(-cnkQl{}+6{Zwg-mxfSY4 z3d>(Iz3T;9e?y(5FYj57A$>0}x0m@=N6yHcZRf0PY Lak-7pW66I2&W(xZ literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicLocksAPI.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicLocksAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..d4100e6a7fe4d25eacc23fbabee5ac9c575e348f GIT binary patch literal 13871 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 F{~4BlDbN4_ literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicQAPI.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicQAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..1c28d1b1b176d05a4b754e0db660229f79cc83ae GIT binary patch literal 7943 zcmeHL>vJ1d6+f%Uk|nL;akj%ue(vC|~C1yUdm2IEJgR!QX8ao@mtb#1RB?XK^x zV!NS~N6Vu?`7aoTPw;^>12aI|Z=K<9;4#d=Fw-et`NHtKcUQY!*;edA>A3B9c767q zd(S=hJbvd~z5VZB|CWe8O+U#~KiOGw^5oKLjt-K@Q;KZ)^5n~xuakgv5ot<#2l zy&yktX6fr$dQqcH!&zG5LZgSPj#y%jZMdx2@+^~a-dJRkYuQU|YN|S2RWm1fgD)9A zAH~`WmTmcC8XXuOnb#;i;ncZC{Z-56ms`yRF6NAd21X879n)yc8^V&`;b7WdwmgmQ z@7z{!&u3Thx+Jxj8Lw5aQ`Qt5d(LR|?r?R*xM8q{0j*|z0p&*juOl5+svExH`HtXh z#dB%5GjoY^48;adNQv2w&E3^RBYwzl@n{Dz%c5_v3j(|Q{wH)TH88WJw5%0yuUF(X=h1wbN2>K(|l$A9) zw8^ydj#bBmyAxiSz-d}d?tyX0aNUMwDnZKY8l6ZUv1SM;<8zTX>rfZX)C$P%yJW05 zVleU_R9tOYg4Yiq>otw;Nhno=Y2uYK4%#c_beyo5n0}EPbuQWq4nB1z89IFsXD+uT zXoLwJ!8Bf()aclFeEdOa^e_Z^Yf)I`p5PmUvq5C!RUQmpR-sX_5Yxi1*uH~Y{^!2Q z<%&}Ke~`=>7(k`lBb~UnbGn6_Bg(plJ`>Iw(mWZqHR04-rV86^%f%kRP%Xc2?0!wD zyeqpWB3)tVHDOikMQ5}-yygP4?A0luW~h1=_Ry%b^Zpv$m0;GcNs!xS0Wikr>pqx; zI;yPCr-jqpSN@XC0a^of+})JuHpcJ4Um2KYug(h9(&%Wy5tCEZsktebJMD6QU86sI z(0Q??yzgMhE@opb-)gW+hKpnMG_0oOYot{`ueP|@(CF;WxKk6{HBf41S&n}P@6jZ zNi@)C^0V}kPT!<&>2!$h(&^h&(&;-it<%d?)#(+Q)9JhPy)1oSrytO(I{lD-q|=Y- zHI0V4ikBA%v}|!^1uoF&NIVqvt4NOyVRyI$A=;O?A6$$yn%Ere6AiROs6BfV2-_8c zyN+s`aGQ!drf{SX6s$Hst`y6y(u<#_uaR}w#pVe z#_iJfuywq{?oGq8nYvO=;C_WGEBvO>+;FFVy2~Be9R&6_4dE>tjRq1az|M2SyIC1@ zDw`oZClfVv?CjHk5z{QLXo_d|MQ-@Qx z>A_s}Qsh1(95z>|`GP6hlC4g7{uPrpt*51l?! zOc#5KnPRrsTg(;nwzG9iKP#Ur&EpyPO?1_M;aBd=HkbRV9y zq6R_rC~62)Mo}j~WfgTlJ%H276({lJ6!jpeJbe;$8aoWr2&fUzr||zFjGXr944uW6 zAQ(Mt(j)XKIs7bX9)1G)45s~6+T>g?Ly?#i|25FVRcTj}E3$3LQOeuAo@n{Oezbp%U!rwlF@Zc%TiqhD2yej!*H<#0L5 z;c}G2ox^2dRglAFYUgm7F41M>=yH_9WeRc_deRlD0Xve}EL}bmXLHi! z1BqhTYMR33(IA9SRum}!V1P3gF0~WynQy?HqI#VDZOFB~^kcS4R=^1(!aBzb9=s9{G zM;k#)@D=(hzGH~^8rG!9hzkD#zQe+ACaOc7I^p5(`>yc6m$Dzk2;UkbssAcQ{s<5K z3BLI=EdQ7N8zYM!#|TPC5F<-b@BcIO)Ux+4Z37~z^Y4oxBk279r9vR+{7Vr`lp>fY zMKDo{V4@VkL@9!aQUnvF2qsFj9CrStsB0*NT|*26vhzQVpp+#e+3-jAfR9eMpCSup VNYRSI#iO7?BV4D3?2A2W{s(U?5nTWP literal 0 HcmV?d00001 diff --git a/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicTestAPI.class b/jar/src/main/webapp/WEB-INF/classes/org/onap/music/rest/RestMusicTestAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..db3248eeb56b11354dffebcdda2b8829b7d6d312 GIT binary patch literal 2338 zcmb_e+fy4=82=p-*bqXYDbP|yk+zikqE;=JQYn{$hJu7kE3LXD$FR8B&FpR{>iFP{ zNwMcC1f<*5NNQR zLP5F$qZ!97=#Fia^kUgFbGnq)hq^j7?SeixmzmE5lC#p11;dvU)SWbK)1MNE_4RKE z#Alqm6llqqw!Bd;ZcBH~*tWqyzRa$%XYA{qboVUj>pQ+*(icdwA%h4d$M)nze;}xrebdsHj1rL& zrfo}?dx2At!v(|J2?c~HAQmY|TLKV)r@l@=^Of-my(NMkB6n0r;^Wd`G{z#L6+I(ACXREa=+EtlF0Xl{UJ!z316T0PS>MQgMBpHC8kPkbvu43I{IbjBe)-g) zsma9uZD;3d+4jw%+%P?pWj1Zwj&JxTi$LIH5TbqkuBW@6etm9@eqG3zj_%zxRQc=1 zk+eQtGM7uz4Rk42zh_uwI-0mH{ccr$0v%OwE3T6-=cGs3R-;t1%v_+V?|P0c&{J*J zis2eX=}WiDzOz+;ImeayjAQ$9-zR7?>y+J`oHtc3wb!=Bi0T8?V_`pp9XcoQ!}9)?PerWXh(;@`I_Ot&N$ws8dg$x2dgQZ zLL1Bf=CH*<;rSb(2^z8~tYKZlMhcs_$+Re&!`7_SrNHTc7peMdWz)(_H-%exR{(0= zO5rxvQ@Dfof_iK{(plc#l{xy?d;}fz;z*4HPnd43@q+Zji6<}<*0>&6HDei`$FcHk zfQ)HZjYiQhZ9SNB>l{wZGjFVfN}#Q;(k_um5TjSQ_2j8X^NoCdK^hF4z{RNfj~pdx zgg3B$rJZMa^erC0zmf@>G5jBhkCRXMPIxchic*>Bxf}%ua~7R$6;2eg!oo{@^U{0^ z1y`0CcXiyeNJ&rgYc}`>P7K_G7)aOMN9 zp5w|0po=m@6mzKO5BPB~U4I`951_^H5Q$s&(6|(v>T38NUsXQGj0^A z^8rpApyiMi{~*FVKrxy=6#kmqEXxQ95^~qkm~a!Cn0SFDDA_ERxEqiK3}TGUZnF$E%&ap#kd);E z_%>=OL{sGh_)wOodzQd1TOt1Gp6))E?|kPn|NQ&c-vI7Fq|t}F7Cuhn6MWi<7JO!5 zB8_(3O<_{+nKY(wPk&8ona@-Bq6;&)Zz0=>2gs$-joB3D^ggeb1q%-uI=rA#ks-r) zJ_sv3@I{sH#*tg%QhHllzq)>f=W_Ykypen$Jy{V-W=MC+^<6d1&^kD@#?Y1x%95cc z@A~plyt^sG6|w2jO>aIZ32#k=u0Gc;+tjujF$^`j4P~VGGA#v-VoipT8~8Iz3*^t* zOHK?EgZUk?C!X<0hI^h=d|Rn1pQojmT#$ik;72kuWCVGvT#pw-m8_)5gLz|kV=D}u zMYrM$6^9hh(>K;@@IIA*@dPniR3Q3m7&okx%NHb#S}r;oK#MYTb(gY z=1GqF>wGMQK{+nThzy())vD)~j6J>+1wO<3^;nlgD0ZciVIAlzbp}g8D0w#Um3*ei zXu250VM)%qx>znX$^Dqdr|T$5dJ_4PP}`(@mGAvntBXlzV|;Yt$;eOqRiRva4KbwL zRpY=Ro@`viC5C~9HlS*0T8|dKw2?=_#s%~t^~$=jZZFHK_ndO=sK5#3 z4>1{Zwt~!>j-tlRho8#?N5sg(^F^85tf*?5ZYDb>djC6&oA*5Kug z5kXy3kt!J*4B4b>xZx=4i72Ax{C@^1V;xk0(l0ZNo-|i$rdqq5&H^c3Z*a9MT%Vg6 zvr4mpijbhzXl3XdJZ*|>q*Rc2qG9LyTLHs`W+-SD-byOf3R5WqO^hY2 zc_N~W9<}c@3x-k~duru*mAc3(u4c2jVv)gVvmVQR7ku41Wj<%O*Uq3`guXTXb z3v|+Yfb;>nMtW^J{)x9*@e,PRIMARY KEY (empName)) " + + "WITH comment='Financial Info of employees' " + + "AND compression={'sstable_compression':'DeflateCompressor','chunk_length_kb':64} " + + "AND compaction={'class':'SizeTieredCompactionStrategy','min_threshold':6};"; + + public static final String insertIntoTablePrepared1 = + "INSERT INTO testCassa.employees (vector_ts,empId,empName,empSalary) VALUES (?,?,?,?); "; + + public static final String insertIntoTablePrepared2 = + "INSERT INTO testCassa.employees (vector_ts,empId,empName,empSalary,address) VALUES (?,?,?,?,?);"; + + public static final String selectALL = "SELECT * FROM testCassa.employees;"; + + public static final String selectSpecific = + "SELECT * FROM testCassa.employees WHERE empName= ?;"; + + public static final String updatePreparedQuery = + "UPDATE testCassa.employees SET vector_ts=?,address= ? WHERE empName= ?;"; + + public static final String deleteFromTable = " "; + + public static final String deleteFromTablePrepared = " "; + + // Set Values for Prepared Query + + public static List setPreparedInsertValues1() { + + List preppreparedInsertValues1 = new ArrayList<>(); + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + UUID empId = UUID.fromString("abc66ccc-d857-4e90-b1e5-df98a3d40cd6"); + BigInteger empSalary = BigInteger.valueOf(23443); + String empName = "Mr Test one"; + preppreparedInsertValues1.add(vectorTs); + preppreparedInsertValues1.add(empId); + preppreparedInsertValues1.add(empName); + preppreparedInsertValues1.add(empSalary); + return preppreparedInsertValues1; + } + + public static List setPreparedInsertValues2() { + + List preparedInsertValues2 = new ArrayList<>(); + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + UUID empId = UUID.fromString("abc434cc-d657-4e90-b4e5-df4223d40cd6"); + BigInteger empSalary = BigInteger.valueOf(45655); + String empName = "Mr Test two"; + Map address = new HashMap<>(); + preparedInsertValues2.add(vectorTs); + preparedInsertValues2.add(empId); + preparedInsertValues2.add(empName); + preparedInsertValues2.add(empSalary); + address.put("Street", "1 some way"); + address.put("City", "Some town"); + preparedInsertValues2.add(address); + return preparedInsertValues2; + } + + public static List setPreparedUpdateValues() { + + List preparedUpdateValues = new ArrayList<>(); + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + Map address = new HashMap<>(); + preparedUpdateValues.add(vectorTs); + String empName = "Mr Test one"; + address.put("Street", "101 Some Way"); + address.put("City", "New York"); + preparedUpdateValues.add(address); + preparedUpdateValues.add(empName); + return preparedUpdateValues; + } + + // Generate Different Prepared Query Objects + /** + * Query Object for Get. + * + * @return + */ + public static PreparedQueryObject setPreparedGetQuery() { + + PreparedQueryObject queryObject = new PreparedQueryObject(); + String empName1 = "Mr Test one"; + queryObject.appendQueryString(selectSpecific); + queryObject.addValue(empName1); + return queryObject; + } + + /** + * Query Object 1 for Insert. + * + * @return {@link PreparedQueryObject} + */ + public static PreparedQueryObject setPreparedInsertQueryObject1() { + + PreparedQueryObject queryobject = new PreparedQueryObject(); + queryobject.appendQueryString(insertIntoTablePrepared1); + List values = setPreparedInsertValues1(); + if (!values.isEmpty() || values != null) { + for (Object o : values) { + queryobject.addValue(o); + } + } + return queryobject; + + } + + /** + * Query Object 2 for Insert. + * + * @return {@link PreparedQueryObject} + */ + public static PreparedQueryObject setPreparedInsertQueryObject2() { + + PreparedQueryObject queryobject = new PreparedQueryObject(); + queryobject.appendQueryString(insertIntoTablePrepared2); + List values = setPreparedInsertValues2(); + if (!values.isEmpty() || values != null) { + for (Object o : values) { + queryobject.addValue(o); + } + } + return queryobject; + + } + + /** + * Query Object for Update. + * + * @return {@link PreparedQueryObject} + */ + public static PreparedQueryObject setPreparedUpdateQueryObject() { + + PreparedQueryObject queryobject = new PreparedQueryObject(); + queryobject.appendQueryString(updatePreparedQuery); + List values = setPreparedUpdateValues(); + if (!values.isEmpty() || values != null) { + for (Object o : values) { + queryobject.addValue(o); + } + } + return queryobject; + + } + + private static ArrayList getAllPossibleLocalIps() { + ArrayList allPossibleIps = new ArrayList(); + try { + Enumeration en = NetworkInterface.getNetworkInterfaces(); + while (en.hasMoreElements()) { + NetworkInterface ni = (NetworkInterface) en.nextElement(); + Enumeration ee = ni.getInetAddresses(); + while (ee.hasMoreElements()) { + InetAddress ia = (InetAddress) ee.nextElement(); + allPossibleIps.add(ia.getHostAddress()); + } + } + } catch (SocketException e) { + System.out.println(e.getMessage()); + } + return allPossibleIps; + } + + public static MusicDataStore connectToEmbeddedCassandra() { + Iterator it = getAllPossibleLocalIps().iterator(); + String address = "localhost"; + + Cluster cluster = null; + Session session = null; + while (it.hasNext()) { + try { + + try { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(80000); + } catch (ConfigurationException | TTransportException | IOException e) { + + System.out.println(e.getMessage()); + } + + cluster = new Cluster.Builder().addContactPoint(address).withPort(9142).build(); + cluster.getConfiguration().getSocketOptions().setReadTimeoutMillis(20000); + session = cluster.connect(); + + break; + } catch (NoHostAvailableException e) { + address = it.next(); + System.out.println(e.getMessage()); + + } + } + return new MusicDataStore(cluster, session); + + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/JsonResponseTest.java b/jar/src/test/java/org/onap/music/unittests/JsonResponseTest.java new file mode 100644 index 00000000..9da10638 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/JsonResponseTest.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.*; +import java.util.Map; +import org.junit.Test; +import org.onap.music.main.ResultType; +import org.onap.music.response.jsonobjects.JsonResponse; + +public class JsonResponseTest { + + JsonResponse result = null; + + @Test + public void testJsonResponseBooleanStringString() { + result = new JsonResponse(ResultType.SUCCESS).setError("error").setMusicVersion("version"); + assertEquals("error",result.getError()); + } + + @Test + public void testStatus() { + result = new JsonResponse(ResultType.SUCCESS); + result.setStatus(ResultType.SUCCESS); + assertEquals(ResultType.SUCCESS, result.getStatus()); + result = new JsonResponse(ResultType.FAILURE).setError("error").setMusicVersion("version"); + assertEquals(ResultType.FAILURE, result.getStatus()); + } + + @Test + public void testError() { + result = new JsonResponse(ResultType.FAILURE); + result.setError("error"); + assertTrue(result.getError().equals("error")); + result.setError(""); + assertFalse(result.getError().equals("error")); + } + + @Test + public void testVersion() { + result = new JsonResponse(ResultType.SUCCESS); + result.setMusicVersion("version"); + assertTrue(result.getMusicVersion().equals("version")); + result.setMusicVersion(""); + assertFalse(result.getMusicVersion().equals("version")); + } + + @Test + public void testToMap() { + result = new JsonResponse(ResultType.SUCCESS).setError("error").setMusicVersion("1.0"); + Map myMap = result.toMap(); + assertTrue(myMap.containsKey("status")); + assertEquals(ResultType.SUCCESS, myMap.get("status")); + assertEquals("error", myMap.get("error")); + assertEquals("1.0", myMap.get("version")); + + result = new JsonResponse(ResultType.FAILURE); + myMap = result.toMap(); + assertTrue(myMap.containsKey("status")); + assertEquals(ResultType.FAILURE, myMap.get("status")); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/MusicDataStoreTest.java b/jar/src/test/java/org/onap/music/unittests/MusicDataStoreTest.java new file mode 100644 index 00000000..16d2af02 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/MusicDataStoreTest.java @@ -0,0 +1,162 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.mockito.Mock; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; + +import org.onap.music.datastore.MusicDataStore; +import org.onap.music.datastore.PreparedQueryObject; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.TableMetadata; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class MusicDataStoreTest { + + static MusicDataStore dataStore; + static PreparedQueryObject testObject; + + @BeforeClass + public static void init() { + dataStore = CassandraCQL.connectToEmbeddedCassandra(); + + } + + @AfterClass + public static void close() throws MusicServiceException, MusicQueryException { + + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.dropKeyspace); + dataStore.executePut(testObject, "eventual"); + dataStore.close(); + + } + + @Test + public void Test1_SetUp() throws MusicServiceException, MusicQueryException { + boolean result = false; + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.createKeySpace); + result = dataStore.executePut(testObject, "eventual");; + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.createTableEmployees); + result = dataStore.executePut(testObject, "eventual"); + assertEquals(true, result); + + } + + @Test + public void Test2_ExecutePut_eventual_insert() throws MusicServiceException, MusicQueryException { + testObject = CassandraCQL.setPreparedInsertQueryObject1(); + boolean result = dataStore.executePut(testObject, "eventual"); + assertEquals(true, result); + } + + @Test + public void Test3_ExecutePut_critical_insert() throws MusicServiceException, MusicQueryException { + testObject = CassandraCQL.setPreparedInsertQueryObject2(); + boolean result = dataStore.executePut(testObject, "Critical"); + assertEquals(true, result); + } + + @Test + public void Test4_ExecutePut_eventual_update() throws MusicServiceException, MusicQueryException { + testObject = CassandraCQL.setPreparedUpdateQueryObject(); + boolean result = false; + result = dataStore.executePut(testObject, "eventual"); + assertEquals(true, result); + } + + @Test + public void Test5_ExecuteEventualGet() throws MusicServiceException, MusicQueryException { + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.selectALL); + boolean result = false; + int count = 0; + ResultSet output = null; + output = dataStore.executeEventualGet(testObject); + System.out.println(output); + ; + for (Row row : output) { + count++; + System.out.println(row.toString()); + } + if (count == 2) { + result = true; + } + assertEquals(true, result); + } + + @Test + public void Test6_ExecuteCriticalGet() throws MusicServiceException, MusicQueryException { + testObject = CassandraCQL.setPreparedGetQuery(); + boolean result = false; + int count = 0; + ResultSet output = null; + output = dataStore.executeCriticalGet(testObject); + System.out.println(output); + ; + for (Row row : output) { + count++; + System.out.println(row.toString()); + } + if (count == 1) { + result = true; + } + assertEquals(true, result); + } + + @Test(expected = NullPointerException.class) + public void Test7_exception() { + PreparedQueryObject queryObject = null; + try { + dataStore.executePut(queryObject, "critical"); + } catch (MusicQueryException | MusicServiceException e) { + System.out.println(e.getMessage()); + } + } + + @Test + public void Test8_columnDataType() { + DataType data = dataStore.returnColumnDataType("testCassa", "employees", "empName"); + String datatype = data.toString(); + assertEquals("text",datatype); + } + + @Test + public void Test8_columnMetdaData() { + TableMetadata data = dataStore.returnColumnMetadata("testCassa", "employees"); + assertNotNull(data); + } +} diff --git a/jar/src/test/java/org/onap/music/unittests/MusicUtilTest.java b/jar/src/test/java/org/onap/music/unittests/MusicUtilTest.java new file mode 100644 index 00000000..b117c330 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/MusicUtilTest.java @@ -0,0 +1,207 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.*; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.apache.cassandra.exceptions.PreparedQueryNotFoundException; +import org.junit.Test; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicUtil; +import com.datastax.driver.core.DataType; +import javassist.CodeConverter.ArrayAccessReplacementMethodNames; + +public class MusicUtilTest { + + @Test + public void testGetCassName() { + MusicUtil.setCassName("Cassandra"); + assertTrue(MusicUtil.getCassName().equals("Cassandra")); + } + + @Test + public void testGetCassPwd() { + MusicUtil.setCassPwd("Cassandra"); + assertTrue(MusicUtil.getCassPwd().equals("Cassandra")); + } + + @Test + public void testGetAafEndpointUrl() { + MusicUtil.setAafEndpointUrl("url"); + assertEquals(MusicUtil.getAafEndpointUrl(),"url"); + } + + @Test + public void testGetMyId() { + MusicUtil.setMyId(1); + assertEquals(MusicUtil.getMyId(),1); + } + + @Test + public void testGetAllIds() { + List ids = new ArrayList(); + ids.add("1"); + ids.add("2"); + ids.add("3"); + MusicUtil.setAllIds(ids); + assertEquals(MusicUtil.getAllIds().get(0),"1"); + } + +// @Test +// public void testGetPublicIp() { +// MusicUtil.setPublicIp("10.0.0.1"); +// assertEquals(MusicUtil.getPublicIp(),"10.0.0.1"); +// } + + @Test + public void testGetAllPublicIps() { + List ips = new ArrayList(); + ips.add("10.0.0.1"); + ips.add("10.0.0.2"); + ips.add("10.0.0.3"); + MusicUtil.setAllPublicIps(ips); + assertEquals(MusicUtil.getAllPublicIps().get(1),"10.0.0.2"); + } + + @Test + public void testGetPropkeys() { + assertEquals(MusicUtil.getPropkeys()[2],"music.ip"); + } + + @Test + public void testGetMusicRestIp() { + MusicUtil.setMusicRestIp("localhost"); + assertEquals(MusicUtil.getMusicRestIp(),"localhost"); + } + + @Test + public void testGetMusicPropertiesFilePath() { + MusicUtil.setMusicPropertiesFilePath("filepath"); + assertEquals(MusicUtil.getMusicPropertiesFilePath(),"filepath"); + } + + @Test + public void testGetDefaultLockLeasePeriod() { + MusicUtil.setDefaultLockLeasePeriod(5000); + assertEquals(MusicUtil.getDefaultLockLeasePeriod(),5000); + } + + @Test + public void testIsDebug() { + MusicUtil.setDebug(true); + assertTrue(MusicUtil.isDebug()); + } + + @Test + public void testGetVersion() { + MusicUtil.setVersion("1.0.0"); + assertEquals(MusicUtil.getVersion(),"1.0.0"); + } + + /*@Test + public void testGetMyZkHost() { + MusicUtil.setMyZkHost("10.0.0.2"); + assertEquals(MusicUtil.getMyZkHost(),"10.0.0.2"); + }*/ + + @Test + public void testGetMyCassaHost() { + MusicUtil.setMyCassaHost("10.0.0.2"); + assertEquals(MusicUtil.getMyCassaHost(),"10.0.0.2"); + } + + @Test + public void testGetDefaultMusicIp() { + MusicUtil.setDefaultMusicIp("10.0.0.2"); + assertEquals(MusicUtil.getDefaultMusicIp(),"10.0.0.2"); + } + +// @Test +// public void testGetTestType() { +// fail("Not yet implemented"); // TODO +// } + + @Test + public void testIsValidQueryObject() { + PreparedQueryObject myQueryObject = new PreparedQueryObject(); + myQueryObject.appendQueryString("select * from apple where type = ?"); + myQueryObject.addValue("macintosh"); + assertTrue(MusicUtil.isValidQueryObject(true,myQueryObject)); + + myQueryObject.appendQueryString("select * from apple"); + assertTrue(MusicUtil.isValidQueryObject(false,myQueryObject)); + + myQueryObject.appendQueryString("select * from apple where type = ?"); + assertFalse(MusicUtil.isValidQueryObject(true,myQueryObject)); + + myQueryObject = new PreparedQueryObject(); + myQueryObject.appendQueryString(""); + System.out.println("#######" + myQueryObject.getQuery().isEmpty()); + assertFalse(MusicUtil.isValidQueryObject(false,myQueryObject)); + + + } + + @Test + public void testConvertToCQLDataType() throws Exception { + Map myMap = new HashMap(); + myMap.put("name","tom"); + assertEquals(MusicUtil.convertToCQLDataType(DataType.varchar(),"Happy People"),"'Happy People'"); + assertEquals(MusicUtil.convertToCQLDataType(DataType.uuid(),UUID.fromString("29dc2afa-c2c0-47ae-afae-e72a645308ab")),"29dc2afa-c2c0-47ae-afae-e72a645308ab"); + assertEquals(MusicUtil.convertToCQLDataType(DataType.blob(),"Hi"),"Hi"); + assertEquals(MusicUtil.convertToCQLDataType(DataType.map(DataType.varchar(),DataType.varchar()),myMap),"{'name':'tom'}"); + } + + @Test + public void testConvertToActualDataType() throws Exception { + assertEquals(MusicUtil.convertToActualDataType(DataType.varchar(),"Happy People"),"Happy People"); + assertEquals(MusicUtil.convertToActualDataType(DataType.uuid(),"29dc2afa-c2c0-47ae-afae-e72a645308ab"),UUID.fromString("29dc2afa-c2c0-47ae-afae-e72a645308ab")); + assertEquals(MusicUtil.convertToActualDataType(DataType.varint(),"1234"),BigInteger.valueOf(Long.parseLong("1234"))); + assertEquals(MusicUtil.convertToActualDataType(DataType.bigint(),"123"),Long.parseLong("123")); + assertEquals(MusicUtil.convertToActualDataType(DataType.cint(),"123"),Integer.parseInt("123")); + assertEquals(MusicUtil.convertToActualDataType(DataType.cfloat(),"123.01"),Float.parseFloat("123.01")); + assertEquals(MusicUtil.convertToActualDataType(DataType.cdouble(),"123.02"),Double.parseDouble("123.02")); + assertEquals(MusicUtil.convertToActualDataType(DataType.cboolean(),"true"),Boolean.parseBoolean("true")); + Map myMap = new HashMap(); + myMap.put("name","tom"); + assertEquals(MusicUtil.convertToActualDataType(DataType.map(DataType.varchar(),DataType.varchar()),myMap),myMap); + + } + + @Test + public void testJsonMaptoSqlString() throws Exception { + Map myMap = new HashMap<>(); + myMap.put("name","tom"); + myMap.put("value",5); + String result = MusicUtil.jsonMaptoSqlString(myMap,","); + assertTrue(result.contains("name")); + assertTrue(result.contains("value")); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/ResultTypeTest.java b/jar/src/test/java/org/onap/music/unittests/ResultTypeTest.java new file mode 100644 index 00000000..012629e0 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/ResultTypeTest.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.onap.music.main.ResultType; + +public class ResultTypeTest { + + @Test + public void testResultType() { + assertEquals("SUCCESS",ResultType.SUCCESS.name()); + assertEquals("FAILURE",ResultType.FAILURE.name()); + } + + @Test + public void testGetResult() { + assertEquals("Success",ResultType.SUCCESS.getResult()); + assertEquals("Failure",ResultType.FAILURE.getResult()); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/ReturnTypeTest.java b/jar/src/test/java/org/onap/music/unittests/ReturnTypeTest.java new file mode 100644 index 00000000..c22b0155 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/ReturnTypeTest.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.*; +import java.util.Map; +import org.apache.tools.ant.filters.TokenFilter.ContainsString; +import org.hamcrest.core.AnyOf; +import org.junit.Test; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; + +public class ReturnTypeTest { + + @Test + public void testReturnType() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + assertEquals(result.getMessage(),"message"); + assertEquals(result.getResult(),ResultType.SUCCESS); + } + + @Test + public void testTimingInfo() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + result.setTimingInfo("123"); + assertEquals(result.getTimingInfo(),"123"); + } + + @Test + public void testGetResult() { + ReturnType result = new ReturnType(ResultType.FAILURE,"message"); + assertEquals(result.getResult(),ResultType.FAILURE); + } + + @Test + public void testGetMessage() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + result.setMessage("NewMessage"); + assertEquals(result.getMessage(),"NewMessage"); + } + + @Test + public void testToJson() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + String myJson = result.toJson(); + assertTrue(myJson.contains("message")); + } + + @Test + public void testToString() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + String test = result.toString(); + assertTrue(test.contains("message")); + } + + @Test + public void testToMap() { + ReturnType result = new ReturnType(ResultType.SUCCESS,"message"); + Map myMap = result.toMap(); + assertTrue(myMap.containsKey("message")); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/TestLockStore.java b/jar/src/test/java/org/onap/music/unittests/TestLockStore.java new file mode 100644 index 00000000..4dbc7b4f --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/TestLockStore.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import org.apache.log4j.Logger; +import org.onap.music.lockingservice.MusicLockingService; + +public class TestLockStore { + final static Logger logger = Logger.getLogger(TestLockStore.class); + + public static void main(String[] args) throws Exception { + String lockName = "/achristmkllas"; + MusicLockingService ml = new MusicLockingService(); + ml.deleteLock(lockName); + + + logger.info("lockname:" + lockName); + + String lockId1 = ml.createLockId(lockName); + logger.info("lockId1 " + lockId1); + logger.info(ml.isMyTurn(lockId1)); + + String lockId2 = ml.createLockId(lockName); + logger.info("lockId2 " + lockId2); + logger.info("check " + ml.isMyTurn("$bank$x-94608776321630264-0000000000")); + logger.info(ml.isMyTurn(lockId2)); + + // zkClient.unlock(lockId1); + // logger.info(ml.lock(lockId2)); + // zkClient.unlock(lockId2); + } + + +} diff --git a/jar/src/test/java/org/onap/music/unittests/TestMusicCore.java b/jar/src/test/java/org/onap/music/unittests/TestMusicCore.java new file mode 100644 index 00000000..e798aaf1 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/TestMusicCore.java @@ -0,0 +1,489 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests; + +import static org.junit.Assert.*; +import static org.onap.music.main.MusicCore.mDstoreHandle; +import static org.onap.music.main.MusicCore.mLockHandle; + +import org.apache.zookeeper.KeeperException.NoNodeException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.lockingservice.MusicLockState; +import org.onap.music.lockingservice.MusicLockingService; +import org.onap.music.lockingservice.MusicLockState.LockStatus; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; +import org.onap.music.main.MusicCore.Condition; +import org.onap.music.datastore.MusicDataStore; +import org.onap.music.datastore.PreparedQueryObject; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Session; + +@RunWith(MockitoJUnitRunner.class) +public class TestMusicCore { + + @Mock + private Condition condition; + + @Mock + private ResultSet rs; + + @Mock + private PreparedQueryObject preparedQueryObject; + + @Mock + private Session session; + + @Before + public void setUp() { + mLockHandle = Mockito.mock(MusicLockingService.class); + + } + + @Test + public void testCreateLockReferenceforvalidlock() { + Mockito.when(mLockHandle.createLockId("/" + "test")).thenReturn("lock"); + String lockId = MusicCore.createLockReference("test"); + assertEquals("lock", lockId); + Mockito.verify(mLockHandle).createLockId("/" + "test"); + } + + @Test + public void testIsTableOrKeySpaceLock() { + Boolean result = MusicCore.isTableOrKeySpaceLock("ks1.tn1"); + assertTrue(result); + } + + @Test + public void testIsTableOrKeySpaceLockwithPrimarykey() { + Boolean result = MusicCore.isTableOrKeySpaceLock("ks1.tn1.pk1"); + assertFalse(result); + } + + @Test + public void testGetMusicLockState() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + Mockito.when(mLockHandle.getLockState("ks1.tb1.pk1")).thenReturn(musicLockState); + MusicLockState mls = MusicCore.getMusicLockState("ks1.tb1.pk1"); + assertEquals(musicLockState, mls); + Mockito.verify(mLockHandle).getLockState("ks1.tb1.pk1"); + } + + @Test + public void testAcquireLockifisMyTurnTrue() throws MusicLockingException { + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType lock = MusicCore.acquireLock("ks1.tn1", "id1"); + assertEquals(lock.getResult(), ResultType.SUCCESS); + Mockito.verify(mLockHandle).isMyTurn("id1"); + } + + @Test + public void testAcquireLockifisMyTurnFalse() throws MusicLockingException { + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(false); + ReturnType lock = MusicCore.acquireLock("ks1.ts1", "id1"); + assertEquals(lock.getResult(), ResultType.FAILURE); + Mockito.verify(mLockHandle).isMyTurn("id1"); + } + + @Test + public void testAcquireLockifisMyTurnTrueandIsTableOrKeySpaceLockTrue() throws MusicLockingException { + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType lock = MusicCore.acquireLock("ks1.tn1", "id1"); + assertEquals(lock.getResult(), ResultType.SUCCESS); + Mockito.verify(mLockHandle).isMyTurn("id1"); + } + + @Test + public void testAcquireLockifisMyTurnTrueandIsTableOrKeySpaceLockFalseandHaveLock() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + ReturnType lock = MusicCore.acquireLock("ks1.tn1.pk1", "id1"); + assertEquals(lock.getResult(), ResultType.SUCCESS); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testAcquireLockifisMyTurnTrueandIsTableOrKeySpaceLockFalseandDontHaveLock() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id2"); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + ReturnType lock = MusicCore.acquireLock("ks1.tn1.pk1", "id1"); + assertEquals(lock.getResult(), ResultType.SUCCESS); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testAcquireLockifLockRefDoesntExist() throws MusicLockingException { + Mockito.when(mLockHandle.lockIdExists("bs1")).thenReturn(false); + ReturnType lock = MusicCore.acquireLock("ks1.ts1", "bs1"); + assertEquals(lock.getResult(), ResultType.FAILURE); + assertEquals(lock.getMessage(), "Lockid doesn't exist"); + Mockito.verify(mLockHandle).lockIdExists("bs1"); + } + + @Test + public void testAcquireLockWithLeasewithLease() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + musicLockState.setLeasePeriod(0); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType actualResult = MusicCore.acquireLockWithLease("ks1.tn1.pk1", "id1", 6000); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testAcquireLockWithLeasewithException() throws MusicLockingException { + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "failure"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenThrow(new MusicLockingException()); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType actualResult = MusicCore.acquireLockWithLease("ks1.tn1.pk1", "id1", 6000); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testAcquireLockWithLeasewithLockStatusLOCKED() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType actualResult = MusicCore.acquireLockWithLease("ks1.tn1.pk1", "id1", 6000); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testAcquireLockWithLeasewithLockStatusUNLOCKED() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + ReturnType actualResult = MusicCore.acquireLockWithLease("ks1.tn1.pk1", "id1", 6000); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + + } + + @Test + public void testAcquireLockWithLeaseIfNotMyTurn() throws MusicLockingException { + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "Failure"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(false); + ReturnType actualResult = MusicCore.acquireLockWithLease("ks1.tn1.pk1", "id1", 6000); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle).getLockState("ks1.tn1.pk1"); + } + + @Test + public void testQuorumGet() throws MusicServiceException, MusicQueryException { + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + mDstoreHandle = Mockito.mock(MusicDataStore.class); + rs = Mockito.mock(ResultSet.class); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mDstoreHandle.executeCriticalGet(preparedQueryObject)).thenReturn(rs); + ResultSet rs1 = MusicCore.quorumGet(preparedQueryObject); + assertNotNull(rs1); + } + + @Test + public void testGetLockNameFromId() { + String lockname = MusicCore.getLockNameFromId("lockName$id"); + assertEquals("lockName", lockname); + } + + @Test + public void testDestroyLockRef() throws NoNodeException { + Mockito.doNothing().when(mLockHandle).unlockAndDeleteId("id1"); + MusicCore.destroyLockRef("id1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).unlockAndDeleteId("id1"); + } + + @Test + public void testreleaseLockwithvoluntaryReleaseTrue() throws NoNodeException { + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id2"); + Mockito.doNothing().when(mLockHandle).unlockAndDeleteId("id1"); + MusicLockState musicLockState1 = MusicCore.releaseLock("id1", true); + assertEquals(musicLockState.getLockStatus(), musicLockState1.getLockStatus()); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).unlockAndDeleteId("id1"); + } + + @Test + public void testreleaseLockwithvoluntaryReleaseFalse() throws NoNodeException { + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id2"); + Mockito.doNothing().when(mLockHandle).unlockAndDeleteId("id1"); + MusicLockState musicLockState1 = MusicCore.releaseLock("id1", false); + assertEquals(musicLockState.getLockStatus(), musicLockState1.getLockStatus()); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).unlockAndDeleteId("id1"); + } + + @Test + public void testDeleteLock() throws MusicLockingException { + Mockito.doNothing().when(mLockHandle).deleteLock("/" + "id1"); + MusicCore.deleteLock("id1"); + Mockito.verify(mLockHandle).deleteLock("/" + "id1"); + } + + /* + * @Test public void testNonKeyRelatedPut() throws Exception { mDstoreHandle = + * Mockito.mock(MusicDataStore.class); Mockito.when(mDstoreHandle.executePut("qu1", + * "consistency")).thenReturn(true); Boolean result = MusicCore.nonKeyRelatedPut("qu1", + * "consistency"); assertTrue(result); Mockito.verify(mDstoreHandle).executePut("qu1", + * "consistency"); } + */ + + @Test + public void testEventualPutPreparedQuery() throws MusicServiceException, MusicQueryException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mDstoreHandle.executePut(preparedQueryObject, "eventual")).thenReturn(true); + ReturnType actualResult = MusicCore.eventualPut(preparedQueryObject); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, "eventual"); + } + + @Test + public void testEventualPutPreparedQuerywithResultFalse() + throws MusicServiceException, MusicQueryException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "Failure"); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mDstoreHandle.executePut(preparedQueryObject, "eventual")).thenReturn(false); + ReturnType actualResult = MusicCore.eventualPut(preparedQueryObject); + assertEquals(expectedResult.getResult(), actualResult.getResult()); + Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, "eventual"); + //Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, MusicUtil.EVENTUAL); + } + + @Test + public void testCriticalPutPreparedQuerywithValidLockId() + throws Exception { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + Mockito.when(condition.testCondition()).thenReturn(true); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + Mockito.when(mDstoreHandle.executePut(preparedQueryObject, "critical")).thenReturn(true); + ReturnType returnType = MusicCore.criticalPut("ks1", "tn1", "pk1", preparedQueryObject, + "id1", condition); + assertEquals(expectedResult.getResult(), returnType.getResult()); + Mockito.verify(condition).testCondition(); + Mockito.verify(mLockHandle).getLockState("ks1" + "." + "tn1" + "." + "pk1"); + Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, "critical"); + } + + @Test + public void testCriticalPutPreparedQuerywithInvalidLockId() throws MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id2"); + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "Failure"); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + ReturnType returnType = MusicCore.criticalPut("ks1", "tn1", "pk1", preparedQueryObject, + "id1", condition); + assertEquals(expectedResult.getResult(), returnType.getResult()); + Mockito.verify(mLockHandle).getLockState("ks1" + "." + "tn1" + "." + "pk1"); + } + + @Test + public void testCriticalPutPreparedQuerywithvalidLockIdandTestConditionFalse() throws Exception { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + Mockito.when(condition.testCondition()).thenReturn(false); + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "Failure"); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + ReturnType returnType = MusicCore.criticalPut("ks1", "tn1", "pk1", preparedQueryObject, + "id1", condition); + assertEquals(expectedResult.getResult(), returnType.getResult()); + Mockito.verify(condition).testCondition(); + Mockito.verify(mLockHandle).getLockState("ks1" + "." + "tn1" + "." + "pk1"); + } + + @Test + public void testNonKeyRelatedPutPreparedQuery() throws Exception { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mDstoreHandle.executePut(preparedQueryObject, "consistency")).thenReturn(true); + ResultType result = MusicCore.nonKeyRelatedPut(preparedQueryObject, "consistency"); + assertEquals(ResultType.SUCCESS, result); + Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, "consistency"); + } + + @Test + public void testAtomicPutPreparedQuery() throws Exception { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + Mockito.when(mLockHandle.createLockId("/" + "ks1.tn1.pk1")).thenReturn("id1"); + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + ReturnType expectedResult = new ReturnType(ResultType.SUCCESS, "Succes"); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + Mockito.when(condition.testCondition()).thenReturn(true); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + Mockito.when(mDstoreHandle.executePut(preparedQueryObject, "critical")).thenReturn(true); + ReturnType returnType = + MusicCore.atomicPut("ks1", "tn1", "pk1", preparedQueryObject, condition); + assertEquals(expectedResult.getResult(), returnType.getResult()); + Mockito.verify(mLockHandle).createLockId("/" + "ks1.tn1.pk1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(condition).testCondition(); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()) + .getLockState("ks1" + "." + "tn1" + "." + "pk1"); + Mockito.verify(mDstoreHandle).executePut(preparedQueryObject, "critical"); + } + + @Test + public void testAtomicPutPreparedQuerywithAcquireLockWithLeaseFalse() throws MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + Mockito.when(mLockHandle.createLockId("/" + "ks1.tn1.pk1")).thenReturn("id1"); + ReturnType expectedResult = new ReturnType(ResultType.FAILURE, "Failure"); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(false); + ReturnType returnType = + MusicCore.atomicPut("ks1", "tn1", "pk1", preparedQueryObject, condition); + assertEquals(expectedResult.getResult(), returnType.getResult()); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle).createLockId("/" + "ks1.tn1.pk1"); + } + + @Test + public void testAtomicGetPreparedQuery() throws MusicServiceException, MusicQueryException, MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + rs = Mockito.mock(ResultSet.class); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mLockHandle.createLockId("/" + "ks1.tn1.pk1")).thenReturn("id1"); + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + Mockito.when(mLockHandle.getLockState("ks1.tn1.pk1")).thenReturn(musicLockState); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(true); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + Mockito.when(mDstoreHandle.executeCriticalGet(preparedQueryObject)).thenReturn(rs); + ResultSet rs1 = MusicCore.atomicGet("ks1", "tn1", "pk1", preparedQueryObject); + assertNotNull(rs1); + Mockito.verify(mLockHandle).createLockId("/" + "ks1.tn1.pk1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()).getLockState("ks1.tn1.pk1"); + Mockito.verify(mLockHandle).isMyTurn("id1"); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()) + .getLockState("ks1" + "." + "tn1" + "." + "pk1"); + Mockito.verify(mDstoreHandle).executeCriticalGet(preparedQueryObject); + } + + @Test + public void testAtomicGetPreparedQuerywithAcquireLockWithLeaseFalse() + throws MusicServiceException, MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + rs = Mockito.mock(ResultSet.class); + Mockito.when(mLockHandle.createLockId("/" + "ks1.tn1.pk1")).thenReturn("id1"); + Mockito.when(mLockHandle.isMyTurn("id1")).thenReturn(false); + ResultSet rs1 = MusicCore.atomicGet("ks1", "tn1", "pk1", preparedQueryObject); + assertNull(rs1); + Mockito.verify(mLockHandle).createLockId("/" + "ks1.tn1.pk1"); + Mockito.verify(mLockHandle).isMyTurn("id1"); + } + + @Test + public void testGetPreparedQuery() throws MusicServiceException, MusicQueryException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + rs = Mockito.mock(ResultSet.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mDstoreHandle.executeEventualGet(preparedQueryObject)).thenReturn(rs); + ResultSet rs1 = MusicCore.get(preparedQueryObject); + assertNotNull(rs1); + Mockito.verify(mDstoreHandle).executeEventualGet(preparedQueryObject); + + } + + @Test + public void testcriticalGetPreparedQuery() throws MusicServiceException, MusicQueryException, MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id1"); + rs = Mockito.mock(ResultSet.class); + session = Mockito.mock(Session.class); + Mockito.when(mDstoreHandle.getSession()).thenReturn(session); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + Mockito.when(mDstoreHandle.executeCriticalGet(preparedQueryObject)).thenReturn(rs); + ResultSet rs1 = MusicCore.criticalGet("ks1", "tn1", "pk1", preparedQueryObject, "id1"); + assertNotNull(rs1); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()) + .getLockState("ks1" + "." + "tn1" + "." + "pk1"); + Mockito.verify(mDstoreHandle).executeCriticalGet(preparedQueryObject); + } + + @Test + public void testcriticalGetPreparedQuerywithInvalidLockId() throws MusicServiceException, MusicLockingException { + mDstoreHandle = Mockito.mock(MusicDataStore.class); + preparedQueryObject = Mockito.mock(PreparedQueryObject.class); + MusicLockState musicLockState = new MusicLockState(LockStatus.UNLOCKED, "id2"); + Mockito.when(mLockHandle.getLockState("ks1" + "." + "tn1" + "." + "pk1")) + .thenReturn(musicLockState); + ResultSet rs1 = MusicCore.criticalGet("ks1", "tn1", "pk1", preparedQueryObject, "id1"); + assertNull(rs1); + Mockito.verify(mLockHandle, Mockito.atLeastOnce()) + .getLockState("ks1" + "." + "tn1" + "." + "pk1"); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/TestMusicCoreIntegration.java b/jar/src/test/java/org/onap/music/unittests/TestMusicCoreIntegration.java new file mode 100644 index 00000000..d327d0f0 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/TestMusicCoreIntegration.java @@ -0,0 +1,176 @@ +/* + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT 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.music.unittests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.util.List; +import org.apache.curator.test.TestingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.lockingservice.MusicLockState; +import org.onap.music.lockingservice.MusicLockingService; +import org.onap.music.lockingservice.MusicLockState.LockStatus; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.main.ReturnType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestMusicCoreIntegration { + + static TestingServer zkServer; + static PreparedQueryObject testObject; + static String lockId = null; + static String lockName = "ks1.tb1.pk1"; + + @BeforeClass + public static void init() throws Exception { + try { + MusicCore.mDstoreHandle = CassandraCQL.connectToEmbeddedCassandra(); + zkServer = new TestingServer(2181, new File("/tmp/zk")); + MusicCore.mLockHandle = new MusicLockingService(); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("####Port:" + zkServer.getPort()); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + System.out.println("After class"); + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.dropKeyspace); + MusicCore.eventualPut(testObject); + MusicCore.deleteLock(lockName); + MusicCore.mDstoreHandle.close(); + MusicCore.mLockHandle.getzkLockHandle().close(); + MusicCore.mLockHandle.close(); + zkServer.stop(); + + } + + @Test + public void Test1_SetUp() throws MusicServiceException, MusicQueryException { + MusicCore.mLockHandle = new MusicLockingService(); + ResultType result = ResultType.FAILURE; + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.createKeySpace); + MusicCore.eventualPut(testObject); + testObject = new PreparedQueryObject(); + testObject.appendQueryString(CassandraCQL.createTableEmployees); + result = MusicCore.nonKeyRelatedPut(testObject, MusicUtil.EVENTUAL); + assertEquals(ResultType.SUCCESS, result); + } + + @Test + public void Test2_atomicPut() throws Exception { + testObject = new PreparedQueryObject(); + testObject = CassandraCQL.setPreparedInsertQueryObject1(); + ReturnType returnType = MusicCore.atomicPut("testCassa", "employees", "Mr Test one", + testObject, null); + assertEquals(ResultType.SUCCESS, returnType.getResult()); + } + + @Test + public void Test3_atomicPutWithDeleteLock() throws Exception { + testObject = new PreparedQueryObject(); + testObject = CassandraCQL.setPreparedInsertQueryObject2(); + ReturnType returnType = MusicCore.atomicPutWithDeleteLock("testCassa", "employees", + "Mr Test two", testObject, null); + assertEquals(ResultType.SUCCESS, returnType.getResult()); + } + + @Test + public void Test4_atomicGetWithDeleteLock() throws Exception { + testObject = new PreparedQueryObject(); + testObject = CassandraCQL.setPreparedGetQuery(); + ResultSet resultSet = MusicCore.atomicGetWithDeleteLock("testCassa", "employees", + "Mr Test one", testObject); + List rows = resultSet.all(); + assertEquals(1, rows.size()); + } + + @Test + public void Test5_atomicGet() throws Exception { + testObject = new PreparedQueryObject(); + testObject = CassandraCQL.setPreparedGetQuery(); + ResultSet resultSet = + MusicCore.atomicGet("testCassa", "employees", "Mr Test two", testObject); + List rows = resultSet.all(); + assertEquals(1, rows.size()); + } + + @Test + public void Test6_createLockReference() throws Exception { + lockId = MusicCore.createLockReference(lockName); + assertNotNull(lockId); + } + + @Test + public void Test7_acquireLockwithLease() throws Exception { + ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, 1000); + assertEquals(ResultType.SUCCESS, lockLeaseStatus.getResult()); + } + + @Test + public void Test8_acquireLock() throws Exception { + ReturnType lockStatus = MusicCore.acquireLock(lockName, lockId); + assertEquals(ResultType.SUCCESS, lockStatus.getResult()); + } + + @Test + public void Test9_release() throws Exception { + MusicLockState musicLockState = new MusicLockState(LockStatus.LOCKED, "id1"); + MusicLockState musicLockState1 = new MusicLockState(LockStatus.UNLOCKED, "id1"); + MusicCore.whoseTurnIsIt(lockName); + MusicLockState mls = MusicCore.getMusicLockState(lockName); + boolean voluntaryRelease = true; + MusicLockState mls1 = MusicCore.releaseLock(lockId, voluntaryRelease); + assertEquals(musicLockState.getLockStatus(), mls.getLockStatus()); + assertEquals(musicLockState1.getLockStatus(), mls1.getLockStatus()); + } + + @Test + public void Test10_create() { + MusicCore.pureZkCreate("/nodeName"); + } + + @Test + public void Test11_write() { + MusicCore.pureZkWrite("nodeName", "I'm Test".getBytes()); + } + + @Test + public void Test12_read() { + byte[] data = MusicCore.pureZkRead("nodeName"); + String data1 = new String(data); + assertEquals("I'm Test", data1); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/TestRestMusicData.java b/jar/src/test/java/org/onap/music/unittests/TestRestMusicData.java new file mode 100644 index 00000000..febf6c76 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/TestRestMusicData.java @@ -0,0 +1,718 @@ +/* + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT 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.music.unittests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.apache.curator.test.TestingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.mindrot.jbcrypt.BCrypt; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JsonDelete; +import org.onap.music.datastore.jsonobjects.JsonInsert; +import org.onap.music.datastore.jsonobjects.JsonKeySpace; +import org.onap.music.datastore.jsonobjects.JsonOnboard; +import org.onap.music.datastore.jsonobjects.JsonSelect; +import org.onap.music.datastore.jsonobjects.JsonTable; +import org.onap.music.datastore.jsonobjects.JsonUpdate; +import org.onap.music.lockingservice.MusicLockingService; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +import org.onap.music.rest.RestMusicAdminAPI; +import org.onap.music.rest.RestMusicDataAPI; +import org.onap.music.rest.RestMusicLocksAPI; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.sun.jersey.core.util.MultivaluedMapImpl; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@RunWith(MockitoJUnitRunner.class) +public class TestRestMusicData { + + RestMusicDataAPI data = new RestMusicDataAPI(); + RestMusicAdminAPI admin = new RestMusicAdminAPI(); + RestMusicLocksAPI lock = new RestMusicLocksAPI(); + static PreparedQueryObject testObject; + static TestingServer zkServer; + + @Mock + HttpServletResponse http; + + @Mock + UriInfo info; + + static String appName = "TestApp"; + static String userId = "TestUser"; + static String password = "TestPassword"; + static boolean isAAF = false; + static UUID uuid = UUID.fromString("abc66ccc-d857-4e90-b1e5-df98a3d40ce6"); + static String keyspaceName = "testCassa"; + static String tableName = "employees"; + static String xLatestVersion = "X-latestVersion"; + static String onboardUUID = null; + static String lockId = null; + static String lockName = "testCassa.employees.sample3"; + + @BeforeClass + public static void init() throws Exception { + try { + MusicCore.mDstoreHandle = CassandraCQL.connectToEmbeddedCassandra(); + zkServer = new TestingServer(2181, new File("/tmp/zk")); + MusicCore.mLockHandle = new MusicLockingService(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + System.out.println("After class"); + testObject = new PreparedQueryObject(); + testObject.appendQueryString("DROP KEYSPACE IF EXISTS " + keyspaceName); + MusicCore.eventualPut(testObject); + testObject = new PreparedQueryObject(); + testObject.appendQueryString("DROP KEYSPACE IF EXISTS admin"); + MusicCore.eventualPut(testObject); + MusicCore.mDstoreHandle.close(); + MusicCore.mLockHandle.getzkLockHandle().close(); + MusicCore.mLockHandle.close(); + zkServer.stop(); + } + + @Test + public void Test1_createKeyspace() throws Exception { + testObject = new PreparedQueryObject(); + testObject.appendQueryString("CREATE KEYSPACE admin WITH REPLICATION = " + + "{'class' : 'SimpleStrategy' , " + + "'replication_factor': 1} AND DURABLE_WRITES = true"); + MusicCore.eventualPut(testObject); + testObject = new PreparedQueryObject(); + testObject.appendQueryString( + "CREATE TABLE admin.keyspace_master (" + " uuid uuid, keyspace_name text," + + " application_name text, is_api boolean," + + " password text, username text," + + " is_aaf boolean, PRIMARY KEY (uuid)\n" + ");"); + MusicCore.eventualPut(testObject); + + testObject = new PreparedQueryObject(); + testObject.appendQueryString( + "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " + + "password, username, is_aaf) VALUES (?,?,?,?,?,?,?)"); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + MusicCore.eventualPut(testObject); + + testObject = new PreparedQueryObject(); + testObject.appendQueryString( + "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " + + "password, username, is_aaf) VALUES (?,?,?,?,?,?,?)"); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString("bbc66ccc-d857-4e90-b1e5-df98a3d40de6"))); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), "TestApp1")); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), "TestUser1")); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + MusicCore.eventualPut(testObject); + + testObject = new PreparedQueryObject(); + testObject.appendQueryString( + "select uuid from admin.keyspace_master where application_name = ? allow filtering"); + testObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + ResultSet rs = MusicCore.get(testObject); + List rows = rs.all(); + if (rows.size() > 0) { + System.out.println("#######UUID is:" + rows.get(0).getUUID("uuid")); + } + } + + @Test + public void Test2_createKeyspace() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + consistencyInfo.put("type", "eventual"); + replicationInfo.put("class", "SimpleStrategy"); + replicationInfo.put("replication_factor", 1); + jsonKeyspace.setConsistencyInfo(consistencyInfo); + jsonKeyspace.setDurabilityOfWrites("true"); + jsonKeyspace.setKeyspaceName(keyspaceName); + jsonKeyspace.setReplicationInfo(replicationInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createKeySpace("1", "1", "1", null, appName, userId, + password, jsonKeyspace, keyspaceName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(200,response.getStatus()); + } + + @Test + public void Test2_createKeyspace0() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createKeySpace("1", "1", "1", null, appName, userId, + password, jsonKeyspace, keyspaceName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(400,response.getStatus()); + } +//MusicCore.autheticateUser + @Test + public void Test2_createKeyspace01() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + String appName1 = "test"; + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createKeySpace("1", "1", "1", null, appName1, userId, + password, jsonKeyspace, keyspaceName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(401,response.getStatus()); + } + + @Test + public void Test3_createKeyspace1() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + consistencyInfo.put("type", "eventual"); + replicationInfo.put("class", "SimpleStrategy"); + replicationInfo.put("replication_factor", 1); + jsonKeyspace.setConsistencyInfo(consistencyInfo); + jsonKeyspace.setDurabilityOfWrites("true"); + jsonKeyspace.setKeyspaceName("TestApp1"); + jsonKeyspace.setReplicationInfo(replicationInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createKeySpace("1", "1", "1", null, "TestApp1", + "TestUser1", password, jsonKeyspace, keyspaceName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(400,response.getStatus()); + } + + @Test + public void Test3_createTable() throws Exception { + JsonTable jsonTable = new JsonTable(); + Map consistencyInfo = new HashMap<>(); + Map fields = new HashMap<>(); + fields.put("uuid", "text"); + fields.put("emp_name", "text"); + fields.put("emp_salary", "varint"); + fields.put("PRIMARY KEY", "(emp_name)"); + consistencyInfo.put("type", "eventual"); + jsonTable.setConsistencyInfo(consistencyInfo); + jsonTable.setKeyspaceName(keyspaceName); + jsonTable.setPrimaryKey("emp_name"); + jsonTable.setTableName(tableName); + jsonTable.setFields(fields); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonTable, keyspaceName, tableName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(200, response.getStatus()); + } + + // Improper Auth + @Test + public void Test3_createTable1() throws Exception { + JsonTable jsonTable = new JsonTable(); + Map consistencyInfo = new HashMap<>(); + Map fields = new HashMap<>(); + fields.put("uuid", "text"); + fields.put("emp_name", "text"); + fields.put("emp_salary", "varint"); + fields.put("PRIMARY KEY", "(emp_name)"); + consistencyInfo.put("type", "eventual"); + jsonTable.setConsistencyInfo(consistencyInfo); + jsonTable.setKeyspaceName(keyspaceName); + jsonTable.setPrimaryKey("emp_name"); + jsonTable.setTableName(tableName); + jsonTable.setFields(fields); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, "wrong", + jsonTable, keyspaceName, tableName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(401, response.getStatus()); + } + + // Improper keyspace + @Test + public void Test3_createTable2() throws Exception { + JsonTable jsonTable = new JsonTable(); + Map consistencyInfo = new HashMap<>(); + Map fields = new HashMap<>(); + fields.put("uuid", "text"); + fields.put("emp_name", "text"); + fields.put("emp_salary", "varint"); + fields.put("PRIMARY KEY", "(emp_name)"); + consistencyInfo.put("type", "eventual"); + jsonTable.setConsistencyInfo(consistencyInfo); + jsonTable.setKeyspaceName(keyspaceName); + jsonTable.setPrimaryKey("emp_name"); + jsonTable.setTableName(tableName); + jsonTable.setFields(fields); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.createTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonTable, "wrong", tableName); + System.out.println("#######status is " + response.getStatus()); + System.out.println("Entity" + response.getEntity()); + assertEquals(401, response.getStatus()); + } + + + + @Test + public void Test4_insertIntoTable() throws Exception { + JsonInsert jsonInsert = new JsonInsert(); + Map consistencyInfo = new HashMap<>(); + Map values = new HashMap<>(); + values.put("uuid", "cfd66ccc-d857-4e90-b1e5-df98a3d40cd6"); + values.put("emp_name", "testName"); + values.put("emp_salary", 500); + consistencyInfo.put("type", "eventual"); + jsonInsert.setConsistencyInfo(consistencyInfo); + jsonInsert.setKeyspaceName(keyspaceName); + jsonInsert.setTableName(tableName); + jsonInsert.setValues(values); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.insertIntoTable("1", "1", "1", "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, password, jsonInsert, keyspaceName, tableName); + assertEquals(200, response.getStatus()); + } + + @Test + public void Test4_insertIntoTable2() throws Exception { + JsonInsert jsonInsert = new JsonInsert(); + Map consistencyInfo = new HashMap<>(); + Map values = new HashMap<>(); + values.put("uuid", "cfd66ccc-d857-4e90-b1e5-df98a3d40cd6"); + values.put("emp_name", "test1"); + values.put("emp_salary", 1500); + consistencyInfo.put("type", "eventual"); + jsonInsert.setConsistencyInfo(consistencyInfo); + jsonInsert.setKeyspaceName(keyspaceName); + jsonInsert.setTableName(tableName); + jsonInsert.setValues(values); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.insertIntoTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonInsert, keyspaceName, tableName); + assertEquals(200, response.getStatus()); + } + + // Auth Error + @Test + public void Test4_insertIntoTable3() throws Exception { + JsonInsert jsonInsert = new JsonInsert(); + Map consistencyInfo = new HashMap<>(); + Map values = new HashMap<>(); + values.put("uuid", "cfd66ccc-d857-4e90-b1e5-df98a3d40cd6"); + values.put("emp_name", "test1"); + values.put("emp_salary", 1500); + consistencyInfo.put("type", "eventual"); + jsonInsert.setConsistencyInfo(consistencyInfo); + jsonInsert.setKeyspaceName(keyspaceName); + jsonInsert.setTableName(tableName); + jsonInsert.setValues(values); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.insertIntoTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, "wrong", + jsonInsert, keyspaceName, tableName); + assertEquals(401, response.getStatus()); + } + + // Table wrong + @Test + public void Test4_insertIntoTable4() throws Exception { + JsonInsert jsonInsert = new JsonInsert(); + Map consistencyInfo = new HashMap<>(); + Map values = new HashMap<>(); + values.put("uuid", "cfd66ccc-d857-4e90-b1e5-df98a3d40cd6"); + values.put("emp_name", "test1"); + values.put("emp_salary", 1500); + consistencyInfo.put("type", "eventual"); + jsonInsert.setConsistencyInfo(consistencyInfo); + jsonInsert.setKeyspaceName(keyspaceName); + jsonInsert.setTableName(tableName); + jsonInsert.setValues(values); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.insertIntoTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonInsert, keyspaceName, "wrong"); + assertEquals(400, response.getStatus()); + } + + + + @Test + public void Test5_updateTable() throws Exception { + JsonUpdate jsonUpdate = new JsonUpdate(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + Map values = new HashMap<>(); + row.add("emp_name", "testName"); + values.put("emp_salary", 2500); + consistencyInfo.put("type", "atomic"); + jsonUpdate.setConsistencyInfo(consistencyInfo); + jsonUpdate.setKeyspaceName(keyspaceName); + jsonUpdate.setTableName(tableName); + jsonUpdate.setValues(values); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.updateTable("1", "1", "1", "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, + userId, password, jsonUpdate, keyspaceName, tableName, info); + assertEquals(200, response.getStatus()); + } + + @Test + public void Test6_select() throws Exception { + JsonSelect jsonSelect = new JsonSelect(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + row.add("emp_name", "testName"); + consistencyInfo.put("type", "atomic"); + jsonSelect.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.select("1", "1", "1","abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, password, keyspaceName, tableName, info); + HashMap> map = (HashMap>) response.getEntity(); + HashMap result = map.get("result"); + assertEquals("2500", ((HashMap) result.get("row 0")).get("emp_salary").toString()); + } + + @Test + public void Test6_selectCritical() throws Exception { + JsonInsert jsonInsert = new JsonInsert(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + row.add("emp_name", "testName"); + consistencyInfo.put("type", "atomic"); + jsonInsert.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.selectCritical("1", "1", "1","abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, password, jsonInsert, keyspaceName, tableName,info); + HashMap> map = (HashMap>) response.getEntity(); + HashMap result = map.get("result"); + assertEquals("2500", ((HashMap) result.get("row 0")).get("emp_salary").toString()); + } + + @Test + public void Test6_deleteFromTable() throws Exception { + JsonDelete jsonDelete = new JsonDelete(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + row.add("emp_name", "test1"); + consistencyInfo.put("type", "atomic"); + jsonDelete.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.deleteFromTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonDelete, keyspaceName, tableName, info); + assertEquals(200, response.getStatus()); + } + + // Values + @Test + public void Test6_deleteFromTable1() throws Exception { + JsonDelete jsonDelete = new JsonDelete(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + consistencyInfo.put("type", "atomic"); + jsonDelete.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.deleteFromTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + jsonDelete, keyspaceName, tableName, info); + assertEquals(400, response.getStatus()); + } + + // delObj + @Test + public void Test6_deleteFromTable2() throws Exception { + JsonDelete jsonDelete = new JsonDelete(); + Map consistencyInfo = new HashMap<>(); + MultivaluedMap row = new MultivaluedMapImpl(); + row.add("emp_name", "test1"); + consistencyInfo.put("type", "atomic"); + jsonDelete.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Mockito.when(info.getQueryParameters()).thenReturn(row); + Response response = data.deleteFromTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + null, keyspaceName, tableName, info); + assertEquals(400, response.getStatus()); + } + + @Test + public void Test7_dropTable() throws Exception { + JsonTable jsonTable = new JsonTable(); + Map consistencyInfo = new HashMap<>(); + consistencyInfo.put("type", "atomic"); + jsonTable.setConsistencyInfo(consistencyInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.dropTable("1", "1", "1", + "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", appName, userId, password, + keyspaceName, tableName); + assertEquals(200, response.getStatus()); + } + + @Test + public void Test8_deleteKeyspace() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + consistencyInfo.put("type", "eventual"); + replicationInfo.put("class", "SimpleStrategy"); + replicationInfo.put("replication_factor", 1); + jsonKeyspace.setConsistencyInfo(consistencyInfo); + jsonKeyspace.setDurabilityOfWrites("true"); + jsonKeyspace.setKeyspaceName("TestApp1"); + jsonKeyspace.setReplicationInfo(replicationInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.dropKeySpace("1", "1", "1", "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, password, keyspaceName); + assertEquals(200, response.getStatus()); + } + + @Test + public void Test8_deleteKeyspace2() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + consistencyInfo.put("type", "eventual"); + replicationInfo.put("class", "SimpleStrategy"); + replicationInfo.put("replication_factor", 1); + jsonKeyspace.setConsistencyInfo(consistencyInfo); + jsonKeyspace.setDurabilityOfWrites("true"); + jsonKeyspace.setKeyspaceName("TestApp1"); + jsonKeyspace.setReplicationInfo(replicationInfo); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.dropKeySpace("1", "1", "1", "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, "wrong", keyspaceName); + assertEquals(401, response.getStatus()); + } + + @Test + public void Test8_deleteKeyspace3() throws Exception { + JsonKeySpace jsonKeyspace = new JsonKeySpace(); + Map consistencyInfo = new HashMap<>(); + Map replicationInfo = new HashMap<>(); + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Response response = data.dropKeySpace("1", "1", "1", "abc66ccc-d857-4e90-b1e5-df98a3d40ce6", + appName, userId, password, keyspaceName); + assertEquals(400, response.getStatus()); + } + + + + @Test + public void Test6_onboard() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setAppname("TestApp2"); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setUserId("TestUser2"); + jsonOnboard.setPassword("TestPassword2"); + Map resultMap = (Map) admin.onboardAppWithMusic(jsonOnboard).getEntity(); + resultMap.containsKey("success"); + onboardUUID = resultMap.get("Generated AID").toString(); + assertEquals("Your application TestApp2 has been onboarded with MUSIC.", resultMap.get("Success")); + } + // Missing appname + @Test + public void Test6_onboard1() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setUserId("TestUser2"); + jsonOnboard.setPassword("TestPassword2"); + Map resultMap = (Map) admin.onboardAppWithMusic(jsonOnboard).getEntity(); + resultMap.containsKey("success"); + System.out.println("--->" + resultMap.toString()); + assertEquals("Unauthorized: Please check the request parameters. Some of the required values appName(ns), userId, password, isAAF are missing.", resultMap.get("Exception")); + } + + + @Test + public void Test7_onboardSearch() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setAppname("TestApp2"); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.getOnboardedInfoSearch(jsonOnboard).getEntity(); + resultMap.containsKey("success"); + assertEquals(MusicUtil.DEFAULTKEYSPACENAME, resultMap.get(onboardUUID)); + + } + + // Missing appname + @Test + public void Test7_onboardSearch1() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.getOnboardedInfoSearch(jsonOnboard).getEntity(); + System.out.println("--->" + resultMap.toString()); + resultMap.containsKey("success"); + assertEquals(MusicUtil.DEFAULTKEYSPACENAME, resultMap.get(onboardUUID)); + + } + + @Test + public void Test8_onboardUpdate() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setUserId("TestUser3"); + jsonOnboard.setPassword("TestPassword3"); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.updateOnboardApp(jsonOnboard).getEntity(); + System.out.println("--->" + resultMap.toString()); + resultMap.containsKey("success"); + assertEquals("Your application has been updated successfully", resultMap.get("Success")); + } + + // Aid null + @Test + public void Test8_onboardUpdate1() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setUserId("TestUser3"); + jsonOnboard.setPassword("TestPassword3"); + Map resultMap = (Map) admin.updateOnboardApp(jsonOnboard).getEntity(); + System.out.println("--->" + resultMap.toString()); + resultMap.containsKey("success"); + assertEquals("Please make sure Aid is present", resultMap.get("Exception")); + } + + // Appname not null + @Test + public void Test8_onboardUpdate2() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setAppname("TestApp2"); + jsonOnboard.setIsAAF("false"); + jsonOnboard.setUserId("TestUser3"); + jsonOnboard.setPassword("TestPassword3"); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.updateOnboardApp(jsonOnboard).getEntity(); + resultMap.containsKey("success"); + System.out.println("--->" + resultMap.toString()); + assertEquals("Application TestApp2 has already been onboarded. Please contact admin.", resultMap.get("Exception")); + } + + // All null + @Test + public void Test8_onboardUpdate3() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.updateOnboardApp(jsonOnboard).getEntity(); + assertTrue(resultMap.containsKey("Exception") ); + } + + @Test + public void Test9_onboardDelete() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + jsonOnboard.setAppname("TestApp2"); + jsonOnboard.setAid(onboardUUID); + Map resultMap = (Map) admin.deleteOnboardApp(jsonOnboard).getEntity(); + resultMap.containsKey("success"); + assertEquals("Your application has been deleted successfully", resultMap.get("Success")); + } + + @Test + public void Test9_onboardDelete1() throws Exception { + JsonOnboard jsonOnboard = new JsonOnboard(); + Map resultMap = (Map) admin.deleteOnboardApp(jsonOnboard).getEntity(); + assertTrue(resultMap.containsKey("Exception")); + } + + @Test + public void Test3_createLockReference() throws Exception { + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Map resultMap = (Map) lock.createLockReference(lockName,"1","1", null, appName, userId, password).getEntity(); + @SuppressWarnings("unchecked") + Map resultMap1 = (Map) resultMap.get("lock"); + lockId = (String) resultMap1.get("lock"); + assertEquals(ResultType.SUCCESS, resultMap.get("status")); + } + + @Test + public void Test4_accquireLock() throws Exception { + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Map resultMap = (Map) lock.accquireLock(lockId,"1","1", null, appName, userId, password).getEntity(); + assertEquals(ResultType.SUCCESS, resultMap.get("status")); + } + + @Test + public void Test5_currentLockHolder() throws Exception { + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Map resultMap = (Map) lock.currentLockHolder(lockName,"1","1", null, appName, userId, password).getEntity(); + assertEquals(ResultType.SUCCESS, resultMap.get("status")); + } + + @Test + public void Test7_unLock() throws Exception { + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Map resultMap = (Map) lock.unLock(lockId,"1","1", null, appName, userId, password).getEntity(); + assertEquals(ResultType.SUCCESS, resultMap.get("status")); + } + + @Test + public void Test8_delete() throws Exception { + Mockito.doNothing().when(http).addHeader(xLatestVersion, MusicUtil.getVersion()); + Map resultMap = (Map) lock.deleteLock(lockName,"1","1", null, appName, userId, password).getEntity(); + assertEquals(ResultType.SUCCESS, resultMap.get("status")); + } +} \ No newline at end of file diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/AAFResponseTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/AAFResponseTest.java new file mode 100644 index 00000000..354668c7 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/AAFResponseTest.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.ArrayList; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.AAFResponse; +import org.onap.music.datastore.jsonobjects.NameSpace; + +public class AAFResponseTest { + + @Test + public void testGetNs() { + NameSpace ns = new NameSpace(); + AAFResponse ar = new AAFResponse(); + ArrayList nsArray = new ArrayList<>(); + ns.setName("tom"); + ArrayList admin = new ArrayList<>(); + admin.add("admin1"); + ns.setAdmin(admin); + nsArray.add(ns); + ar.setNs(nsArray); + assertEquals("tom",ar.getNs().get(0).getName()); + assertEquals("admin1",ar.getNs().get(0).getAdmin().get(0)); + + } + +// @Test +// public void testSetNs() { +// fail("Not yet implemented"); +// } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonDeleteTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonDeleteTest.java new file mode 100644 index 00000000..885694bd --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonDeleteTest.java @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonDelete; + +public class JsonDeleteTest { + + JsonDelete jd = null; + + @Before + public void init() { + jd = new JsonDelete(); + } + + + @Test + public void testGetConditions() { + Map mapSo = new HashMap<>(); + mapSo = new HashMap<>(); + mapSo.put("key1","one"); + mapSo.put("key2","two"); + jd.setConditions(mapSo); + assertEquals("one",jd.getConditions().get("key1")); + } + + @Test + public void testGetConsistencyInfo() { + Map mapSs = new HashMap<>(); + mapSs = new HashMap<>(); + mapSs.put("key3","three"); + mapSs.put("key4","four"); + jd.setConsistencyInfo(mapSs); + assertEquals("three",jd.getConsistencyInfo().get("key3")); + } + + @Test + public void testGetColumns() { + ArrayList ary = new ArrayList<>(); + ary = new ArrayList<>(); + ary.add("e1"); + ary.add("e2"); + ary.add("e3"); + jd.setColumns(ary); + assertEquals("e1",jd.getColumns().get(0)); + } + + @Test + public void testGetTtl() { + jd.setTtl("2000"); + assertEquals("2000",jd.getTtl()); + } + + @Test + public void testGetTimestamp() { + jd.setTimestamp("20:00"); + assertEquals("20:00",jd.getTimestamp()); + + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonInsertTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonInsertTest.java new file mode 100644 index 00000000..69403cc7 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonInsertTest.java @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonInsert; + +public class JsonInsertTest { + + JsonInsert ji = new JsonInsert(); + + @Test + public void testGetKeyspaceName() { + ji.setKeyspaceName("keyspace"); + assertEquals("keyspace",ji.getKeyspaceName()); + } + + @Test + public void testGetTableName() { + ji.setTableName("table"); + assertEquals("table",ji.getTableName()); + } + + @Test + public void testGetConsistencyInfo() { + Map cons = new HashMap<>(); + cons.put("test","true"); + ji.setConsistencyInfo(cons); + assertEquals("true",ji.getConsistencyInfo().get("test")); + } + + @Test + public void testGetTtl() { + ji.setTtl("ttl"); + assertEquals("ttl",ji.getTtl()); + } + + @Test + public void testGetTimestamp() { + ji.setTimestamp("10:30"); + assertEquals("10:30",ji.getTimestamp()); + } + + @Test + public void testGetValues() { + Map cons = new HashMap<>(); + cons.put("val1","one"); + cons.put("val2","two"); + ji.setValues(cons); + assertEquals("one",ji.getValues().get("val1")); + } + + @Test + public void testGetRow_specification() { + Map cons = new HashMap<>(); + cons.put("val1","one"); + cons.put("val2","two"); + ji.setRow_specification(cons); + assertEquals("two",ji.getRow_specification().get("val2")); + } + + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonKeySpaceTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonKeySpaceTest.java new file mode 100644 index 00000000..882d5d5e --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonKeySpaceTest.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonKeySpace; + +public class JsonKeySpaceTest { + + JsonKeySpace jk = null; + + + @Before + public void init() { + jk = new JsonKeySpace(); + } + + + + @Test + public void testGetConsistencyInfo() { + Map mapSs = new HashMap<>(); + mapSs.put("k1", "one"); + jk.setConsistencyInfo(mapSs); + assertEquals("one",jk.getConsistencyInfo().get("k1")); + } + + @Test + public void testGetReplicationInfo() { + Map mapSo = new HashMap<>(); + mapSo.put("k1", "one"); + jk.setReplicationInfo(mapSo); + assertEquals("one",jk.getReplicationInfo().get("k1")); + + } + + @Test + public void testGetDurabilityOfWrites() { + jk.setDurabilityOfWrites("1"); + assertEquals("1",jk.getDurabilityOfWrites()); + } + + @Test + public void testGetKeyspaceName() { + jk.setKeyspaceName("Keyspace"); + assertEquals("Keyspace",jk.getKeyspaceName()); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java new file mode 100644 index 00000000..63f901c6 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonLeasedLock; + +public class JsonLeasedLockTest { + + JsonLeasedLock jl = null; + + @Before + public void init() { + jl = new JsonLeasedLock(); + } + + + @Test + public void testGetLeasePeriod() { + long lease = 20000; + jl.setLeasePeriod(lease); + assertEquals(lease,jl.getLeasePeriod()); + } + + @Test + public void testGetNotifyUrl() { + String url = "http://somewhere.com"; + jl.setNotifyUrl(url); + assertEquals(url,jl.getNotifyUrl()); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonOnboardTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonOnboardTest.java new file mode 100644 index 00000000..82f1748a --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonOnboardTest.java @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonOnboard; + +public class JsonOnboardTest { + + JsonOnboard jo = null; + + @Before + public void init() { + jo = new JsonOnboard(); + } + + + @Test + public void testGetPassword() { + String password = "password"; + jo.setPassword(password); + assertEquals(password,jo.getPassword()); + } + + @Test + public void testGetAid() { + String aid = "aid"; + jo.setAid(aid); + assertEquals(aid,jo.getAid()); + + } + + @Test + public void testGetAppname() { + String appName = "appName"; + jo.setAppname(appName); + assertEquals(appName,jo.getAppname()); + + } + + @Test + public void testGetUserId() { + String userId = "userId"; + jo.setUserId(userId); + assertEquals(userId,jo.getUserId()); + + } + + @Test + public void testGetIsAAF() { + String aaf = "true"; + jo.setIsAAF(aaf); + assertEquals(aaf,jo.getIsAAF()); + + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonSelectTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonSelectTest.java new file mode 100644 index 00000000..0243232f --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonSelectTest.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonSelect; + +public class JsonSelectTest { + + @Test + public void testGetConsistencyInfo() { + JsonSelect js = new JsonSelect(); + Map mapSs = new HashMap<>(); + mapSs.put("k1", "one"); + js.setConsistencyInfo(mapSs); + assertEquals("one",js.getConsistencyInfo().get("k1")); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonTableTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonTableTest.java new file mode 100644 index 00000000..e4c800fc --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonTableTest.java @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonTable; + +public class JsonTableTest { + + JsonTable jt = null; + + @Before + public void init() { + jt = new JsonTable(); + } + + @Test + public void testGetConsistencyInfo() { + Map mapSs = new HashMap<>(); + mapSs.put("k1", "one"); + jt.setConsistencyInfo(mapSs); + assertEquals("one",jt.getConsistencyInfo().get("k1")); + } + + @Test + public void testGetProperties() { + Map properties = new HashMap<>(); + properties.put("k1", "one"); + jt.setProperties(properties); + } + + @Test + public void testGetFields() { + Map fields = new HashMap<>(); + fields.put("k1", "one"); + jt.setFields(fields); + assertEquals("one",jt.getFields().get("k1")); + } + + @Test + public void testGetKeyspaceName() { + String keyspace = "keyspace"; + jt.setKeyspaceName(keyspace); + assertEquals(keyspace,jt.getKeyspaceName()); + } + + @Test + public void testGetTableName() { + String table = "table"; + jt.setTableName(table); + assertEquals(table,jt.getTableName()); + } + + @Test + public void testGetSortingKey() { + String sortKey = "sortkey"; + jt.setSortingKey(sortKey); + assertEquals(sortKey,jt.getSortingKey()); + } + + @Test + public void testGetClusteringOrder() { + String clusteringOrder = "clusteringOrder"; + jt.setClusteringOrder(clusteringOrder); + assertEquals(clusteringOrder,jt.getClusteringOrder()); + } + + @Test + public void testGetPrimaryKey() { + String primaryKey = "primaryKey"; + jt.setPrimaryKey(primaryKey); + assertEquals(primaryKey,jt.getPrimaryKey()); + } + +} diff --git a/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonUpdateTest.java b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonUpdateTest.java new file mode 100644 index 00000000..54db0540 --- /dev/null +++ b/jar/src/test/java/org/onap/music/unittests/jsonobjects/JsonUpdateTest.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2018 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.music.unittests.jsonobjects; + +import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.onap.music.datastore.jsonobjects.JsonUpdate; + +public class JsonUpdateTest { + + JsonUpdate ju = null; + + @Before + public void init() { + ju = new JsonUpdate(); + } + + + @Test + public void testGetConditions() { + Map mapSo = new HashMap<>(); + mapSo.put("key1","one"); + mapSo.put("key2","two"); + ju.setConditions(mapSo); + assertEquals("one",ju.getConditions().get("key1")); + } + + @Test + public void testGetRow_specification() { + Map mapSo = new HashMap<>(); + mapSo.put("key1","one"); + mapSo.put("key2","two"); + ju.setRow_specification(mapSo); + assertEquals("one",ju.getRow_specification().get("key1")); + } + + @Test + public void testGetKeyspaceName() { + String keyspace = "keyspace"; + ju.setKeyspaceName(keyspace); + assertEquals(keyspace,ju.getKeyspaceName()); + } + + @Test + public void testGetTableName() { + String table = "table"; + ju.setTableName(table); + assertEquals(table,ju.getTableName()); + } + + @Test + public void testGetConsistencyInfo() { + Map mapSs = new HashMap<>(); + mapSs.put("k1", "one"); + ju.setConsistencyInfo(mapSs); + assertEquals("one",ju.getConsistencyInfo().get("k1")); + } + + @Test + public void testGetTtl() { + ju.setTtl("2000"); + assertEquals("2000",ju.getTtl()); + } + + @Test + public void testGetTimestamp() { + ju.setTimestamp("20:00"); + assertEquals("20:00",ju.getTimestamp()); + + } + + @Test + public void testGetValues() { + Map cons = new HashMap<>(); + cons.put("val1","one"); + cons.put("val2","two"); + ju.setValues(cons); + assertEquals("one",ju.getValues().get("val1")); + } + +} -- 2.16.6