From fa4ad8759dff978a9e3fd2466bc79abf1db3fab7 Mon Sep 17 00:00:00 2001 From: ycombes Date: Mon, 19 Aug 2019 13:00:13 +0200 Subject: [PATCH 001/134] Make SDK from scratch --- .../java/io/kuzzle/sdk/core/Collection.java | 1975 -------- .../io/kuzzle/sdk/core/CollectionMapping.java | 246 - .../java/io/kuzzle/sdk/core/Document.java | 628 --- src/main/java/io/kuzzle/sdk/core/Kuzzle.java | 2785 ----------- .../io/kuzzle/sdk/core/MemoryStorage.java | 4355 ----------------- src/main/java/io/kuzzle/sdk/core/Options.java | 982 ---- src/main/java/io/kuzzle/sdk/core/Room.java | 560 --- .../java/io/kuzzle/sdk/core/RoomOptions.java | 114 - .../io/kuzzle/sdk/enums/CollectionType.java | 7 - src/main/java/io/kuzzle/sdk/enums/Event.java | 15 - src/main/java/io/kuzzle/sdk/enums/Mode.java | 5 - .../java/io/kuzzle/sdk/enums/Policies.java | 5 - src/main/java/io/kuzzle/sdk/enums/Scope.java | 9 - src/main/java/io/kuzzle/sdk/enums/State.java | 7 - src/main/java/io/kuzzle/sdk/enums/Users.java | 8 - .../kuzzle/sdk/listeners/EventListener.java | 15 - .../sdk/listeners/OnConnectionEvent.java | 8 - .../sdk/listeners/OnQueryDoneListener.java | 8 - .../sdk/listeners/ResponseListener.java | 22 - .../sdk/listeners/SubscribeListener.java | 46 - .../io/kuzzle/sdk/responses/KuzzleList.java | 8 - .../sdk/responses/NotificationResponse.java | 142 - .../io/kuzzle/sdk/responses/SearchResult.java | 191 - .../sdk/responses/SecurityDocumentList.java | 33 - .../kuzzle/sdk/responses/TokenValidity.java | 33 - .../security/AbstractSecurityDocument.java | 226 - .../java/io/kuzzle/sdk/security/Profile.java | 211 - .../java/io/kuzzle/sdk/security/Role.java | 83 - .../java/io/kuzzle/sdk/security/Security.java | 1847 ------- .../java/io/kuzzle/sdk/security/User.java | 360 -- .../java/io/kuzzle/sdk/state/KuzzleQueue.java | 61 - src/main/java/io/kuzzle/sdk/state/States.java | 15 - src/main/java/io/kuzzle/sdk/util/Event.java | 25 - .../java/io/kuzzle/sdk/util/EventList.java | 8 - .../io/kuzzle/sdk/util/KuzzleJSONObject.java | 58 - .../kuzzle/sdk/util/OfflineQueueLoader.java | 7 - .../java/io/kuzzle/sdk/util/QueryObject.java | 86 - .../java/io/kuzzle/sdk/util/QueueFilter.java | 7 - src/main/java/io/kuzzle/sdk/util/Scroll.java | 14 - .../sdk/core/Kuzzle/checkTokenTest.java | 131 - .../core/Kuzzle/connectionManagementTest.java | 264 - .../sdk/core/Kuzzle/constructorTest.java | 290 -- .../sdk/core/Kuzzle/createIndexTest.java | 96 - .../core/Kuzzle/createMyCredentialsTest.java | 107 - .../core/Kuzzle/deleteMyCredentialsTest.java | 95 - .../sdk/core/Kuzzle/eventSystemTest.java | 106 - .../kuzzle/sdk/core/Kuzzle/factoriesTest.java | 63 - .../sdk/core/Kuzzle/getAllStatisticsTest.java | 187 - .../sdk/core/Kuzzle/getAutoRefreshTest.java | 117 - .../core/Kuzzle/getLastStatisticsTest.java | 114 - .../sdk/core/Kuzzle/getMyCredentialsTest.java | 98 - .../sdk/core/Kuzzle/getMyRightsTest.java | 82 - .../sdk/core/Kuzzle/getServerInfoTest.java | 106 - .../sdk/core/Kuzzle/getStatisticsTest.java | 139 - .../sdk/core/Kuzzle/listCollectionsTest.java | 119 - .../sdk/core/Kuzzle/listIndexesTest.java | 108 - .../io/kuzzle/sdk/core/Kuzzle/loginTest.java | 159 - .../io/kuzzle/sdk/core/Kuzzle/logoutTest.java | 110 - .../io/kuzzle/sdk/core/Kuzzle/nowTest.java | 110 - .../core/Kuzzle/offlineQueueLoaderTest.java | 230 - .../io/kuzzle/sdk/core/Kuzzle/queryTest.java | 284 -- .../sdk/core/Kuzzle/queueManagementTest.java | 209 - .../sdk/core/Kuzzle/refreshIndexTest.java | 116 - .../sdk/core/Kuzzle/setAutoRefreshTest.java | 117 - .../sdk/core/Kuzzle/setJwtTokenTest.java | 93 - .../Kuzzle/subscriptionsManagementTest.java | 83 - .../sdk/core/Kuzzle/unsetJwtTokenTest.java | 58 - .../core/Kuzzle/updateMyCredentialsTest.java | 105 - .../sdk/core/Kuzzle/updateSelfTest.java | 79 - .../Kuzzle/validateMyCredentialsTest.java | 108 - .../io/kuzzle/sdk/core/Kuzzle/whoAmiTest.java | 111 - .../KuzzleDataCollection/constructorTest.java | 101 - .../core/KuzzleDataCollection/countTest.java | 106 - .../createDocumentTest.java | 152 - .../core/KuzzleDataCollection/createTest.java | 142 - .../deleteDocumentTest.java | 136 - .../deleteSpecificationsTest.java | 101 - .../documentExistsTest.java | 111 - .../KuzzleDataCollection/factoriesTest.java | 68 - .../KuzzleDataCollection/fetchDocument.java | 115 - .../KuzzleDataCollection/getMappingTest.java | 71 - .../getSpecificationsTest.java | 113 - .../mCreateDocumentTest.java | 113 - .../mCreateOrReplaceDocumentTest.java | 113 - .../mDeleteDocumentTest.java | 112 - .../mGetDocumentTest.java | 126 - .../mReplaceDocumentTest.java | 127 - .../mUpdateDocumentTest.java | 127 - .../publishMessageTest.java | 127 - .../replaceDocumentTest.java | 116 - .../scrollSpecificationsTest.java | 167 - .../core/KuzzleDataCollection/scrollTest.java | 177 - .../searchSpecificationsTest.java | 166 - .../core/KuzzleDataCollection/searchTest.java | 279 -- .../KuzzleDataCollection/subscribeTest.java | 90 - .../KuzzleDataCollection/truncateTest.java | 101 - .../updateDocumentTest.java | 157 - .../updateSpecificationsTest.java | 149 - .../validateSpecificationsTest.java | 146 - .../sdk/core/KuzzleDataMapping/applyTest.java | 98 - .../KuzzleDataMapping/constructorTest.java | 86 - .../core/KuzzleDataMapping/refreshTest.java | 152 - .../core/KuzzleDataMapping/removeTest.java | 40 - .../core/KuzzleDocument/constructorTest.java | 178 - .../sdk/core/KuzzleDocument/deleteTest.java | 95 - .../sdk/core/KuzzleDocument/existsTest.java | 125 - .../sdk/core/KuzzleDocument/publishTest.java | 66 - .../sdk/core/KuzzleDocument/refreshTest.java | 140 - .../sdk/core/KuzzleDocument/saveTest.java | 113 - .../core/KuzzleDocument/serializeTest.java | 54 - .../core/KuzzleDocument/subscribeTest.java | 97 - .../core/KuzzleMemoryStorage/methodsTest.java | 2458 ---------- .../sdk/core/KuzzleRoom/constructorTest.java | 136 - .../kuzzle/sdk/core/KuzzleRoom/countTest.java | 167 - .../KuzzleRoom/notificationHandlerTest.java | 167 - .../kuzzle/sdk/core/KuzzleRoom/renewTest.java | 166 - .../sdk/core/KuzzleRoom/unsubscribeTest.java | 182 - .../sdk/listeners/KuzzleListenerTest.java | 148 - .../KuzzleSubscribeListenerTest.java | 66 - .../sdk/responses/SearchResultTest.java | 158 - .../sdk/security/KuzzleProfileTest.java | 214 - .../kuzzle/sdk/security/KuzzleRoleTest.java | 94 - .../AbstractKuzzleSecurityDocumentTest.java | 186 - .../KuzzleSecurity/createCredentialsTest.java | 87 - .../KuzzleSecurity/createProfileTest.java | 126 - .../createRestrictedUserTest.java | 131 - .../KuzzleSecurity/createRoleTest.java | 125 - .../KuzzleSecurity/createUserTest.java | 114 - .../KuzzleSecurity/deleteCredentialsTest.java | 86 - .../KuzzleSecurity/deleteProfileTest.java | 104 - .../KuzzleSecurity/deleteRoleTest.java | 104 - .../KuzzleSecurity/deleteUserTest.java | 105 - .../KuzzleSecurity/factoriesTest.java | 48 - .../getAllCredentialFieldsTest.java | 89 - .../getCredentialFieldsTest.java | 90 - .../KuzzleSecurity/getCredentialsTest.java | 89 - .../KuzzleSecurity/getProfileTest.java | 125 - .../security/KuzzleSecurity/getRoleTest.java | 112 - .../KuzzleSecurity/getUserRightsTest.java | 86 - .../security/KuzzleSecurity/getUserTest.java | 103 - .../KuzzleSecurity/hasCredentialsTest.java | 89 - .../KuzzleSecurity/isActionAllowedTest.java | 123 - .../KuzzleSecurity/replaceUserTest.java | 110 - .../KuzzleSecurity/scrollProfilesTest.java | 181 - .../KuzzleSecurity/scrollUsersTest.java | 181 - .../KuzzleSecurity/searchProfilesTest.java | 112 - .../KuzzleSecurity/searchRolesTest.java | 113 - .../KuzzleSecurity/searchUsersTest.java | 112 - .../KuzzleSecurity/updateCredentialsTest.java | 87 - .../KuzzleSecurity/updateProfileTest.java | 109 - .../KuzzleSecurity/updateRoleTest.java | 110 - .../KuzzleSecurity/updateUserTest.java | 110 - .../validateCredentialsTest.java | 91 - .../kuzzle/sdk/security/KuzzleUserTest.java | 408 -- .../testUtils/KuzzleDataCollectionExtend.java | 18 - .../io/kuzzle/sdk/testUtils/KuzzleExtend.java | 131 - .../kuzzle/sdk/testUtils/QueryArgsHelper.java | 10 - .../io/kuzzle/sdk/testUtils/RoomExtend.java | 62 - 158 files changed, 32285 deletions(-) delete mode 100644 src/main/java/io/kuzzle/sdk/core/Collection.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/CollectionMapping.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/Document.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/Kuzzle.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/MemoryStorage.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/Options.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/Room.java delete mode 100644 src/main/java/io/kuzzle/sdk/core/RoomOptions.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/CollectionType.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/Event.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/Mode.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/Policies.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/Scope.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/State.java delete mode 100644 src/main/java/io/kuzzle/sdk/enums/Users.java delete mode 100644 src/main/java/io/kuzzle/sdk/listeners/EventListener.java delete mode 100644 src/main/java/io/kuzzle/sdk/listeners/OnConnectionEvent.java delete mode 100644 src/main/java/io/kuzzle/sdk/listeners/OnQueryDoneListener.java delete mode 100644 src/main/java/io/kuzzle/sdk/listeners/ResponseListener.java delete mode 100644 src/main/java/io/kuzzle/sdk/listeners/SubscribeListener.java delete mode 100644 src/main/java/io/kuzzle/sdk/responses/KuzzleList.java delete mode 100644 src/main/java/io/kuzzle/sdk/responses/NotificationResponse.java delete mode 100644 src/main/java/io/kuzzle/sdk/responses/SearchResult.java delete mode 100644 src/main/java/io/kuzzle/sdk/responses/SecurityDocumentList.java delete mode 100644 src/main/java/io/kuzzle/sdk/responses/TokenValidity.java delete mode 100644 src/main/java/io/kuzzle/sdk/security/AbstractSecurityDocument.java delete mode 100644 src/main/java/io/kuzzle/sdk/security/Profile.java delete mode 100644 src/main/java/io/kuzzle/sdk/security/Role.java delete mode 100644 src/main/java/io/kuzzle/sdk/security/Security.java delete mode 100644 src/main/java/io/kuzzle/sdk/security/User.java delete mode 100644 src/main/java/io/kuzzle/sdk/state/KuzzleQueue.java delete mode 100644 src/main/java/io/kuzzle/sdk/state/States.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/Event.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/EventList.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/KuzzleJSONObject.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/OfflineQueueLoader.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/QueryObject.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/QueueFilter.java delete mode 100644 src/main/java/io/kuzzle/sdk/util/Scroll.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/checkTokenTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/connectionManagementTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/constructorTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/createIndexTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/createMyCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/deleteMyCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/eventSystemTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/factoriesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getAllStatisticsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getAutoRefreshTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getLastStatisticsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyRightsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getServerInfoTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/getStatisticsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/listCollectionsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/listIndexesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/loginTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/logoutTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/nowTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/offlineQueueLoaderTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/queryTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/queueManagementTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/refreshIndexTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/setAutoRefreshTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/setJwtTokenTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/subscriptionsManagementTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/unsetJwtTokenTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/updateMyCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/updateSelfTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/validateMyCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/Kuzzle/whoAmiTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/constructorTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/countTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/documentExistsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/factoriesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/fetchDocument.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getMappingTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateOrReplaceDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mDeleteDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mGetDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mReplaceDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mUpdateDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/publishMessageTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/replaceDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/subscribeTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/truncateTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/validateSpecificationsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/applyTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/constructorTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/refreshTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/removeTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/constructorTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/deleteTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/existsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/publishTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/refreshTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/saveTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/serializeTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleDocument/subscribeTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleMemoryStorage/methodsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleRoom/constructorTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleRoom/countTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleRoom/notificationHandlerTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleRoom/renewTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/core/KuzzleRoom/unsubscribeTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/listeners/KuzzleListenerTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/listeners/KuzzleSubscribeListenerTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/responses/SearchResultTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleProfileTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleRoleTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/AbstractKuzzleSecurityDocumentTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createProfileTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRestrictedUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRoleTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteProfileTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteRoleTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/factoriesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getAllCredentialFieldsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialFieldsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getProfileTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getRoleTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserRightsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/hasCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/isActionAllowedTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/replaceUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollProfilesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollUsersTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchProfilesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchRolesTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchUsersTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateProfileTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateRoleTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/validateCredentialsTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/security/KuzzleUserTest.java delete mode 100644 test/main/java/io/kuzzle/sdk/testUtils/KuzzleDataCollectionExtend.java delete mode 100644 test/main/java/io/kuzzle/sdk/testUtils/KuzzleExtend.java delete mode 100644 test/main/java/io/kuzzle/sdk/testUtils/QueryArgsHelper.java delete mode 100644 test/main/java/io/kuzzle/sdk/testUtils/RoomExtend.java diff --git a/src/main/java/io/kuzzle/sdk/core/Collection.java b/src/main/java/io/kuzzle/sdk/core/Collection.java deleted file mode 100644 index a9884ff5..00000000 --- a/src/main/java/io/kuzzle/sdk/core/Collection.java +++ /dev/null @@ -1,1975 +0,0 @@ -package io.kuzzle.sdk.core; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.SubscribeListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SearchResult; -import io.kuzzle.sdk.responses.NotificationResponse; - -public class Collection { - private final Kuzzle kuzzle; - private final String collection; - private final String index; - private ResponseListener subscribeCallback; - private JSONObject subscribeError = null; - private Room subscribeRoom = null; - - protected JSONObject headers; - - /** - * Constructor - * - * @param kuzzle Kuzzle instance - * @param collection Data collection name - * @param index Parent data index name - */ - public Collection(final Kuzzle kuzzle, final String collection, final String index) { - if (kuzzle == null) { - throw new IllegalArgumentException("Collection: need a Kuzzle instance to initialize"); - } - - if (index == null || collection == null) { - throw new IllegalArgumentException("Collection: index and collection required"); - } - this.kuzzle = kuzzle; - this.collection = collection; - this.index = index; - - try { - this.headers = new JSONObject(kuzzle.getHeaders().toString()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #search(JSONObject, Options, ResponseListener)} - */ - public void search(final JSONObject filter, final ResponseListener listener) { - this.search(filter, new Options(), listener); - } - - /** - * Executes a search on the data collection. - * /!\ There is a small delay between documents creation and their existence in our search layer, - * usually a couple of seconds. - * That means that a document that was just been created won’t be returned by this function. - * - * @param filters Search filters to apply - * @param options Request options - * @param listener Response callback listener - */ - public void search(final JSONObject filters, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - this.kuzzle.isValid(); - JSONObject data = new JSONObject(); - try { - if (filters != null) { - data.put("body", filters); - } - - this.kuzzle.addHeaders(data, this.getHeaders()); - - this.kuzzle.query(makeQueryArgs("document", "search"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - SearchResult response; - JSONObject aggregations = null; - JSONArray hits = object.getJSONObject("result").getJSONArray("hits"); - List docs = new ArrayList(); - - for (int i = 0; i < hits.length(); i++) { - JSONObject hit = hits.getJSONObject(i); - Document doc = new Document(Collection.this, hit.getString("_id"), hit.getJSONObject("_source"), hit.getJSONObject("_meta")); - - docs.add(doc); - } - - if (object.getJSONObject("result").has("_scroll_id")) { - options.setScrollId(object.getJSONObject("result").getString("_scroll_id")); - } - - if (object.getJSONObject("result").has("aggregations")) { - aggregations = object.getJSONObject("result").getJSONObject("aggregations"); - } - - response = new SearchResult( - Collection.this, - object.getJSONObject("result").getInt("total"), - docs, - aggregations, - options, - filters, - options.getPrevious() - ); - - listener.onSuccess(response); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #scroll(String, Options, ResponseListener)} - */ - public void scroll(String scrollId, final ResponseListener listener) { - this.scroll(scrollId, new Options(), new JSONObject(), listener); - } - - /** - * {@link #scroll(String, Options, ResponseListener)} - */ - public void scroll(String scrollId, final Options options, final ResponseListener listener) { - this.scroll(scrollId, options, new JSONObject(), listener); - } - - /** - * Gets the next page of results from a previous search or scroll request - * - * @param scrollId Scroll unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void scroll(String scrollId, final Options options, final JSONObject filters, final ResponseListener listener) { - JSONObject request; - - try { - request = new JSONObject().put("body", new JSONObject()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - if (scrollId == null) { - throw new RuntimeException("Collection.scroll: scrollId is required"); - } - - options.setScrollId(scrollId); - - try { - this.kuzzle.query(this.kuzzle.buildQueryArgs("document", "scroll"), request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - SearchResult response; - JSONArray hits = object.getJSONObject("result").getJSONArray("hits"); - List docs = new ArrayList(); - - for (int i = 0; i < hits.length(); i++) { - JSONObject hit = hits.getJSONObject(i); - Document doc = new Document(Collection.this, hit.getString("_id"), hit.getJSONObject("_source"), hit.getJSONObject("_meta")); - - docs.add(doc); - } - - if (object.getJSONObject("result").has("_scroll_id")) { - options.setScrollId(object.getJSONObject("result").getString("_scroll_id")); - } - - response = new SearchResult( - Collection.this, - object.getJSONObject("result").getInt("total"), - docs, - new JSONObject(), - options, - filters, - options.getPrevious() - ); - - listener.onSuccess(response); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #scrollSpecifications(String, Options, ResponseListener)} - */ - public void scrollSpecifications(final String scrollId, final ResponseListener listener) { - this.scrollSpecifications(scrollId, new Options(), listener); - } - - /** - * Scrolls through specifications using the provided scrollId - * - * @param scrollId Scroll unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void scrollSpecifications(final String scrollId, final Options options, final ResponseListener listener) { - this.kuzzle.isValid(); - - JSONObject data = new JSONObject(); - - if (scrollId == null) { - throw new RuntimeException("Collection.scrollSpecifications: scrollId is required"); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - try { - data.put("scrollId", scrollId); - - this.kuzzle.addHeaders(data, this.getHeaders()); - - this.kuzzle.query(makeQueryArgs("collection", "scrollSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #searchSpecifications(JSONObject, Options, ResponseListener)} - */ - public void searchSpecifications(final ResponseListener listener) { - this.searchSpecifications(null, new Options(), listener); - } - - /** - * {@link #searchSpecifications(JSONObject, Options, ResponseListener)} - */ - public void searchSpecifications(final JSONObject filters, final ResponseListener listener) { - this.searchSpecifications(filters, new Options(), listener); - } - - /** - * {@link #searchSpecifications(JSONObject, Options, ResponseListener)} - */ - public void searchSpecifications(final Options options, final ResponseListener listener) { - this.searchSpecifications(null, options, listener); - } - - /** - * Searches specifications across indexes/collections according to the provided filters - * - * @param filters Optional filters in ElasticSearch Query DSL format - * @param options Request options - * @param listener Response callback listener - */ - public void searchSpecifications(final JSONObject filters, final Options options, final ResponseListener listener) { - this.kuzzle.isValid(); - - JSONObject data = new JSONObject(); - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - try { - if (filters != null) { - data.put("body", new JSONObject() - .put("query", filters) - ); - } - - this.kuzzle.addHeaders(data, this.getHeaders()); - - this.kuzzle.query(makeQueryArgs("collection", "searchSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Make query args kuzzle . query args. - * - * @param controller API Controller to invoke - * @param action Controller action name - * @return Built query arguments - */ - protected io.kuzzle.sdk.core.Kuzzle.QueryArgs makeQueryArgs(final String controller, final String action) { - io.kuzzle.sdk.core.Kuzzle.QueryArgs args = new io.kuzzle.sdk.core.Kuzzle.QueryArgs(); - args.action = action; - args.controller = controller; - args.index = this.index; - args.collection = this.collection; - return args; - } - - /** - * Returns the provided array of Documents with each one being serialized - * - * @param documents Array of Document objects - * @return A list of serialized documents - */ - private JSONArray serializeDocuments(Document[] documents) throws JSONException { - JSONArray serializedDocuments = new JSONArray(); - - for (Document document : documents) { - serializedDocuments.put(document.serialize()); - } - - return serializedDocuments; - } - - /** - * {@link #count(JSONObject, Options, ResponseListener)} - */ - public void count(final JSONObject filters, final ResponseListener listener) { - this.count(filters, null, listener); - } - - /** - * {@link #count(JSONObject, Options, ResponseListener)} - */ - public void count(final ResponseListener listener) { - this.count(null, null, listener); - } - - /** - * Returns the number of documents matching the provided set of filters. - * There is a small delay between documents creation and their existence in our search layer, - * usually a couple of seconds. - * That means that a document that was just been created won’t be returned by this function - * - * @param filters Search filters - * @param options Request options - * @param listener Response callback listener - */ - public void count(final JSONObject filters, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Collection.count: listener required"); - } - JSONObject data = new JSONObject(); - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - data.put("body", filters); - this.kuzzle.query(makeQueryArgs("document", "count"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getInt("count")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final Options options) { - return this.create(null, options, null); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create() { - return this.create(null, null, null); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final ResponseListener listener) { - return this.create(null, null, listener); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final Options options, final ResponseListener listener) { - return this.create(null, options, listener); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final JSONObject mapping) { - return this.create(mapping, null, null); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final JSONObject mapping, final Options options) { - return this.create(mapping, options, null); - } - - /** - * {@link #create(JSONObject, Options, ResponseListener)} - */ - public Collection create(final JSONObject mapping, final ResponseListener listener) { - return this.create(mapping, null, listener); - } - - /** - * Create a new empty data collection, with associated mappings. - * Kuzzle automatically creates data collections when storing documents, - * but there are cases where we want to create and prepare data collections - * before storing documents in it. - * - * @param mapping Collection mapping - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection create(final JSONObject mapping, final Options options, final ResponseListener listener) { - JSONObject data = new JSONObject(); - - try { - if (mapping != null) { - data.put("body", mapping); - } - - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "create"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final String id, final JSONObject content) throws JSONException { - return this.createDocument(id, content, null, null); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final String id, final JSONObject content, Options options) throws JSONException { - return this.createDocument(id, content, options, null); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - return this.createDocument(id, content, null, listener); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final JSONObject content) throws JSONException { - return this.createDocument(null, content, null, null); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final JSONObject content, Options options) throws JSONException { - return this.createDocument(null, content, options, null); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final JSONObject content, final ResponseListener listener) throws JSONException { - return this.createDocument(null, content, null, listener); - } - - /** - * {@link #createDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection createDocument(final JSONObject content, Options options, final ResponseListener listener) throws JSONException { - return this.createDocument(null, content, options, listener); - } - - /** - * Create document kuzzle data collection. - * - * @param id document ID - * @param content document content - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection createDocument(final String id, final JSONObject content, Options options, final ResponseListener listener) throws JSONException { - if (content == null) { - throw new IllegalArgumentException("Cannot create an empty document"); - } - - Document doc = new Document(this, id, content); - return this.createDocument(doc, options, listener); - } - - /** - * {@link #createDocument(Document, Options, ResponseListener)} - */ - public Collection createDocument(final Document document) { - return this.createDocument(document, null, null); - } - - /** - * {@link #createDocument(Document, Options, ResponseListener)} - */ - public Collection createDocument(final Document document, final Options options) { - return this.createDocument(document, options, null); - } - - /** - * {@link #createDocument(Document, Options, ResponseListener)} - */ - public Collection createDocument(final Document document, final ResponseListener listener) { - return this.createDocument(document, null, listener); - } - - /** - * Create a new document in kuzzle - * - * @param document the document - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection createDocument(final Document document, final Options options, final ResponseListener listener) { - String action = "create"; - JSONObject data = document.serialize(); - - if (options != null && options.getIfExist().equals("replace")) { - action = "createOrReplace"; - } - - this.kuzzle.addHeaders(data, this.getHeaders()); - - try { - this.kuzzle.query(makeQueryArgs("document", action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - JSONObject result = response.getJSONObject("result"); - Document document = new Document(Collection.this, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta")); - document.setVersion(result.getLong("_version")); - listener.onSuccess(document); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #collectionMapping(JSONObject)} - */ - public CollectionMapping collectionMapping() { - return new CollectionMapping(this); - } - - /** - * CollectionMapping constructor, attaching it to this - * Collection object - * - * @param mapping Raw mapping to declare - * @return a newly instantiated CollectionMapping object - */ - public CollectionMapping collectionMapping(JSONObject mapping) { - return new CollectionMapping(this, mapping); - } - - /** - * {@link #deleteDocument(String, Options, ResponseListener)} - */ - public Collection deleteDocument(final String documentId) { - return this.deleteDocument(documentId, null, null); - } - - /** - * {@link #deleteDocument(String, Options, ResponseListener)} - */ - public Collection deleteDocument(final String documentId, Options options) { - return this.deleteDocument(documentId, options, null); - } - - /** - * {@link #deleteDocument(String, Options, ResponseListener)} - */ - public Collection deleteDocument(final String documentId, final ResponseListener listener) { - return this.deleteDocument(documentId, null, listener); - } - - /** - * Delete a single document - * - * @param documentId Document unique identifier - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection deleteDocument(final String documentId, final Options options, final ResponseListener listener) { - if (documentId == null) { - throw new IllegalArgumentException("Collection.deleteDocument: documentId required"); - } - return this.deleteDocument(documentId, null, options, listener, null); - } - - /** - * {@link #deleteDocument(JSONObject, Options, ResponseListener)} - */ - public Collection deleteDocument(final JSONObject filters) { - return this.deleteDocument(filters, null, null); - } - - /** - * {@link #deleteDocument(JSONObject, Options, ResponseListener)} - */ - public Collection deleteDocument(final JSONObject filters, final Options options) { - return this.deleteDocument(filters, options, null); - } - - /** - * {@link #deleteDocument(JSONObject, Options, ResponseListener)} - */ - public Collection deleteDocument(final JSONObject filters, final ResponseListener listener) { - return this.deleteDocument(filters, null, listener); - } - - /** - * Delete documents using search filters - * - * @param filters Search filters - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection deleteDocument(final JSONObject filters, final Options options, final ResponseListener listener) { - if (filters == null) { - throw new IllegalArgumentException("Collection.deleteDocument: filters required"); - } - return this.deleteDocument(null, filters, options, null, listener); - } - - /** - * Delete either a single document or multiple ones using search filters - * - * @param documentId Document unique identifier - * @param filter Search fitlers - * @param options Request options - * @param listener Response callback listener (single document delete) - * @param listener2 Response callback listener (document search delete) - * @return this - */ - protected Collection deleteDocument(final String documentId, final JSONObject filter, final Options options, final ResponseListener listener, final ResponseListener listener2) { - JSONObject data = new JSONObject(); - String action; - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - if (documentId != null) { - data.put("_id", documentId); - action = "delete"; - } else { - data.put("body", new JSONObject().put("query", filter)); - action = "deleteByQuery"; - } - this.kuzzle.query(makeQueryArgs("document", action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result").getString("_id")); - } else if (listener2 != null) { - JSONArray array = response.getJSONObject("result").getJSONArray("hits"); - int length = array.length(); - String[] ids = new String[length]; - for (int i = 0; i < length; i++) { - ids[i] = array.getString(i); - } - listener2.onSuccess(ids); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } else if (listener2 != null) { - listener2.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #deleteSpecifications(Options, ResponseListener)} - */ - public Collection deleteSpecifications() throws JSONException { - return this.deleteSpecifications(new Options(), null); - } - - /** - * {@link #deleteSpecifications(Options, ResponseListener)} - */ - public Collection deleteSpecifications(final Options options) throws JSONException { - return this.deleteSpecifications(options, null); - } - - /** - * {@link #deleteSpecifications(Options, ResponseListener)} - */ - public Collection deleteSpecifications(final ResponseListener listener) throws JSONException { - return this.deleteSpecifications(new Options(), listener); - } - - /** - * Deletes the current specifications for this collection - * - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection deleteSpecifications(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = new JSONObject(); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "deleteSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #document(String, JSONObject)} - */ - public Document document() throws JSONException { - return new Document(this); - } - - /** - * {@link #document(String, JSONObject)} - */ - public Document document(final String id) throws JSONException { - return new Document(this, id); - } - - /** - * {@link #document(String, JSONObject)} - */ - public Document document(final JSONObject content) throws JSONException { - return new Document(this, content); - } - - /** - * Instantiates a Document object with a preset unique - * identifier and content. - * This document is attached to this data collection - * - * @param id Document unique identifier - * @param content Document content - * @return newly instantiated Document object - * @throws JSONException - */ - public Document document(final String id, final JSONObject content) throws JSONException { - return new Document(this, id, content); - } - - /** - * {@link #documentExists(String, Options, ResponseListener)} - */ - public void documentExists(final String documentId, final ResponseListener listener) { - this.documentExists(documentId, null, listener); - } - - /** - * Asks Kuzzle API if the provided document exists - * - * @param documentId Document unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void documentExists(final String documentId, final Options options, final ResponseListener listener) { - if (documentId == null) { - throw new IllegalArgumentException("Collection.documentExists: documentId required"); - } - if (listener == null) { - throw new IllegalArgumentException("Collection.documentExists: listener required"); - } - - try { - JSONObject data = new JSONObject().put("_id", documentId); - this.kuzzle.addHeaders(data, this.getHeaders()); - - this.kuzzle.query(makeQueryArgs("document", "exists"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(response); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #fetchDocument(String, Options, ResponseListener)} - */ - public void fetchDocument(final String documentId, final ResponseListener listener) { - this.fetchDocument(documentId, null, listener); - } - - /** - * Fetch a document from Kuzzle - * - * @param documentId Document unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void fetchDocument(final String documentId, final Options options, final ResponseListener listener) { - if (documentId == null) { - throw new IllegalArgumentException("Collection.fetchDocument: documentId required"); - } - if (listener == null) { - throw new IllegalArgumentException("Collection.fetchDocument: listener required"); - } - - try { - JSONObject data = new JSONObject().put("_id", documentId); - this.kuzzle.addHeaders(data, this.getHeaders()); - - this.kuzzle.query(makeQueryArgs("document", "get"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - Document document = new Document(Collection.this, result.getString("_id"), result.getJSONObject("_source")); - - document.setVersion(result.getLong("_version")); - listener.onSuccess(document); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getMapping(Options, ResponseListener)} - */ - public void getMapping(final ResponseListener listener) { - this.getMapping(null, listener); - } - - /** - * Get the mapping for this data collection - * - * @param options Request options - * @param listener Response callback listener - */ - public void getMapping(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Collection.getMapping: listener required"); - } - new CollectionMapping(this).refresh(options, listener); - } - - /** - * {@link #getSpecifications(Options, ResponseListener)} - */ - public void getSpecifications(final ResponseListener listener) throws JSONException { - this.getSpecifications(new Options(), listener); - } - - /** - * Get the specifications for this collection - * - * @param options Request options - * @param listener Response callback listener - * @throws JSONException - */ - public void getSpecifications(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = new JSONObject() - .put("body", new JSONObject()); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "getSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Create multiple documents - * - * @param documents Array of Document objects to create - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection mCreateDocument(final Document[] documents, final Options options, final ResponseListener listener) throws JSONException { - if (documents.length == 0) { - throw new IllegalArgumentException("Collection.mCreateDocument: The document array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("documents", this.serializeDocuments(documents)) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mCreate"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #mCreateDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateDocument(final Document[] documents, final ResponseListener listener) throws JSONException { - return this.mCreateDocument(documents, new Options(), listener); - } - - /** - * {@link #mCreateDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateDocument(final Document[] documents, Options options) throws JSONException { - return this.mCreateDocument(documents, options, null); - } - - /** - * {@link #mCreateDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateDocument(final Document[] documents) throws JSONException { - return this.mCreateDocument(documents, new Options(), null); - } - - /** - * Create or replace multiple documents - * - * @param documents Array of Document objects to create or replace - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection mCreateOrReplaceDocument(final Document[] documents, final Options options, final ResponseListener listener) throws JSONException { - if (documents.length == 0) { - throw new IllegalArgumentException("Collection.mCreateOrReplaceDocument: The document array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("documents", this.serializeDocuments(documents)) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mCreateOrReplace"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #mCreateOrReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateOrReplaceDocument(final Document[] documents, final ResponseListener listener) throws JSONException { - return this.mCreateOrReplaceDocument(documents, new Options(), listener); - } - - /** - * {@link #mCreateOrReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateOrReplaceDocument(final Document[] documents, Options options) throws JSONException { - return this.mCreateOrReplaceDocument(documents, options, null); - } - - /** - * {@link #mCreateOrReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mCreateOrReplaceDocument(final Document[] documents) throws JSONException { - return this.mCreateOrReplaceDocument(documents, new Options(), null); - } - - /** - * Delete multiple documents using their unique IDs - * - * @param documentIds Array of document IDs to delete - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection mDeleteDocument(final String[] documentIds, final Options options, final ResponseListener listener) throws JSONException { - if (documentIds.length == 0) { - throw new IllegalArgumentException("Collection.mDeleteDocument: The document IDs array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("ids", new JSONArray(Arrays.asList(documentIds))) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mDelete"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONArray("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #mDeleteDocument(String[], Options, ResponseListener)} - */ - public Collection mDeleteDocument(final String[] documentIds, final ResponseListener listener) throws JSONException { - return this.mDeleteDocument(documentIds, new Options(), listener); - } - - /** - * {@link #mDeleteDocument(String[], Options, ResponseListener)} - */ - public Collection mDeleteDocument(final String[] documentIds, Options options) throws JSONException { - return this.mDeleteDocument(documentIds, options, null); - } - - /** - * {@link #mDeleteDocument(String[], Options, ResponseListener)} - */ - public Collection mDeleteDocument(final String[] documentIds) throws JSONException { - return this.mDeleteDocument(documentIds, new Options(), null); - } - - /** - * Fetch multiple documents - * - * @param documentIds Array of document IDs to retrieve - * @param options Request options - * @param listener Response callback listener - * @throws JSONException - */ - public void mGetDocument(final String[] documentIds, final Options options, final ResponseListener listener) throws JSONException { - if (documentIds.length == 0) { - throw new IllegalArgumentException("Collection.mGetDocument: The document IDs array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("ids", new JSONArray(Arrays.asList(documentIds))) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mGet"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #mGetDocument(String[], Options, ResponseListener)} - */ - public void mGetDocument(final String[] documentIds, final ResponseListener listener) throws JSONException { - this.mGetDocument(documentIds, new Options(), listener); - } - - /** - * Replace multiple documents - * - * @param documents Array of Document objects to replace - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection mReplaceDocument(final Document[] documents, final Options options, final ResponseListener listener) throws JSONException { - if (documents.length == 0) { - throw new IllegalArgumentException("Collection.mReplaceDocument: The document array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("documents", this.serializeDocuments(documents)) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mReplace"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #mReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mReplaceDocument(final Document[] documents, final ResponseListener listener) throws JSONException { - return this.mReplaceDocument(documents, new Options(), listener); - } - - /** - * {@link #mReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mReplaceDocument(final Document[] documents, Options options) throws JSONException { - return this.mReplaceDocument(documents, options, null); - } - - /** - * {@link #mReplaceDocument(Document[], Options, ResponseListener)} - */ - public Collection mReplaceDocument(final Document[] documents) throws JSONException { - return this.mReplaceDocument(documents, new Options(), null); - } - - /** - * Update multiple documents - * - * @param documents Array of Document objects to update - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Collection mUpdateDocument(final Document[] documents, final Options options, final ResponseListener listener) throws JSONException { - if (documents.length == 0) { - throw new IllegalArgumentException("Collection.mUpdateDocument: The document array should not be empty"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put("documents", this.serializeDocuments(documents)) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "mUpdate"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #mUpdateDocument(Document[], Options, ResponseListener)} - */ - public Collection mUpdateDocument(final Document[] documents, final ResponseListener listener) throws JSONException { - return this.mUpdateDocument(documents, new Options(), listener); - } - - /** - * {@link #mUpdateDocument(Document[], Options, ResponseListener)} - */ - public Collection mUpdateDocument(final Document[] documents, Options options) throws JSONException { - return this.mUpdateDocument(documents, options, null); - } - - /** - * {@link #mUpdateDocument(Document[], Options, ResponseListener)} - */ - public Collection mUpdateDocument(final Document[] documents) throws JSONException { - return this.mUpdateDocument(documents, new Options(), null); - } - - /** - * {@link #publishMessage(Document, Options, ResponseListener)} - */ - public Collection publishMessage(final Document document) { - return this.publishMessage(document, null, null); - } - - /** - * {@link #publishMessage(Document, Options, ResponseListener)} - */ - public Collection publishMessage(final Document document, final ResponseListener listener) { - return this.publishMessage(document, null, listener); - } - - /** - * {@link #publishMessage(Document, Options, ResponseListener)} - */ - public Collection publishMessage(final Document document, final Options options) { - return this.publishMessage(document, options, null); - } - - /** - * Publish a real-time message - * - * @param document Document to publish - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection publishMessage(final Document document, final Options options, final ResponseListener listener) { - if (document == null) { - throw new IllegalArgumentException("Cannot publish a null document"); - } - - return this.publishMessage(document.getContent(), options, listener); - } - - /** - * {@link #publishMessage(JSONObject, Options, ResponseListener)} - */ - public Collection publishMessage(final JSONObject content) { - return this.publishMessage(content, null, null); - } - - /** - * {@link #publishMessage(JSONObject, Options, ResponseListener)} - */ - public Collection publishMessage(final JSONObject content, final ResponseListener listener) { - return this.publishMessage(content, null, listener); - } - - /** - * {@link #publishMessage(JSONObject, Options, ResponseListener)} - */ - public Collection publishMessage(final JSONObject content, final Options options) { - return this.publishMessage(content, options, null); - } - - /** - * Publish a real-time message - * - * @param content Message content - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection publishMessage(final JSONObject content, final Options options, final ResponseListener listener) { - if (content == null) { - throw new IllegalArgumentException("Cannot publish null content"); - } - - try { - JSONObject data = new JSONObject().put("body", content); - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("realtime", "publish"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - listener.onSuccess(response); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #replaceDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection replaceDocument(final String documentId, final JSONObject content) { - return this.replaceDocument(documentId, content, null, null); - } - - /** - * {@link #replaceDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection replaceDocument(final String documentId, final JSONObject content, final ResponseListener listener) { - return this.replaceDocument(documentId, content, null, listener); - } - - /** - * {@link #replaceDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection replaceDocument(final String documentId, final JSONObject content, final Options options) { - return this.replaceDocument(documentId, content, options, null); - } - - /** - * Replace an existing document with a new one. - * - * @param documentId Document unique identifier - * @param content New document content - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection replaceDocument(final String documentId, final JSONObject content, final Options options, final ResponseListener listener) { - if (documentId == null) { - throw new IllegalArgumentException("Collection.replaceDocument: documentId required"); - } - - try { - JSONObject data = new JSONObject().put("_id", documentId).put("body", content); - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("document", "createOrReplace"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - JSONObject result = response.getJSONObject("result"); - Document document = new Document(Collection.this, result.getString("_id"), result.getJSONObject("_source")); - document.setVersion(result.getLong("_version")); - listener.onSuccess(document); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #validateSpecifications(JSONObject, Options, ResponseListener)} - */ - public void validateSpecifications(JSONObject specifications, ResponseListener listener) throws JSONException { - this.validateSpecifications(specifications, new Options(), listener); - } - - /** - * Validates the provided specifications - * - * @param specifications Specifications content - * @param options Request options - * @param listener Response callback listener - * @throws JSONException - */ - public void validateSpecifications(JSONObject specifications, Options options, final ResponseListener listener) throws JSONException { - if (specifications == null) { - throw new IllegalArgumentException("Collection.validateSpecifications: specifications cannot be null"); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put(this.getIndex(), new JSONObject() - .put(this.getCollection(), specifications) - ) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "validateSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getBoolean("valid")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #room(RoomOptions)} - */ - public Room room() { - return this.room(null); - } - - /** - * Room object constructor, attaching it to this - * data collection - * - * @param options Request options - * @return a newly instantiated Room object - */ - public Room room(RoomOptions options) { - return new Room(this, options); - } - - /** - * {@link #setHeaders(JSONObject, boolean)} - */ - public Collection setHeaders(final JSONObject content) { - return this.setHeaders(content, false); - } - - /** - * Sets headers global to this data collection - * - * @param content Headers content - * @param replace true: replace existing headers, false: append - * @return this - */ - public Collection setHeaders(final JSONObject content, final boolean replace) { - try { - if (content == null) { - if (replace) { - this.headers = new JSONObject(); - } - - return this; - } - - if (replace) { - this.headers = new JSONObject(content.toString()); - } else { - for (Iterator ite = content.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - this.headers.put(key, content.get(key)); - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #subscribe(JSONObject, RoomOptions, ResponseListener)} - */ - public SubscribeListener subscribe(final JSONObject filters, final ResponseListener listener) { - return this.subscribe(filters, null, listener); - } - - /** - * {@link #subscribe(JSONObject, RoomOptions, ResponseListener)} - */ - public SubscribeListener subscribe(final RoomOptions options, final ResponseListener listener) { - return this.subscribe(null, options, listener); - } - - /** - * Subscribes to this data collection with a set of Kuzzle DSL filters. - * - * @param filters Subscription filters - * @param options Request options - * @param listener Response callback listener - * @return an object with a onDone() callback triggered when the subscription is active - */ - public SubscribeListener subscribe(final JSONObject filters, final RoomOptions options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Collection.subscribe: listener required"); - } - this.kuzzle.isValid(); - final Room room = new Room(this, options); - final SubscribeListener subscribeResponseListener = new SubscribeListener(); - - room.renew(filters, listener, subscribeResponseListener); - - return subscribeResponseListener; - } - - /** - * {@link #truncate(Options, ResponseListener)} - */ - public Collection truncate() { - return this.truncate(null, null); - } - - /** - * {@link #truncate(Options, ResponseListener)} - */ - public Collection truncate(final Options options) { - return this.truncate(options, null); - } - - /** - * {@link #truncate(Options, ResponseListener)} - */ - public Collection truncate(final ResponseListener listener) { - return this.truncate(null, listener); - } - - /** - * Truncate the data collection, removing all stored documents but keeping all associated mappings. - * - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection truncate(final Options options, final ResponseListener listener) { - JSONObject data = new JSONObject(); - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "truncate"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #updateDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection updateDocument(final String documentId, final JSONObject content) { - return this.updateDocument(documentId, content, null, null); - } - - /** - * {@link #updateDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection updateDocument(final String documentId, final JSONObject content, final Options options) { - return this.updateDocument(documentId, content, options, null); - } - - /** - * {@link #updateDocument(String, JSONObject, Options, ResponseListener)} - */ - public Collection updateDocument(final String documentId, final JSONObject content, final ResponseListener listener) { - return this.updateDocument(documentId, content, null, listener); - } - - /** - * Update parts of a document - * - * @param documentId Document unique identifier - * @param content Document content to update - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection updateDocument(final String documentId, final JSONObject content, final Options options, final ResponseListener listener) { - if (documentId == null) { - throw new IllegalArgumentException("Collection.updateDocument: documentId required"); - } - if (content == null) { - throw new IllegalArgumentException("Collection.updateDocument: content required"); - } - - try { - JSONObject data = new JSONObject().put("_id", documentId).put("body", content); - this.kuzzle.addHeaders(data, this.getHeaders()); - - if (options != null && options.getRetryOnConflict() > 0) { - data.put("retryOnConflict", options.getRetryOnConflict()); - } - - this.kuzzle.query(makeQueryArgs("document", "update"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - JSONObject result = response.getJSONObject("result"); - Document document = new Document(Collection.this, result.getString("_id"), result.getJSONObject("_source")); - document.setVersion(result.getLong("_version")); - document.refresh(listener); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #updateSpecifications(JSONObject, Options, ResponseListener)} - */ - public Collection updateSpecifications(final JSONObject specifications) throws JSONException { - return this.updateSpecifications(specifications, new Options(), null); - } - - /** - * {@link #updateSpecifications(JSONObject, Options, ResponseListener)} - */ - public Collection updateSpecifications(final JSONObject specifications, final Options options) throws JSONException { - return this.updateSpecifications(specifications, options, null); - } - - /** - * {@link #updateSpecifications(JSONObject, Options, ResponseListener)} - */ - public Collection updateSpecifications(final JSONObject specifications, final ResponseListener listener) throws JSONException { - return this.updateSpecifications(specifications, new Options(), listener); - } - - /** - * Updates the current specifications of this collection - * - * @param specifications Updated specifications content - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Collection updateSpecifications(final JSONObject specifications, final Options options, final ResponseListener listener) throws JSONException { - if (specifications == null) { - throw new IllegalArgumentException("Collection.updateSpecifications: specifications cannot be null"); - } - - JSONObject data = new JSONObject() - .put("body", new JSONObject() - .put(this.getIndex(), new JSONObject() - .put(this.getCollection(), specifications) - ) - ); - - try { - this.kuzzle.addHeaders(data, this.getHeaders()); - this.kuzzle.query(makeQueryArgs("collection", "updateSpecifications"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Get the attached Kuzzle object instance. - * - * @return attached Kuzzle object instance - */ - public Kuzzle getKuzzle() { - return kuzzle; - } - - /** - * Get this data collection name - * - * @return data collection name - */ - public String getCollection() { - return collection; - } - - /** - * Get the parent data index name - * - * @return parent data index name - */ - public String getIndex() { - return this.index; - } - - /** - * Get the data collection global headers - * - * @return data collection global headers - */ - public JSONObject getHeaders() { - return this.headers; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/CollectionMapping.java b/src/main/java/io/kuzzle/sdk/core/CollectionMapping.java deleted file mode 100644 index ab599ef5..00000000 --- a/src/main/java/io/kuzzle/sdk/core/CollectionMapping.java +++ /dev/null @@ -1,246 +0,0 @@ -package io.kuzzle.sdk.core; - - - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Iterator; - -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -public class CollectionMapping { - - private JSONObject headers; - private JSONObject mapping; - private Kuzzle kuzzle; - private String collection; - private Collection dataCollection; - - /** - * Constructor - * - * @param kuzzleDataCollection - Parent data collection - */ - public CollectionMapping(final Collection kuzzleDataCollection) { - this(kuzzleDataCollection, null); - } - - /** - * Constructor - * - * @param kuzzleDataCollection - Parent data collection - * @param mapping - Mapping content - */ - public CollectionMapping(final Collection kuzzleDataCollection, final JSONObject mapping) { - try { - this.headers = new JSONObject(kuzzleDataCollection.getHeaders().toString()); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - - this.kuzzle = kuzzleDataCollection.getKuzzle(); - this.collection = kuzzleDataCollection.getCollection(); - this.mapping = mapping == null ? new JSONObject() : mapping; - this.dataCollection = kuzzleDataCollection; - } - - /** - * Copy constructor - * - * @param kuzzleDataMapping - The CollectionMapping object to copy - */ - public CollectionMapping(final CollectionMapping kuzzleDataMapping) { - this(kuzzleDataMapping.dataCollection, kuzzleDataMapping.mapping); - } - - /** - * {@link #apply(Options, ResponseListener)} - */ - public CollectionMapping apply() { - return this.apply(null, null); - } - - /** - * {@link #apply(Options, ResponseListener)} - */ - public CollectionMapping apply(final Options options) { - return this.apply(options, null); - } - - /** - * {@link #apply(Options, ResponseListener)} - */ - public CollectionMapping apply(final ResponseListener listener) { - return this.apply(null, listener); - } - - /** - * Applies this mapping content to the data collection. - * - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public CollectionMapping apply(final Options options, final ResponseListener listener) { - JSONObject data = new JSONObject(); - JSONObject properties = new JSONObject(); - try { - properties.put("properties", this.mapping); - data.put("body", properties); - this.kuzzle.addHeaders(data, this.headers); - this.kuzzle.query(this.dataCollection.makeQueryArgs("collection", "updateMapping"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - listener.onSuccess(CollectionMapping.this); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #refresh(Options, ResponseListener)} - */ - public void refresh(final ResponseListener listener) { - refresh(null, listener); - } - - /** - * Gets a refreshed copy of the current object - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void refresh(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("CollectionMapping.refresh: listener callback missing"); - } - - JSONObject data = new JSONObject(); - try { - this.kuzzle.addHeaders(data, this.headers); - this.kuzzle.query(this.dataCollection.makeQueryArgs("collection", "getMapping"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject args) { - try { - CollectionMapping newMapping = new CollectionMapping(CollectionMapping.this.dataCollection); - JSONObject mappings = args.getJSONObject(CollectionMapping.this.dataCollection.getIndex()).getJSONObject("mappings"); - newMapping.mapping = mappings.getJSONObject(CollectionMapping.this.collection); - - listener.onSuccess(newMapping); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject object) { - listener.onError(object); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Remove a field from this mapping - * Changes made by this function won't be applied until you call the apply method - * - * @param field - Field name to remove - * @return this - */ - public CollectionMapping remove(final String field) { - if (this.mapping.has(field)) { - CollectionMapping.this.mapping.remove(field); - } - - return this; - } - - /** - * Attach a mapping to a field - * - * @param field - Field name - * @param mapping - Field mapping - * @return this - * @throws JSONException - */ - public CollectionMapping set(final String field, final JSONObject mapping) throws JSONException { - this.mapping.put(field, mapping); - return this; - } - - /** - * Get the global headers for this object - * - * @return global headers for this object - */ - public JSONObject getHeaders() { - return headers; - } - - /** - * {@link #setHeaders(JSONObject, boolean)} - */ - public CollectionMapping setHeaders(final JSONObject content) { - return this.setHeaders(content, false); - } - - /** - * Helper function allowing to set headers while chaining calls. - * If the replace argument is set to true, replace the current headers with the provided content. - * Otherwise, it appends the content to the current headers, only replacing already existing values - * - * @param content - Headers to append or replace - * @param replace - false (default): append the content, true: replace the current headers - * @return this - */ - public CollectionMapping setHeaders(final JSONObject content, final boolean replace) { - try { - if (content == null) { - if (replace) { - this.headers = new JSONObject(); - } - - return this; - } - - if (replace) { - this.headers = new JSONObject(content.toString()); - } else { - for (Iterator ite = content.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - this.headers.put(key, content.get(key)); - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Get this mapping raw content - * - * @return mapping raw content - */ - public JSONObject getMapping() { - return mapping; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/Document.java b/src/main/java/io/kuzzle/sdk/core/Document.java deleted file mode 100644 index 021dc3c1..00000000 --- a/src/main/java/io/kuzzle/sdk/core/Document.java +++ /dev/null @@ -1,628 +0,0 @@ -package io.kuzzle.sdk.core; - - - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Iterator; - -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.SubscribeListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.NotificationResponse; - -public class Document { - private final Collection dataCollection; - private final String collection; - private final Kuzzle kuzzle; - private JSONObject headers; - - private String id; - private JSONObject content; - private JSONObject meta; - private long version = -1; - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @param id - Unique document identifier - * @param content - The content of the document - * @param meta - Document metadata - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection, final String id, final JSONObject content, final JSONObject meta) throws JSONException { - if (kuzzleDataCollection == null) { - throw new IllegalArgumentException("Document: Collection argument missing"); - } - - this.dataCollection = kuzzleDataCollection; - this.collection = kuzzleDataCollection.getCollection(); - this.kuzzle = kuzzleDataCollection.getKuzzle(); - this.setId(id); - this.setContent(content, true); - - if (meta != null) { - this.meta = new JSONObject(meta.toString()); - } - - this.headers = kuzzleDataCollection.getHeaders(); - } - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @param id - Unique document identifier - * @param content - The content of the document - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection, final String id, final JSONObject content) throws JSONException { - this(kuzzleDataCollection, id, content, null); - } - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection) throws JSONException { - this(kuzzleDataCollection, null, null, null); - } - - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @param id - Unique document identifier - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection, final String id) throws JSONException { - this(kuzzleDataCollection, id, null, null); - } - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @param content - The content of the document - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection, final JSONObject content) throws JSONException { - this(kuzzleDataCollection, null, content, null); - } - - /** - * Kuzzle handles documents either as real-time messages or as stored documents. - * Document is the object representation of one of these documents. - * - * @param kuzzleDataCollection - An instantiated Collection object - * @param content - The content of the document - * @param meta - Document metadata - * @throws JSONException - */ - public Document(final Collection kuzzleDataCollection, final JSONObject content, final JSONObject meta) throws JSONException { - this(kuzzleDataCollection, null, content, meta); - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete(final Options options) { - this.delete(options, null); - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete(final ResponseListener listener) { - this.delete(null, listener); - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete() { - this.delete(null, null); - } - - /** - * Delete this document from Kuzzle - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void delete(final Options options, final ResponseListener listener) { - try { - if (this.id == null) { - throw new IllegalStateException("Document.delete: cannot delete a document without a document ID"); - } - - this.kuzzle.query(this.dataCollection.makeQueryArgs("document", "delete"), this.serialize(), options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - setId(null); - if (listener != null) { - try { - listener.onSuccess(object.getString("result")); - } catch (JSONException e) { - e.printStackTrace(); - }; - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #exists(Options, ResponseListener)} - */ - public void exists(final ResponseListener listener) { - this.exists(null, listener); - } - - /** - * Ask Kuzzle if this document exists - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void exists(final Options options, final ResponseListener listener) { - if (this.id == null) { - throw new IllegalStateException("Document.exists: cannot check if the document exists if no id has been provided"); - } - - if (listener == null) { - throw new IllegalArgumentException("Document.exists: a valid ResponseListener object is required"); - } - - try { - this.kuzzle.query(this.dataCollection.makeQueryArgs("document", "exists"), this.serialize(), options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - listener.onSuccess(object.getBoolean("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #refresh(Options, ResponseListener)} - */ - public void refresh(final ResponseListener listener) { - this.refresh(null, listener); - } - - /** - * Gets a refreshed copy of this document from Kuzzle - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void refresh(final Options options, final ResponseListener listener) { - if (this.id == null) { - throw new IllegalStateException("Document.refresh: cannot retrieve a document if no id has been provided"); - } - - if (listener == null) { - throw new IllegalArgumentException("Document.refresh: a valid ResponseListener object is required"); - } - - try { - JSONObject content = new JSONObject(); - content.put("_id", this.getId()); - - this.kuzzle.query(this.dataCollection.makeQueryArgs("document", "get"), content, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject args) { - try { - JSONObject result = args.getJSONObject("result"); - Document newDocument = new Document( - Document.this.dataCollection, - result.getString("_id"), - result.getJSONObject("_source"), - result.getJSONObject("_meta") - ); - - newDocument.setVersion(result.getLong("_version")); - listener.onSuccess(newDocument); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject arg) { - listener.onError(arg); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Document save() { - return save(null, null); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Document save(final Options options) { - return this.save(options, null); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Document save(final ResponseListener listener) { - return save(null, listener); - } - - /** - * Saves this document into Kuzzle. - * If this is a new document, this function will create it in Kuzzle and the id property will be made available. - * Otherwise, this method will replace the latest version of this document in Kuzzle by the current content of this object. - * - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Document save(final Options options, final ResponseListener listener) { - try { - kuzzle.query(this.dataCollection.makeQueryArgs("document", "createOrReplace"), this.serialize(), options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - Document.this.setId(result.getString("_id")); - Document.this.setVersion(result.getLong("_version")); - - if (listener != null) { - listener.onSuccess(Document.this); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #publish(Options)} - */ - public Document publish() { - return this.publish(null); - } - - /** - * Sends the content of this document as a real-time message. - * - * @param options - Request options - * @return this - */ - public Document publish(final Options options) { - try { - kuzzle.query(this.dataCollection.makeQueryArgs("realtime", "publish"), this.serialize(), options, null); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #setContent(JSONObject, boolean)} - */ - public Document setContent(final JSONObject content) throws JSONException { - this.setContent(content, false); - return this; - } - - /** - * Sets this document content - * - * @param content - New content for this document - * @param replace - true: replace the current content, false (default): update/append it - * @return this - * @throws JSONException - */ - public Document setContent(final JSONObject content, final boolean replace) throws JSONException { - if (replace) { - if (content != null) { - this.content = new JSONObject(content.toString()); - } - else { - this.content = new JSONObject(); - } - } else if (content != null) { - for (Iterator iterator = content.keys(); iterator.hasNext(); ) { - String key = (String) iterator.next(); - this.content.put(key, content.get(key)); - } - } - - if (this.content.has("version")) { - Object version = this.content.get("version"); - if (version instanceof Long || version instanceof Integer) { - this.version = this.content.getLong("version"); - this.content.remove("version"); - } - } - - return this; - } - - /** - * Set a document field value - * - * @param key - Field name to set - * @param value - New field value - * @return this - * @throws JSONException - */ - public Document setContent(final String key, final Object value) throws JSONException { - if (key == null) { - throw new IllegalArgumentException("Document.setContent: key required"); - } - - this.content.put(key, value); - return this; - } - - /** - * {@link #subscribe(RoomOptions, ResponseListener)} - */ - public SubscribeListener subscribe(final ResponseListener listener) { - return this.subscribe(null, listener); - } - - /** - * Subscribe to changes occuring on this document. - * Throws an error if this document has not yet been created in Kuzzle. - * - * @param options - Room object constructor options - * @param listener - Response callback listener - * @return an object with a "onDone" callback triggered when the subscription is active - */ - public SubscribeListener subscribe(final RoomOptions options, final ResponseListener listener) { - if (this.id == null) { - throw new IllegalStateException("Document.subscribe: cannot subscribe to a document if no ID has been provided"); - } - - SubscribeListener returnValue; - - try { - JSONObject filters = new JSONObject("{" + - "\"ids\": {" + - "\"values\": [\"" + this.id + "\"]" + - "}" + - "}"); - returnValue = this.dataCollection.subscribe(filters, options, listener); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return returnValue; - } - - /** - * Get the parent data collection name - * - * @return parent data collection name - */ - public String getCollection() { - return collection; - } - - /** - * Document content getter - * - * @return current document content - */ - public JSONObject getContent() { - return this.content; - } - - - /** - * Get document content field - * - * @param key - Field name to get - * @return field value - * @throws JSONException - */ - public Object getContent(final String key) throws JSONException { - if (this.content.has(key)) { - return this.content.get(key); - } - - return null; - } - - /** - * Document metadata getter - * - * @return this document metadata - */ - public JSONObject getMeta() { - return this.meta; - } - - - /** - * Get a metadata field value - * - * @param key - Metadata field name to get - * @return metadata field value - * @throws JSONException - */ - public Object getMeta(final String key) throws JSONException { - if (this.meta.has(key)) { - return this.meta.get(key); - } - - return null; - } - - /** - * {@link #setHeaders(JSONObject, boolean)} - */ - public Document setHeaders(final JSONObject content) { - return this.setHeaders(content, false); - } - - /** - * Replace or append/update global headers for this object - * - * @param content - new headers content - * @param replace - true: replace the current headers, false (default): append/update - * @return this - */ - public Document setHeaders(final JSONObject content, final boolean replace) { - try { - if (content == null) { - if (replace) { - this.content = new JSONObject(); - } - - return this; - } - - if (replace) { - this.headers = new JSONObject(content.toString()); - } else { - for (Iterator ite = content.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - this.headers.put(key, content.get(key)); - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * Get the global headers for this object - * - * @return global headers for this object - */ - public JSONObject getHeaders() { - return this.headers; - } - - /** - * Unique identifier getter - * - * @return this document unique identifier - */ - public String getId() { - return this.id; - } - - /** - * Set this document unique identifier - * - * @param id - New document unique identifier - * @return this - */ - public Document setId(final String id) { - this.id = id; - return this; - } - - /** - * Get this document version - * - * @return this document version - */ - public long getVersion() { - return this.version; - } - - /** - * Serializes this document into a plain old JSON object - * - * @return JSON object representing this document - */ - public JSONObject serialize() { - JSONObject data = new JSONObject(); - - try { - if (this.id != null) { - data.put("_id", this.getId()); - } - - if (this.version != -1) { - data.put("_version", this.version); - } - - data.put("body", this.getContent()); - this.kuzzle.addHeaders(data, getHeaders()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - - return data; - } - - public String toString() { - return this.serialize().toString(); - } - - /** - * Set this document version - * - * @param version - New document version - * @return this - */ - public Document setVersion(long version) { - if (version > 0) { - this.version = version; - } - - return this; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/Kuzzle.java b/src/main/java/io/kuzzle/sdk/core/Kuzzle.java deleted file mode 100644 index 277db6ab..00000000 --- a/src/main/java/io/kuzzle/sdk/core/Kuzzle.java +++ /dev/null @@ -1,2785 +0,0 @@ -package io.kuzzle.sdk.core; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Calendar; -import java.util.Date; -import java.util.Iterator; -import java.util.Map; -import java.util.Queue; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.TokenValidity; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; -import io.kuzzle.sdk.state.KuzzleQueue; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.EventList; -import io.kuzzle.sdk.util.OfflineQueueLoader; -import io.kuzzle.sdk.util.QueryObject; -import io.kuzzle.sdk.util.QueueFilter; -import tech.gusavila92.websocketclient.WebSocketClient; - -/** - * The type Kuzzle. - */ -public class Kuzzle { - private final int MAX_EMIT_TIMEOUT = 10; - private final int EVENT_TIMEOUT = 200; - - protected ConcurrentHashMap eventListeners = new ConcurrentHashMap<>(); - - protected WebSocketClient socket; - protected ConcurrentHashMap currentQueries = new ConcurrentHashMap<>(); - protected ConcurrentHashMap roomList = new ConcurrentHashMap<>(); - - protected Map> collections = new ConcurrentHashMap<>(); - protected boolean autoReconnect = true; - protected JSONObject headers = new JSONObject(); - protected JSONObject _volatile; - protected String host; - protected Integer port; - protected boolean isSsl; - protected ResponseListener connectionCallback; - protected States state = States.INITIALIZING; - protected long reconnectionDelay; - protected boolean autoResubscribe; - protected boolean autoQueue; - protected boolean autoReplay; - - protected QueueFilter queueFilter = new QueueFilter() { - @Override - public boolean filter(JSONObject object) { - return true; - } - }; - - protected long replayInterval; - protected boolean queuing = false; - protected String defaultIndex; - protected ConcurrentHashMap requestHistory = new ConcurrentHashMap<>(); - protected KuzzleQueue offlineQueue = new KuzzleQueue<>(); - protected int queueTTL; - protected int queueMaxSize; - protected String jwtToken = null; - - /* - This property contains the centralized subscription list in the following format: - roomId: - kuzzleRoomID_1: kuzzleRoomInstance_1, - kuzzleRoomID_2: kuzzleRoomInstance_2, - ... - pending: // pending subscriptions - kuzzleRoomID_x: kuzzleRoomInstance_x, - ... - - This was made to allow multiple subscriptions on the same set of filters, - something that Kuzzle does not permit. - This structure also allows renewing subscriptions after a connection loss - */ - protected ConcurrentHashMap> subscriptions = new ConcurrentHashMap<>(); - - private OfflineQueueLoader offlineQueueLoader; - - /** - * Security static class - */ - public Security security; - - private ResponseListener loginCallback; - - public MemoryStorage memoryStorage; - - public static class QueryArgs { - public String controller; - public String action; - public String index; - public String collection; - } - - /** - * Emit an event to all registered listeners - * An event cannot be emitted multiple times before a timeout has been reached. - * - * @param event - Event name to emit - * @param args - Event payload - */ - protected void emitEvent(Event event, Object... args) { - long now = System.currentTimeMillis(); - - if (this.eventListeners.containsKey(event)) { - EventList l = this.eventListeners.get(event); - - if (l.lastEmitted < now - this.EVENT_TIMEOUT) { - for (io.kuzzle.sdk.util.Event e : l.values()) { - e.trigger(args); - } - - l.lastEmitted = now; - } - } - } - - /** - * Connection status getter - * @return Connection status - */ - public States getState() { - return state; - } - - /** - * Constructor - * - * @param host - Target host name or IP address - * @param options - Request options - * @param connectionCallback - On success callback listener - * @throws URISyntaxException - */ - public Kuzzle(final String host, final Options options, final ResponseListener connectionCallback) throws URISyntaxException { - if (host == null || host.isEmpty()) { - throw new IllegalArgumentException("Host name/address can't be empty"); - } - - this.host = host; - - Options opt = (options != null ? options : new Options()); - - this.autoQueue = opt.isAutoQueue(); - this.autoReconnect = opt.isAutoReconnect(); - this.autoReplay = opt.isAutoReplay(); - this.autoResubscribe = opt.isAutoResubscribe(); - this.defaultIndex = opt.getDefaultIndex(); - this.headers = opt.getHeaders(); - this._volatile = opt.getVolatile(); - this.port = opt.getPort(); - this.isSsl = opt.isSsl(); - this.queueMaxSize = opt.getQueueMaxSize(); - this.queueTTL = opt.getQueueTTL(); - this.reconnectionDelay = opt.getReconnectionDelay(); - this.replayInterval = opt.getReplayInterval(); - - this.connectionCallback = connectionCallback; - - if (opt.getOfflineMode() == Mode.AUTO) { - this.autoReconnect = this.autoQueue = this.autoReplay = this.autoResubscribe = true; - } - if (opt.getConnect() == Mode.AUTO) { - connect(); - } else { - this.state = States.READY; - } - - this.security = new Security(this); - this.memoryStorage = new MemoryStorage(this); - this.subscriptions.put("pending", new ConcurrentHashMap()); - } - - /** - * Constructor - * - * @param host - Target Kuzzle host name or IP address - * @throws URISyntaxException - */ - public Kuzzle(final String host) throws URISyntaxException { - this(host, null, null); - } - - /** - * Constructor - * - * @param host - Target Kuzzle host name or IP address - * @param cb - On success connection callback listener - * @throws URISyntaxException - */ - public Kuzzle(final String host, final ResponseListener cb) throws URISyntaxException { - this(host, null, cb); - } - - /** - * Constructor - * - * @param host - Target Kuzzle host name or IP address - * @param options - Request options - * @throws URISyntaxException - */ - public Kuzzle(final String host, Options options) throws URISyntaxException { - this(host, options, null); - } - - /** - * Adds a listener to a Kuzzle global event. When an event is triggered, - * listeners are called in the order of their insertion. - * - * @param kuzzleEvent - Name of the global event to subscribe to - * @param listener - Response callback listener - * @return this - */ - public Kuzzle addListener(final Event kuzzleEvent, final EventListener listener) { - this.isValid(); - - io.kuzzle.sdk.util.Event e = new io.kuzzle.sdk.util.Event(kuzzleEvent) { - @Override - public void trigger(Object... args) { - listener.trigger(args); - } - }; - - if (!eventListeners.containsKey(kuzzleEvent)) { - eventListeners.put(kuzzleEvent, new EventList()); - } - - eventListeners.get(kuzzleEvent).put(listener, e); - return this; - } - - /** - * Check an authentication token validity - * - * @param token - Token to check (JWT) - * @param listener - Response callback listener - */ - public void checkToken(final String token, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.checkToken: listener required"); - } - - if (token == null || token.isEmpty()) { - throw new IllegalArgumentException("Kuzzle.checkToken: token required"); - } - - try { - QueryArgs args = new QueryArgs(); - args.controller = "auth"; - args.action = "checkToken"; - JSONObject request = new JSONObject(); - request.put("body", new JSONObject().put("token", token)); - this.query(args, request, new Options().setQueuable(false), new OnQueryDoneListener() { - - @Override - public void onSuccess(JSONObject response) { - try { - TokenValidity validity = new TokenValidity(); - JSONObject result = response.getJSONObject("result"); - validity.setValid(result.getBoolean("valid")); - if (validity.isValid()) { - validity.setExpiresAt(new Date(result.getLong("expiresAt"))); - } else { - validity.setState(result.getString("state")); - } - listener.onSuccess(validity); - } catch (JSONException e) { - throw new RuntimeException(); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Connects to a Kuzzle instance using the provided host and port. - * - * @return this - * @throws URISyntaxException - */ - public Kuzzle connect() throws URISyntaxException { - if (!this.isValidState()) { - if (connectionCallback != null) { - connectionCallback.onSuccess(null); - return this; - } - } - - if (this.socket != null) { - this.disconnect(); - } - - this.socket = createSocket(); - - Kuzzle.this.state = States.CONNECTING; - - if (socket != null) { - socket.connect(); - } - - return this; - } - - /** - * Collection object factory. Default index must be set. - * - * @param collection - Data collection name - * @return Instantiated Collection object - */ - public Collection collection(final String collection) { - this.isValid(); - if (this.defaultIndex == null) { - throw new IllegalArgumentException("Collection: unable to create a new data collection object: no index specified"); - } - - return this.collection(collection, this.defaultIndex); - } - - /** - * Collection object factory - * - * @param collection - Data collection name - * @param index - Parent data index name - * @return Instantiated Collection object - */ - public Collection collection(final String collection, final String index) { - this.isValid(); - if (index == null && this.defaultIndex == null) { - throw new IllegalArgumentException("Collection: unable to create a new data collection object: no index specified"); - } - - if (!this.collections.containsKey(collection)) { - Map col = new ConcurrentHashMap<>(); - col.put(collection, new Collection(this, collection, index)); - this.collections.put(index, col); - } - return this.collections.get(index).get(collection); - } - - /** - * {@link #createIndex(String, Options, ResponseListener)} - */ - public Kuzzle createIndex(final String index, final ResponseListener cb) { - return createIndex(index, null, cb); - } - - /** - * {@link #createIndex(String, Options, ResponseListener)} - */ - public Kuzzle createIndex(final String index) { - return createIndex(index, null, null); - } - - /** - * Create a new data index - * - * @param index - index name to create - * @param options - Request options - * @param cb - Response callback listener - * @return this - */ - public Kuzzle createIndex(final String index, final Options options, final ResponseListener cb) { - if (index == null && defaultIndex == null) { - throw new IllegalArgumentException("Collection.createIndex: index required"); - } - - QueryArgs args = new QueryArgs(); - args.controller = "index"; - args.action = "create"; - - JSONObject request = new JSONObject(); - try { - request.put("index", index == null ? defaultIndex : index); - this.query(args, request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - cb.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - cb.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Empties the offline queue without replaying it. - * - * @return this - */ - public Kuzzle flushQueue() { - this.getOfflineQueue().clear(); - return this; - } - - /** - * {@link #getAllStatistics(Options, ResponseListener)} - */ - public void getAllStatistics(final ResponseListener listener) { - this.getAllStatistics(null, listener); - } - - /** - * Get all Kuzzle usage statistics frames - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void getAllStatistics(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getAllStatistics: listener required"); - } - - this.isValid(); - try { - QueryArgs args = new QueryArgs(); - args.controller = "server"; - args.action = "getAllStats"; - this.query(args, null, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - JSONArray hits = object.getJSONObject("result").getJSONArray("hits"); - JSONObject[] frames = new JSONObject[hits.length()]; - - for(int i = 0; i < hits.length(); i++) { - frames[i] = hits.getJSONObject(i); - } - - listener.onSuccess(frames); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getStatistics(Options, ResponseListener)} - */ - public void getStatistics(final ResponseListener listener) { - this.getStatistics(null, listener); - } - - /** - * Get Kuzzle usage statistics - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void getStatistics(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getStatistics: listener required"); - } - this.isValid(); - JSONObject body = new JSONObject(); - JSONObject data = new JSONObject(); - - try { - body.put("body", data); - QueryArgs args = new QueryArgs(); - args.controller = "server"; - args.action = "getLastStats"; - this.query(args, body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(new JSONObject[]{response.getJSONObject("result")}); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getStatistics(long, Options, ResponseListener)} - */ - public void getStatistics(long timestamp, final ResponseListener listener) { - this.getStatistics(timestamp, null, listener); - } - - /** - * Get Kuzzle usage statistics starting from a provided timestamp - * - * @param timestamp - Statistic starting time to retrieve - * @param options - Request options - * @param listener - Response callback listener - */ - public void getStatistics(long timestamp, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getStatistics: listener required"); - } - - this.isValid(); - JSONObject body = new JSONObject(); - JSONObject data = new JSONObject(); - - try { - data.put("since", timestamp); - body.put("body", data); - QueryArgs args = new QueryArgs(); - args.controller = "server"; - args.action = "getStats"; - this.query(args, body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray hits = response.getJSONObject("result").getJSONArray("hits"); - JSONObject[] stats = new JSONObject[hits.length()]; - - for (int i = 0; i < hits.length(); i++) { - stats[i] = hits.getJSONObject(i); - } - - listener.onSuccess(stats); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getServerInfo(Options, ResponseListener)} - */ - public void getServerInfo(final ResponseListener listener) { - this.getServerInfo(null, listener); - } - - /** - * Gets server info. - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void getServerInfo(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getServerInfo: listener required"); - } - QueryArgs args = new QueryArgs(); - args.controller = "server"; - args.action = "info"; - try { - this.query(args, null, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getJSONObject("serverInfo")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #listCollections(Options, ResponseListener)} - */ - public void listCollections(final ResponseListener listener) { - this.listCollections(null, null, listener); - } - - /** - * {@link #listCollections(String, Options, ResponseListener)} - */ - public void listCollections(String index, final ResponseListener listener) { - this.listCollections(index, null, listener); - } - - /** - * List data collections on the default data index - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void listCollections(Options options, final ResponseListener listener) { - this.listCollections(null, options, listener); - } - - /** - * List data collections - * - * @param index - Parent data index name - * @param options - Request options - * @param listener - Response callback listener - */ - public void listCollections(String index, Options options, final ResponseListener listener) { - if (index == null) { - if (this.defaultIndex == null) { - throw new IllegalArgumentException("Kuzzle.listCollections: index required"); - } else { - index = this.defaultIndex; - } - } - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.listCollections: listener required"); - } - try { - QueryArgs args = new QueryArgs(); - args.controller = "collection"; - args.action = "list"; - args.index = index; - JSONObject query = new JSONObject(); - if (options == null) { - options = new Options(); - } - JSONObject body = new JSONObject().put("type", options.getCollectionType()); - query.put("body", body); - this.query(args, query, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject collections) { - try { - JSONArray result = collections.getJSONObject("result").getJSONArray("collections"); - JSONObject[] cols = new JSONObject[result.length()]; - - for (int i = 0; i < result.length(); i++) { - cols[i] = result.getJSONObject(i); - } - - listener.onSuccess(cols); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #listIndexes(Options, ResponseListener)} - */ - public void listIndexes(final ResponseListener listener) { - this.listIndexes(null, listener); - } - - /** - * List data indexes - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void listIndexes(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.listIndexes: listener required"); - } - QueryArgs args = new QueryArgs(); - args.controller = "index"; - args.action = "list"; - try { - this.query(args, null, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray array = response.getJSONObject("result").getJSONArray("indexes"); - int length = array.length(); - String[] indexes = new String[length]; - for (int i = 0; i < length; i++) { - indexes[i] = array.getString(i); - } - listener.onSuccess(indexes); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy) { - this.login(strategy, null, -1, null); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final JSONObject credentials) { - this.login(strategy, credentials, -1, null); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final int expiresIn) { - this.login(strategy, null, expiresIn, null); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final JSONObject credentials, final int expiresIn) { - this.login(strategy, credentials, expiresIn, null); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final JSONObject credentials, final ResponseListener listener) { - this.login(strategy, credentials, -1, listener); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final ResponseListener listener) { - this.login(strategy, null, -1, listener); - } - - /** - * {@link #login(String, JSONObject, int, ResponseListener)} - */ - public void login(final String strategy, final int expiresIn, final ResponseListener listener) { - this.login(strategy, null, expiresIn, listener); - } - - /** - * Log- Strategy name to use for the authentication - * - * @param strategy - Strategy name to use for the authentication - * @param credentials - Login credentials - * @param expiresIn - Token expiration delay - * @param listener - Response callback listener - */ - public void login(final String strategy, final JSONObject credentials, int expiresIn, final ResponseListener listener) { - if (strategy == null) { - throw new IllegalArgumentException("Kuzzle.login: cannot authenticate to Kuzzle without an authentication strategy"); - } - - this.loginCallback = listener; - - try { - Options options = new Options(); - JSONObject query = new JSONObject(); - JSONObject body = new JSONObject(); - if (credentials != null) { - body = credentials; - } - - if (expiresIn >= 0) { - query.put("expiresIn", expiresIn); - } - - query.put("strategy", strategy); - - query.put("body", body); - QueryArgs args = new QueryArgs(); - args.controller = "auth"; - args.action = "login"; - options.setQueuable(false); - - this.query(args, query, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - JSONObject result = object.getJSONObject("result"); - - if (result.has("jwt")) { - Kuzzle.this.setJwtToken(result.getString("jwt")); - } - - if (listener != null) { - listener.onSuccess(result); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - try { - emitEvent(Event.loginAttempt, new JSONObject() - .put("success", false) - .put("error", error)); - } catch (JSONException e) { - throw new RuntimeException(e); - } - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Disconnect from Kuzzle and invalidate this instance. - * Does not fire a disconnected event. - */ - public void disconnect() { - if (this.socket != null) { - this.socket.close(); - } - - this.socket = null; - this.collections.clear(); - this.state = States.DISCONNECTED; - } - - /** - * {@link #logout(ResponseListener)} - */ - public Kuzzle logout() { - return this.logout(null); - } - - /** - * Logout method - * - * @param listener - Response callback listener - * @return this - */ - public Kuzzle logout(final ResponseListener listener) { - Options options = new Options(); - - options.setQueuable(false); - - try { - QueryArgs args = new QueryArgs(); - args.controller = "auth"; - args.action = "logout"; - - this.query(args, new JSONObject(), options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - if (listener != null) { - listener.onSuccess(null); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - Kuzzle.this.jwtToken = null; - return this; - } - - /** - * {@link #now(Options, ResponseListener)} - */ - public void now(final ResponseListener listener) { - this.now(null, listener); - } - - /** - * Returns the current Kuzzle UTC timestamp - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void now(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.now: listener required"); - } - this.isValid(); - try { - QueryArgs args = new QueryArgs(); - args.controller = "server"; - args.action = "now"; - this.query(args, null, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(new Date(response.getJSONObject("result").getLong("now"))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #query(QueryArgs, JSONObject, Options, OnQueryDoneListener)} - */ - public Kuzzle query(final QueryArgs queryArgs, final JSONObject query) throws JSONException { - return this.query(queryArgs, query, null, null); - } - - /** - * {@link #query(QueryArgs, JSONObject, Options, OnQueryDoneListener)} - */ - public Kuzzle query(final QueryArgs queryArgs, final JSONObject query, final Options options) throws JSONException { - return this.query(queryArgs, query, options, null); - } - - /** - * {@link #query(QueryArgs, JSONObject, Options, OnQueryDoneListener)} - */ - public Kuzzle query(final QueryArgs queryArgs, final JSONObject query, final OnQueryDoneListener listener) throws JSONException { - return this.query(queryArgs, query, null, listener); - } - - /** - * This is a low-level method, exposed to allow advanced SDK users to bypass high-level methods. - * Base method used to send queries to Kuzzle - * - * @param queryArgs - API route description - * @param query - Query content - * @param options - Request options - * @param listener - Response callback listener - * @return this - * @throws JSONException - */ - public Kuzzle query(final QueryArgs queryArgs, final JSONObject query, final Options options, final OnQueryDoneListener listener) throws JSONException { - this.isValid(); - JSONObject object = query != null ? query : new JSONObject(); - - if (object.isNull("requestId")) { - object.put("requestId", UUID.randomUUID().toString()); - } - - object - .put("action", queryArgs.action) - .put("controller", queryArgs.controller); - - // Global volatile data - JSONObject _volatile = new JSONObject(); - for (Iterator ite = this._volatile.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - _volatile.put(key, this._volatile.get(key)); - } - - // Volatile data for this query - if (options != null) { - if (!options.isQueuable() && this.state != States.CONNECTED) { - discardRequest(listener, object); - return this; - } - - if (options.getRefresh() != null) { - object.put("refresh", options.getRefresh()); - } - - if (options.getVolatile() != null) { - for (Iterator iterator = options.getVolatile().keys(); iterator.hasNext(); ) { - String key = (String) iterator.next(); - _volatile.put(key, options.getVolatile().get(key)); - } - } - - if (options.getFrom() != null) { - object.put("from", options.getFrom()); - } - - if (options.getSize() != null) { - object.put("size", options.getSize()); - } - - if (options.getScroll() != null) { - object.put("scroll", options.getScroll()); - } - - if (options.getScrollId() != null) { - object.put("scrollId", options.getScrollId()); - } - } - - _volatile.put("sdkVersion", this.getSdkVersion()); - object.put("volatile", _volatile); - - if (queryArgs.collection != null) { - object.put("collection", queryArgs.collection); - } - - if (queryArgs.index != null) { - object.put("index", queryArgs.index); - } - - this.addHeaders(object, this.headers); - - /* - * Do not add the token for the checkToken route, to avoid getting a token error when - * a developer simply wish to verify his token - */ - if (this.jwtToken != null && !(queryArgs.controller.equals("auth") && queryArgs.action.equals("checkToken"))) { - object.put("jwt", this.jwtToken); - } - - if (this.state == States.CONNECTED || (options != null && !options.isQueuable())) { - emitRequest(object, listener == null ? null : new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(response); - } - - @Override - public void onError(JSONObject error) { - if (error != null) { - listener.onError(error); - } - } - }); - } else if (this.queuing || (options != null && options.isQueuable()) || this.state == States.INITIALIZING || this.state == States.CONNECTING) { - cleanQueue(); - - if (queueFilter.filter(object)) { - QueryObject o = new QueryObject(); - o.setTimestamp(new Date()); - o.setCb(listener); - o.setQuery(object); - this.offlineQueue.addToQueue(o); - Kuzzle.this.emitEvent(Event.offlineQueuePush, o); - } - } else { - discardRequest(listener, object); - } - - return this; - } - - /** - * Removes all listeners, either from all events - * - * @return this - */ - public Kuzzle removeAllListeners() { - this.eventListeners.clear(); - return this; - } - - /** - * Remove all listeners kuzzle from the provided event name - * - * @param event - Event name - * @return this - */ - public Kuzzle removeAllListeners(Event event) { - if (eventListeners.containsKey(event)) { - eventListeners.get(event).clear(); - } - - return this; - } - - /** - * Removes a listener from an event. - * - * @param event - Event name - * @param listener - Response callback listener - * @return this - */ - public Kuzzle removeListener(Event event, EventListener listener) { - if (eventListeners.containsKey(event)) { - eventListeners.get(event).remove(listener); - } - - return this; - } - - /** - * Renew all registered subscriptions. Usually called after: - * - a connection, if subscriptions occurred before - * - a reconnection - * - after a successful login attempt, to subscribe with the new credentials - */ - protected void renewSubscriptions() { - for (Map roomSubscriptions : subscriptions.values()) { - for (Room room : roomSubscriptions.values()) { - room.renew(room.getListener(), room.getSubscribeListener()); - } - } - } - - /** - * Replays the requests queued during offline mode. - * Works only if the SDK is not in a disconnected state, and if the autoReplay option is set to false. - * - * @return this - */ - public Kuzzle replayQueue() { - if (this.state != States.OFFLINE && !this.autoReplay) { - this.cleanQueue(); - this.dequeue(); - } - return this; - } - - /** - * {@link #setHeaders(JSONObject, boolean)} - */ - public Kuzzle setHeaders(final JSONObject content) throws JSONException { - return this.setHeaders(content, false); - } - - /** - * Helper function allowing to set headers while chaining calls. - * If the replace argument is set to true, replace the current headers with the provided content. - * Otherwise, it appends the content to the current headers, only replacing already existing values - * - * @param content - New headers content - * @param replace - false = append to existing headers (default) - true = replace - * @return this - */ - public Kuzzle setHeaders(final JSONObject content, boolean replace) { - if (this.headers == null) { - this.headers = new JSONObject(); - } - if (replace) { - this.headers = content; - } else { - if (content != null) { - try { - for (Iterator ite = content.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - this.headers.put(key, content.get(key)); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - return this; - } - - /** - * Starts the requests queuing. Works only during offline mode, and if the autoQueue option is set to false. - * - * @return this - */ - public Kuzzle startQueuing() { - if (this.state == States.OFFLINE && !this.autoQueue) { - this.queuing = true; - } - return this; - } - - /** - * Stops the requests queuing. Works only during offline mode, and if the autoQueue option is set to false. - * - * @return this - */ - public Kuzzle stopQueuing() { - if (this.state == States.OFFLINE && !this.autoQueue) { - this.queuing = false; - } - return this; - } - - /** - * Is valid sate boolean. - * - * @return current state validity - */ - protected boolean isValidState() { - switch (this.state) { - case INITIALIZING: - case READY: - case DISCONNECTED: - case ERROR: - case OFFLINE: - return true; - } - return false; - } - - /** - * Handles network reconnection - */ - private void reconnect() { - if (this.autoResubscribe) { - this.renewSubscriptions(); - } - - if (this.autoReplay) { - this.cleanQueue(); - this.dequeue(); - } - - this.emitEvent(Event.reconnected); - } - - /** - * Create a new connection socket - * @return created socket - * @throws URISyntaxException - */ - protected WebSocketClient createSocket() throws URISyntaxException { - URI uri = null; - try { - uri = new URI((this.isSsl ? "wss" : "ws")+"://"+this.host+":"+this.port+"/"); - } - catch (URISyntaxException e) { - e.printStackTrace(); - } - socket = new WebSocketClient(uri) { - @Override - public void onOpen() { - if (Kuzzle.this.state == States.OFFLINE) { // Reconnect - Kuzzle.this.state = States.CONNECTED; - - if (Kuzzle.this.jwtToken != null) { - Kuzzle.this.checkToken(jwtToken, new ResponseListener() { - @Override - public void onSuccess(TokenValidity response) { - if (!response.isValid()) { - Kuzzle.this.jwtToken = null; - Kuzzle.this.emitEvent(Event.tokenExpired); - } - - Kuzzle.this.reconnect(); - } - - @Override - public void onError(JSONObject error) { - Kuzzle.this.jwtToken = null; - Kuzzle.this.emitEvent(Event.tokenExpired); - Kuzzle.this.reconnect(); - } - }); - } else { - Kuzzle.this.reconnect(); - } - } else { - Kuzzle.this.state = States.CONNECTED; - - Kuzzle.this.renewSubscriptions(); - Kuzzle.this.dequeue(); - Kuzzle.this.emitEvent(Event.connected); - - if (Kuzzle.this.connectionCallback != null) { - Kuzzle.this.connectionCallback.onSuccess(null); - } - } - } - - @Override - public void onTextReceived(String message) { - try { - JSONObject json = new JSONObject(message); - OnQueryDoneListener listener = null; - if (json.has("requestId")) { - listener = currentQueries.get(json.getString("requestId")); - } else { - listener = currentQueries.get(json.getString("room")); - } - - if (listener != null) { - // checking token expiration - if (!json.isNull("error") && json.getJSONObject("error").getString("message").equals("Token expired") && !json.getString("action").equals("logout")) { - emitEvent(Event.tokenExpired, listener); - } - - if (!json.isNull("error")) { - listener.onError(json.getJSONObject("error")); - } else { - listener.onSuccess(json); - } - currentQueries.remove(json.getString("requestId")); - } - - EventListener l = roomList.get(json.getString("room")); - if (l != null) { - l.trigger(new JSONObject(message)); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onBinaryReceived(byte[] data) { - - } - - @Override - public void onPingReceived(byte[] data) { - - } - - @Override - public void onPongReceived(byte[] data) { - - } - - @Override - public void onException(Exception e) { - Kuzzle.this.state = States.ERROR; - Kuzzle.this.emitEvent(Event.error, e.getMessage()); - - if (connectionCallback != null) { - JSONObject error = new JSONObject(); - try { - error.put("message", e.getMessage()); - } catch (JSONException ee) { - throw new RuntimeException(ee); - } - connectionCallback.onError(error); - } - } - - @Override - public void onCloseReceived() { - Kuzzle.this.state = States.OFFLINE; - if (!Kuzzle.this.autoReconnect) { - Kuzzle.this.disconnect(); - } - if (Kuzzle.this.autoQueue) { - Kuzzle.this.queuing = true; - } - currentQueries.clear(); - - Kuzzle.this.emitEvent(Event.disconnected); - } - }; - - if (this.autoReconnect) { - socket.enableAutomaticReconnection(this.reconnectionDelay); - } - - return socket; - } - - /** - * Emit request. - * - * @param request - Request to emit - * @param listener - Response callback listener - * @throws JSONException - */ - protected void emitRequest(final JSONObject request, final OnQueryDoneListener listener) throws JSONException { - Date now = new Date(); - Calendar c = Calendar.getInstance(); - c.setTime(now); - c.add(Calendar.SECOND, -MAX_EMIT_TIMEOUT); - - if (listener != null) { - currentQueries.put(request.get("requestId").toString(), listener); - } - - socket.send(request.toString()); - - // Track requests made to allow Room.subscribeToSelf to work - this.requestHistory.put(request.getString("requestId"), new Date()); - - // Clean history from requests made more than 10s ago - Iterator ite = requestHistory.keySet().iterator(); - - while (ite.hasNext()) { - if (this.requestHistory.get(ite.next()).before(c.getTime())) { - ite.remove(); - } - } - } - - /** - * Helper function ensuring that this Kuzzle object is still valid before performing a query - */ - protected void isValid() { - if (this.state == States.DISCONNECTED) { - throw new IllegalStateException("This Kuzzle object has been invalidated. Did you try to access it after a disconnect call?"); - } - } - - /** - * Helper function copying headers to the query data - * - * @param query - Query to update - * @param headers - Headers to set - */ - public void addHeaders(JSONObject query, final JSONObject headers) { - try { - for (Iterator iterator = headers.keys(); iterator.hasNext(); ) { - String key = (String) iterator.next(); - if (query.isNull(key)) { - query.put(key, headers.get(key)); - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * autoReconnect option getter - * - * @return autoReconnect option value - */ - public boolean isAutoReconnect() { - return autoReconnect; - } - - /** - * autoResubscribe option getter - * - * @return autoResubscribe option value - */ - public boolean isAutoResubscribe() { - return this.autoResubscribe; - } - - /** - * autoResubscribe option setter - * - * @param resubscribe - autoResubscribe new value - * @return this - */ - public Kuzzle setAutoResubscribe(boolean resubscribe) { - this.autoResubscribe = resubscribe; - return this; - } - - /** - * Global headers getter - * - * @return global headers - */ - public JSONObject getHeaders() { - return this.headers; - } - - /** - * Returns the current SDK version. - * - * @return Current SDK version - */ - public String getSdkVersion() { - return "2.0.0"; - } - - /** - * Add pending subscription kuzzle. - * - * @param id - Room instance unique ID - * @param room - Associated Room instance - * @return this - */ - protected Kuzzle addPendingSubscription(final String id, final Room room) { - this.subscriptions.get("pending").put(id, room); - return this; - } - - /** - * Delete a pending subscription - * - * @param id - Unique ID of the Room instance to delete - * @return this - */ - protected Kuzzle deletePendingSubscription(final String id) { - ConcurrentHashMap pending = this.subscriptions.get("pending"); - - if (pending != null) { - pending.remove(id); - } - - return this; - } - - /** - * Add a new subscription - * - * @param roomId - Subscription identifier - * @param id - Room instance unique ID - * @param kuzzleRoom - Associated Room instance - * @return this - */ - protected Kuzzle addSubscription(final String roomId, final String id, final Room kuzzleRoom) { - ConcurrentHashMap room = this.subscriptions.get(roomId); - - if (room == null) { - room = new ConcurrentHashMap<>(); - this.subscriptions.put(id, room); - } - - room.put(id, kuzzleRoom); - - return this; - } - - protected Kuzzle addRoom(final String channel, EventListener listener) { - if (channel != null) { - roomList.put(channel, listener); - } - - return this; - } - - protected Kuzzle removeRoom(final String channel) { - if (channel != null) { - roomList.remove(channel); - } - - return this; - } - - /** - * Connection socket getter - * - * @return Connection socket - */ - protected WebSocketClient getSocket() { - return socket; - } - - /** - * Connection socket setter - * - * @param socket - New connection socket - */ - protected void setSocket(WebSocketClient socket) { - this.socket = socket; - } - - /** - * Add a query to the offline queue - * - * @param query - Query to queue - * @return this - */ - public Kuzzle setOfflineQueue(final QueryObject query) { - this.offlineQueue.addToQueue(query); - return this; - } - - /** - * Offline queue getter - * - * @return offline queue - */ - public Queue getOfflineQueue() { - return this.offlineQueue.getQueue(); - } - - - /** - * Sets offline queue filter. - * - * @param queueFilter - Offline queue global filter - * @return this - */ - public Kuzzle setQueueFilter(QueueFilter queueFilter) { - this.queueFilter = queueFilter; - return this; - } - - /** - * Offline queue filter getter - * - * @return Offline queue filter - */ - public QueueFilter getQueueFilter() { - return this.queueFilter; - } - - /** - * autoReplay option getter - * - * @return autoReplay option value - */ - public boolean isAutoReplay() { - return autoReplay; - } - - - /** - * Kuzzle server port getter - * - * @return Kuzzle server port - */ - public int getPort() { - return port; - } - - /** - * Kuzzle server port setter - * - * @param port - New Kuzzle server port - * @return this - */ - public Kuzzle setPort(int port) { - this.port = port; - return this; - } - - /** - * Kuzzle server host name getter - * - * @return Kuzzle server host name - */ - public String getHost() { - return this.host; - } - - /** - * Kuzzle server host name setter - * - * @param host - New host name - * @return this - */ - public Kuzzle setHost(String host) { - this.host = host; - return this; - } - - /** - * autoReplay option setter - * - * @param autoReplay - New autoReplay option value - * @return this - */ - public Kuzzle setAutoReplay(boolean autoReplay) { - this.autoReplay = autoReplay; - return this; - } - - /** - * queueMaxSize option setter - * - * @param newMaxSize - New queueMaxSize value - * @return this - */ - public Kuzzle setQueueMaxSize(int newMaxSize) { - this.queueMaxSize = Math.max(0, newMaxSize); - return this; - } - - /** - * queueMaxSize option getter - * - * @return queueMaxSize option value - */ - public int getQueueMaxSize() { - return this.queueMaxSize; - } - - /** - * autoQueue option getter - * - * @return autoQueue option value - */ - public boolean isAutoQueue() { - return autoQueue; - } - - /** - * autoQueue option setter - * - * @param autoQueue - New autoQueue option value - * @return this - */ - public Kuzzle setAutoQueue(final boolean autoQueue) { - this.autoQueue = autoQueue; - return this; - } - - /** - * Clean up the queue, ensuring the queryTTL and queryMaxSize properties are respected - */ - private void cleanQueue() { - Date now = new Date(); - Calendar cal = Calendar.getInstance(); - cal.setTime(now); - cal.add(Calendar.MILLISECOND, -queueTTL); - - if (this.queueTTL > 0) { - QueryObject o; - while ((o = (QueryObject) offlineQueue.getQueue().peek()) != null) { - if (o.getTimestamp().before(cal.getTime())) { - offlineQueue.getQueue().poll(); - } else { - break; - } - } - } - - int size = this.offlineQueue.getQueue().size(); - if (this.queueMaxSize > 0 && size > this.queueMaxSize) { - int i = 0; - while (offlineQueue.getQueue().peek() != null && (size - this.queueMaxSize) >= i) { - this.offlineQueue.getQueue().poll(); - i++; - } - } - } - - private void mergeOfflineQueueWithLoader() { - KuzzleQueue additionalOfflineQueue = this.offlineQueueLoader.load(); - try { - for (QueryObject additionalQuery : additionalOfflineQueue) { - for (QueryObject offlineQuery : this.offlineQueue) { - if (additionalQuery.getQuery() != null && additionalQuery.getQuery().has("requestId") && additionalQuery.getQuery().has("action") && additionalQuery.getQuery().has("controller")) { - if (!offlineQuery.getQuery().getString("requestId").equals(additionalQuery.getQuery().getString("requestId"))) { - this.offlineQueue.addToQueue(additionalOfflineQueue.dequeue()); - } else { - additionalOfflineQueue.dequeue(); - } - } else { - throw new IllegalArgumentException("Invalid offline queue request. One or more missing properties: requestId, action, controller."); - } - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Play all queued requests, in order. - */ - private void dequeue() { - if (offlineQueueLoader != null) { - this.mergeOfflineQueueWithLoader(); - } - if (this.offlineQueue.getQueue().size() > 0) { - try { - QueryObject query = (QueryObject) this.offlineQueue.getQueue().poll(); - this.emitRequest(query.getQuery(), query.getCb()); - this.emitEvent(Event.offlineQueuePop, query); - } catch (JSONException e) { - throw new RuntimeException(e); - } - Timer timer = new Timer(UUID.randomUUID().toString()); - timer.schedule(new TimerTask() { - @Override - public void run() { - dequeue(); - } - }, Math.max(0, this.replayInterval)); - } else { - this.queuing = false; - } - } - - /** - * Delete a suscription - * - * @param roomId - Subscription unique ID - * @param id - Room instance unique ID - * @return this - */ - protected Kuzzle deleteSubscription(final String roomId, final String id) { - if (this.subscriptions.containsKey(roomId)) { - this.subscriptions.get(roomId).remove(id); - - if (this.subscriptions.get(roomId).isEmpty()) { - this.subscriptions.remove(roomId); - } - } - - return this; - } - - /** - * Gets subscriptions. - * - * @param roomId - Subscription unique ID - * @return matching registered subscriptions - */ - protected Map getSubscriptions(String roomId) { - if (roomId != null && this.subscriptions.containsKey(roomId)) { - return this.subscriptions.get(roomId); - } - - return null; - } - - /** - * Getter for the pendingSubscriptions private property - * - * @return pendingSubscriptions property value - */ - protected Map getPendingSubscriptions() { - return this.subscriptions.get("pending"); - } - - /** - * requestHistory getter - * - * @return Request history - */ - protected Map getRequestHistory() { - return requestHistory; - } - - /** - * Default index getter - * - * @return Default index value - */ - public String getDefaultIndex() { - return this.defaultIndex; - } - - /** - * Default index setter - * - * @param index - New default index name - * @return this - */ - public Kuzzle setDefaultIndex(final String index) { - if (index == null || index.isEmpty()) { - throw new IllegalArgumentException("Kuzzle.setDefaultIndex: index required"); - } - this.defaultIndex = index; - return this; - } - - /** - * Set a new JWT and trigger the 'loginAttempt' event. - * - * @param jwt - New authentication JSON Web Token - * @return this - */ - public Kuzzle setJwtToken(final String jwt) { - this.jwtToken = jwt; - try { - this.renewSubscriptions(); - this.emitEvent(Event.loginAttempt, new JSONObject().put("success", true)); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * Unset the authentication token and cancel all subscriptions - * - * @return this - */ - public Kuzzle unsetJwtToken() { - this.jwtToken = null; - - for (Map roomSubscriptions : subscriptions.values()) { - for (Room room : roomSubscriptions.values()) { - room.unsubscribe(); - } - } - return this; - } - - /** - * Sets the authentication token from a Kuzzle response object - * - * @param response - A Kuzzle API response - * @return this - * @throws JSONException - */ - public Kuzzle setJwtToken(final JSONObject response) throws JSONException { - JSONObject result; - - if (response == null) { - throw new IllegalArgumentException("Cannot set token from a null Kuzzle response"); - } - - if (response.has("result") && (result = response.getJSONObject("result")).has("jwt")) { - this.jwtToken = result.getString("jwt"); - this.renewSubscriptions(); - this.emitEvent(Event.loginAttempt, new JSONObject().put("success", true)); - } else { - this.emitEvent(Event.loginAttempt, new JSONObject() - .put("success", false) - .put("error", "Cannot find a valid JWT token in the following object: " + response.toString()) - ); - } - - return this; - } - - /** - * Authentication token getter - * - * @return Current JWT - */ - public String getJwtToken() { - return this.jwtToken; - } - - /** - * queueTTL option getter - * - * @param newTTL - New queueTTL value - * @return this - */ - public Kuzzle setQueueTTL(int newTTL) { - this.queueTTL = Math.max(0, newTTL); - return this; - } - - /** - * queueTTL option getter - * - * @return queue ttl value - */ - public int getQueueTTL() { - return this.queueTTL; - } - - /** - * Global volatile data setter - * - * @param _volatile - New global volatile data content - * @return this - */ - public Kuzzle setVolatile(JSONObject _volatile) { - this._volatile = _volatile; - return this; - } - - /** - * Global volatile data getter - * - * @return Global volatile data - */ - public JSONObject getVolatile() { - return this._volatile; - } - - - /** - * replayInterval option setter - * - * @param interval - New replayInterval value - * @return this - */ - public Kuzzle setReplayInterval(long interval) { - this.replayInterval = Math.max(0, interval); - return this; - } - - /** - * replayInterval option getter - * - * @return replayInterval value - */ - public long getReplayInterval() { - return this.replayInterval; - } - - /** - * reconnectionDelay option getter - * - * @return reconnectionDelay value - */ - public long getReconnectionDelay() { - return this.reconnectionDelay; - } - - /** - * Offline queue loader setter - * - * @param offlineQueueLoader - Offline queue loader function - */ - public void setOfflineQueueLoader(OfflineQueueLoader offlineQueueLoader) { - this.offlineQueueLoader = offlineQueueLoader; - } - - /** - * {@link #updateSelf(JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateSelf(final JSONObject content) { - return updateSelf(content, null, null); - } - - /** - * {@link #updateSelf(JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateSelf(final JSONObject content, final Options options) { - return updateSelf(content, options, null); - } - - /** - * {@link #updateSelf(JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateSelf(final JSONObject content, final ResponseListener listener) { - return updateSelf(content, null, listener); - } - - /** - * Update the currently authenticated user informations - * - * @param content - Current user infos to update - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle updateSelf(final JSONObject content, final Options options, final ResponseListener listener) { - QueryArgs args = new QueryArgs(); - args.controller = "auth"; - args.action = "updateSelf"; - - try { - JSONObject query = new JSONObject().put("body", content); - this.query(args, query, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener != null) { - listener.onSuccess(response); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Retrieves current user information - * - * @param listener - Response callback listener - */ - public void whoAmI(final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.whoAmI: listener required"); - } - - try { - QueryArgs args = new QueryArgs(); - args.controller = "auth"; - args.action = "getCurrentUser"; - JSONObject request = new JSONObject(); - - this.query(args, request, null, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new User(Kuzzle.this, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #refreshIndex(Options, ResponseListener)} - */ - public Kuzzle refreshIndex() { - return this.refreshIndex(null, null, null); - } - - /** - * {@link #refreshIndex(String, Options, ResponseListener)} - */ - public Kuzzle refreshIndex(String index) { - return this.refreshIndex(index, null, null); - } - - /** - * {@link #refreshIndex(String, Options, ResponseListener)} - */ - public Kuzzle refreshIndex(String index, final ResponseListener listener) { - return this.refreshIndex(index, null, listener); - } - - /** - * {@link #refreshIndex(String, Options, ResponseListener)} - */ - public Kuzzle refreshIndex(String index, final Options options) { - return this.refreshIndex(index, options, null); - } - - /** - * {@link #refreshIndex(Options, ResponseListener)} - */ - public Kuzzle refreshIndex(final Options options) { - return this.refreshIndex(null, options, null); - } - - /** - * Forces the default data index to refresh on each modification - * - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle refreshIndex(final Options options, final ResponseListener listener) { - return this.refreshIndex(null, options, listener); - } - - /** - * {@link #refreshIndex(Options, ResponseListener)} - */ - public Kuzzle refreshIndex(final ResponseListener listener) { - return this.refreshIndex(null, null, listener); - } - - /** - * Forces the provided data index to refresh on each modification - * - * @param index - Data index name - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle refreshIndex(String index, final Options options, final ResponseListener listener) { - if (index == null) { - if (this.defaultIndex == null) { - throw new IllegalArgumentException("Kuzzle.refreshIndex: index required"); - } else { - index = this.defaultIndex; - } - } - - QueryArgs args = new QueryArgs(); - args.index = index; - args.controller = "index"; - args.action = "refresh"; - JSONObject request = new JSONObject(); - - try { - this.query(args, request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener == null) { - return; - } - - try { - JSONObject result = response.getJSONObject("result"); - - listener.onSuccess(result); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener == null) { - return; - } - - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #getAutoRefresh(Options, ResponseListener)} - */ - public void getAutoRefresh(final ResponseListener listener) { - this.getAutoRefresh(null, null, listener); - } - - /** - * {@link #getAutoRefresh(String, Options, ResponseListener)} - */ - public void getAutoRefresh(String index, final ResponseListener listener) { - this.getAutoRefresh(index, null, listener); - } - - /** - * Gets the autoRefresh value for the default data index - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void getAutoRefresh(Options options, final ResponseListener listener) { - this.getAutoRefresh(null, options, listener); - } - - /** - * Gets the autoRefresh value for the provided data index name - * - * @param index - Data index name - * @param options - Request options - * @param listener - Response callback listener - */ - public void getAutoRefresh(String index, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getAutoRefresh: listener required"); - } - - if (index == null) { - if (this.defaultIndex == null) { - throw new IllegalArgumentException("Kuzzle.getAutoRefresh: index required"); - } else { - index = this.defaultIndex; - } - } - - QueryArgs args = new QueryArgs(); - args.index = index; - args.controller = "index"; - args.action = "getAutoRefresh"; - JSONObject request = new JSONObject(); - - try { - this.query(args, request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - boolean result = response.getBoolean("result"); - listener.onSuccess(result); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #setAutoRefresh(boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(final boolean autoRefresh) { - return this.setAutoRefresh(null, autoRefresh, null, null); - } - - /** - * {@link #setAutoRefresh(boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(final boolean autoRefresh, final ResponseListener listener) { - return this.setAutoRefresh(null, autoRefresh, null, listener); - } - - /** - * {@link #setAutoRefresh(String, boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(String index, final boolean autoRefresh) { - return this.setAutoRefresh(index, autoRefresh, null, null); - } - - /** - * {@link #setAutoRefresh(boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(final boolean autoRefresh, final Options options) { - return this.setAutoRefresh(null, autoRefresh, options, null); - } - - /** - * {@link #setAutoRefresh(String, boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(String index, final boolean autoRefresh, final Options options) { - return this.setAutoRefresh(index, autoRefresh, options, null); - } - - /** - * {@link #setAutoRefresh(String, boolean, Options, ResponseListener)} - */ - public Kuzzle setAutoRefresh(String index, final boolean autoRefresh, final ResponseListener listener) { - return this.setAutoRefresh(index, autoRefresh, null, listener); - } - - /** - * autoRefresh status setter for the default data index - * - * @param autoRefresh - New autoRefresh property value - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle setAutoRefresh(final boolean autoRefresh, final Options options, final ResponseListener listener) { - return this.setAutoRefresh(null, autoRefresh, options, listener); - } - - /** - * autorefresh status setter for the provided data index name - * - * @param index - Data index name - * @param autoRefresh - New autoRefresh property value - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle setAutoRefresh(String index, final boolean autoRefresh, final Options options, final ResponseListener listener) { - if (index == null) { - if (this.defaultIndex == null) { - throw new IllegalArgumentException("Kuzzle.setAutoRefresh: index required"); - } else { - index = this.defaultIndex; - } - } - - QueryArgs args = new QueryArgs(); - args.index = index; - args.controller = "index"; - args.action = "setAutoRefresh"; - JSONObject request; - - try { - request = new JSONObject().put("body", new JSONObject().put("autoRefresh", autoRefresh)); - this.query(args, request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - if (listener == null) { - return; - } - - try { - boolean result = response.getBoolean("result"); - listener.onSuccess(result); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #getMyRights(Options, ResponseListener)} - */ - public Kuzzle getMyRights(final ResponseListener listener) { - return getMyRights(null, listener); - } - - /** - * Gets the rights array for the currently logged user. - * - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle getMyRights(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.getMyRights: listener is mandatory."); - } - try { - Kuzzle.this.query(buildQueryArgs("auth", "getMyRights"), new JSONObject(), options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray hits = response.getJSONObject("result").getJSONArray("hits"); - JSONObject[] rights = new JSONObject[hits.length()]; - - for (int i = 0; i < hits.length(); i++) { - rights[i] = hits.getJSONObject(i); - } - - listener.onSuccess(rights); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - protected io.kuzzle.sdk.core.Kuzzle.QueryArgs buildQueryArgs(final String controller, String action) { - io.kuzzle.sdk.core.Kuzzle.QueryArgs args = new io.kuzzle.sdk.core.Kuzzle.QueryArgs(); - args.action = action; - args.controller = "security"; - if (controller != null) { - args.controller = controller; - } - args.action = action; - return args; - } - - /** - * Helper function meant to easily build the first Kuzzle.query() argument - * - * @param action - API controller action name - * @return JSONObject - Kuzzle.query() 1st argument object - * @throws JSONException - */ - protected io.kuzzle.sdk.core.Kuzzle.QueryArgs buildQueryArgs(final String action) throws JSONException { - return buildQueryArgs(null, action); - } - - /** - * Invokes a query listener with a custom error message and status - * - * @param listener - Response callback listener - * @param query - discarded query - * @throws JSONException - */ - protected void discardRequest(final OnQueryDoneListener listener, JSONObject query) throws JSONException { - if (listener != null) { - JSONObject err = new JSONObject() - .put("status", 400) - .put("message", "Unable to execute request: not connected to a Kuzzle server.\nDiscarded request: " + query.toString()); - - listener.onError(err); - } - } - - /** - * {@link #createMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle createMyCredentials(final String strategy, final JSONObject credentials) { - return createMyCredentials(strategy, credentials, null, null); - } - - /** - * {@link #createMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle createMyCredentials(final String strategy, final JSONObject credentials, final Options options) { - return createMyCredentials(strategy, credentials, options, null); - } - - /** - * {@link #createMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle createMyCredentials(final String strategy, final JSONObject credentials, final ResponseListener listener) { - return createMyCredentials(strategy, credentials, null, listener); - } - - /** - * Create credentials of the specified strategy for the current user. - * - * @param strategy - impacted strategy name - * @param credentials - credentials to create - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle createMyCredentials(final String strategy, final JSONObject credentials, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("body", credentials); - Kuzzle.this.query(buildQueryArgs("auth", "createMyCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #deleteMyCredentials(String, Options, ResponseListener)} - */ - public Kuzzle deleteMyCredentials(final String strategy) { - return deleteMyCredentials(strategy, null, null); - } - - /** - * {@link #deleteMyCredentials(String, Options, ResponseListener)} - */ - public Kuzzle deleteMyCredentials(final String strategy, final Options options) { - return deleteMyCredentials(strategy, options, null); - } - - /** - * {@link #deleteMyCredentials(String, Options, ResponseListener)} - */ - public Kuzzle deleteMyCredentials(final String strategy, final ResponseListener listener) { - return deleteMyCredentials(strategy, null, listener); - } - - /** - * Delete credentials of the specified strategy for the current user. - * - * @param strategy- Name of the strategy to remove - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle deleteMyCredentials(final String strategy, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy); - Kuzzle.this.query(buildQueryArgs("auth", "deleteMyCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #getMyCredentials(String, Options, ResponseListener)} - */ - public void getMyCredentials(final String strategy, final ResponseListener listener) { - getMyCredentials(strategy, null, listener); - } - - /** - * Get credential information of the specified strategy for the current user. - * - * @param strategy - Strategy name to get - * @param options - Request options - * @param listener - Response callback listener - */ - public void getMyCredentials(final String strategy, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.getMyCredentials: listener is mandatory"); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy); - Kuzzle.this.query(buildQueryArgs("auth", "getMyCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #updateMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateMyCredentials(final String strategy, final JSONObject credentials) { - return updateMyCredentials(strategy, credentials, null, null); - } - - /** - * {@link #updateMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateMyCredentials(final String strategy, final JSONObject credentials, final Options options) { - return updateMyCredentials(strategy, credentials, options, null); - } - - /** - * {@link #updateMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public Kuzzle updateMyCredentials(final String strategy, final JSONObject credentials, final ResponseListener listener) { - return updateMyCredentials(strategy, credentials, null, listener); - } - - /** - * Update credentials of the specified strategy for the current user. - * - * @param strategy - Strategy name to update - * @param credentials - Updated credentials content - * @param options - Request options - * @param listener - Response callback listener - * @return this - */ - public Kuzzle updateMyCredentials(final String strategy, final JSONObject credentials, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("body", credentials); - Kuzzle.this.query(buildQueryArgs("auth", "updateMyCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #validateMyCredentials(String, JSONObject, Options, ResponseListener)} - */ - public void validateMyCredentials(final String strategy, final JSONObject credentials, final ResponseListener listener) { - validateMyCredentials(strategy, credentials, null, listener); - } - - /** - * Validate credentials of the specified strategy for the current user. - * - * @param strategy - Strategy name to validate - * @param credentials - Credentials content - * @param options - Request options - * @param listener - Response callback listener - */ - public void validateMyCredentials(final String strategy, final JSONObject credentials, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Kuzzle.validateMyCredentials: listener is mandatory"); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("body", credentials); - Kuzzle.this.query(buildQueryArgs("auth", "validateMyCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getBoolean("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/MemoryStorage.java b/src/main/java/io/kuzzle/sdk/core/MemoryStorage.java deleted file mode 100644 index ca53d6f6..00000000 --- a/src/main/java/io/kuzzle/sdk/core/MemoryStorage.java +++ /dev/null @@ -1,4355 +0,0 @@ -package io.kuzzle.sdk.core; - - - -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONArray; - -import java.util.ArrayList; -import java.util.Arrays; - -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.util.KuzzleJSONObject; - -/** - * Kuzzle's memory storage is a separate data store from the database layer. - * It is internaly based on Redis. You can access most of Redis functions (all - * lowercased), excepting: - * * all cluster based functions - * * all script based functions - * * all cursors functions - * - */ -public class MemoryStorage { - private Kuzzle kuzzle; - private Kuzzle.QueryArgs queryArgs = new Kuzzle.QueryArgs(); - - public MemoryStorage(final Kuzzle kuzzle) { - this.kuzzle = kuzzle; - queryArgs.controller = "ms"; - } - - protected void assignGeoradiusOptions(JSONObject query, Options options) { - if (options != null) { - JSONArray opts = new JSONArray(); - - if (options.getWithcoord()) { - opts.put("withcoord"); - } - - if (options.getWithdist()) { - opts.put("withdist"); - } - - if (options.getCount() != null) { - opts.put("count").put(options.getCount()); - } - - if (options.getSort() != null) { - opts.put(options.getSort()); - } - - if (opts.length() > 0) { - try { - query.put("options", opts); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - } - - protected JSONObject[] mapGeoradiusResults(JSONArray points) throws JSONException { - JSONObject[] mapped = new JSONObject[points.length()]; - - // Simple array of point names (no options provided) - if (points.get(0) instanceof String) { - for (int i = 0; i < points.length(); i++) { - mapped[i] = new JSONObject().put("name", points.getString(i)); - } - - return mapped; - } - - for (int i = 0; i < points.length(); i++) { - JSONArray rawPoint = points.getJSONArray(i); - JSONObject p = new JSONObject().put("name", rawPoint.getString(0)); - - for (int j = 1; j < rawPoint.length(); j++) { - // withcoord results are stored in an array... - if (rawPoint.get(j) instanceof JSONArray) { - JSONArray coords = rawPoint.getJSONArray(j); - - p - .put("coordinates", new JSONArray() - .put(Double.parseDouble(coords.getString(0))) - .put(Double.parseDouble(coords.getString(1))) - ); - } - else { - // ... while withdist results are not - p.put("distance", Double.parseDouble(rawPoint.getString(j))); - } - } - - mapped[i] = p; - } - - return mapped; - } - - protected JSONObject[] mapZrangeResults(JSONArray members) { - ArrayList mapped = new ArrayList<>(members.length() /2); - - try { - for (int i = 0; i < members.length(); i += 2) { - mapped.add(new JSONObject() - .put("member", members.getString(i)) - .put("score", Double.parseDouble(members.getString(i+1))) - ); - } - } - catch(JSONException e) { - throw new RuntimeException(e); - } - - return mapped.toArray(new JSONObject[0]); - } - - protected void send(String action, final KuzzleJSONObject query, Options options, final ResponseListener listener) { - queryArgs.action = action; - - try { - if (listener != null) { - kuzzle.query(queryArgs, query, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(response); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - kuzzle.query(queryArgs, query, options); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - protected ResponseListener getCallbackLong(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getLong("result")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - protected ResponseListener getCallbackInt(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getInt("result")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - protected ResponseListener getCallbackString(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getString("result")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - protected ResponseListener getCallbackDouble(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(Double.parseDouble(response.getString("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - protected ResponseListener getCallbackStringArray(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray arr = response.getJSONArray("result"); - String[] result = new String[arr.length()]; - - for (int i = 0; i < arr.length(); i++) { - result[i] = arr.getString(i); - } - - listener.onSuccess(result); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - protected ResponseListener getCallbackScanResult(final ResponseListener listener) { - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray arr = response.getJSONArray("result"); - JSONObject result = new JSONObject(); - - try { - result - .put("cursor", Integer.parseInt(arr.getString(0))) - .put("values", arr.getJSONArray(1)); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - - listener.onSuccess(result); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - /** - * {@link #append(String, String, Options, ResponseListener)} - */ - public MemoryStorage append(String key, final String value) { - return append(key, value, null, null); - } - - /** - * {@link #append(String, String, Options, ResponseListener)} - */ - public MemoryStorage append(String key, final String value, Options options) { - return append(key, value, options, null); - } - - /** - * {@link #append(String, String, Options, ResponseListener)} - */ - public MemoryStorage append(String key, final String value, final ResponseListener listener) { - return append(key, value, null, listener); - } - - /** - * Append a value to a key - * - * @param key Key ID - * @param value Value to append - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage append(String key, final String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("append", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #bitcount(String, Options, ResponseListener)} - */ - public void bitcount(String key, final ResponseListener listener) { - bitcount(key, null, listener); - } - - /** - * Counts the number of set bits (population counting) - * - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void bitcount(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - if (options != null) { - if (options.getStart() != null) { - query.put("start", options.getStart()); - } - - if (options.getEnd() != null) { - query.put("end", options.getEnd()); - } - } - - send("bitcount", query, options, getCallbackLong(listener)); - } - - /** - * {@link #bitop(String, String, String[], Options, ResponseListener)} - */ - public MemoryStorage bitop(String key, String operation, final String[] keys) throws JSONException { - return bitop(key, operation, keys, null, null); - } - - /** - * {@link #bitop(String, String, String[], Options, ResponseListener)} - */ - public MemoryStorage bitop(String key, String operation, final String[] keys, Options options) throws JSONException { - return bitop(key, operation, keys, options, null); - } - - /** - * {@link #bitop(String, String, String[], Options, ResponseListener)} - */ - public MemoryStorage bitop(String key, String operation, final String[] keys, final ResponseListener listener) throws JSONException { - return bitop(key, operation, keys, null, listener); - } - - /** - * Performs a bitwise operation between multiple keys (containing string values) and stores the result in the destination key. - * @param key Destination Key ID - * @param operation Bit operation name - * @param keys Keys on which to perform the bitwise operation - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public MemoryStorage bitop(String key, String operation, final String[] keys, Options options, final ResponseListener listener) throws JSONException { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("operation", operation) - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - send("bitop", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #bitpos(String, int, Options, ResponseListener)} - */ - public void bitpos(String key, int bit, final ResponseListener listener) { - bitpos(key, bit, null, listener); - } - - /** - * Returns the position of the first bit set to 1 or 0 in a string, or in a substring - * @param key Key ID - * @param bit Bit to look for - * @param options Request options - * @param listener Response callback listener - */ - public void bitpos(String key, int bit, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("bit", bit); - - if (options != null) { - if (options.getStart() != null) { - query.put("start", options.getStart()); - } - - if (options.getEnd() != null) { - query.put("end", options.getEnd()); - } - } - - send("bitpos", query, options, getCallbackLong(listener)); - } - - /** - * {@link #dbsize(Options, ResponseListener)} - */ - public void dbsize(final ResponseListener listener) { - dbsize(null, listener); - } - - /** - * Returns the number of keys in the application database. - * @param options Request options - * @param listener Response callback listener - */ - public void dbsize(Options options, final ResponseListener listener) { - send("dbsize", new KuzzleJSONObject(), options, getCallbackLong(listener)); - } - - /** - * {@link #decr(String, Options, ResponseListener)} - */ - public MemoryStorage decr(String key) { - return decr(key, null, null); - } - - /** - * {@link #decr(String, Options, ResponseListener)} - */ - public MemoryStorage decr(String key, Options options) { - return decr(key, options, null); - } - - /** - * {@link #decr(String, Options, ResponseListener)} - */ - public MemoryStorage decr(String key, final ResponseListener listener) { - return decr(key, null, listener); - } - - /** - * Decrements the value of a key by 1 - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage decr(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("decr", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #decrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage decrby(String key, long value) { - return decrby(key, value, null, null); - } - - /** - * {@link #decrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage decrby(String key, long value, Options options) { - return decrby(key, value, options, null); - } - - /** - * {@link #decrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage decrby(String key, long value, final ResponseListener listener) { - return decrby(key, value, null, listener); - } - - /** - * Decrements the value of a key by a given value - * @param key Key ID - * @param value Decrement value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage decrby(String key, long value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("decrby", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #del(String[], Options, ResponseListener)} - */ - public MemoryStorage del(String[] keys) { - return del(keys, null, null); - } - - /** - * {@link #del(String[], Options, ResponseListener)} - */ - public MemoryStorage del(String[] keys, Options options) { - return del(keys, options, null); - } - - /** - * {@link #del(String[], Options, ResponseListener)} - */ - public MemoryStorage del(String[] keys, final ResponseListener listener) { - return del(keys, null, listener); - } - - /** - * Delete keys - * @param keys Key IDs to delete - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage del(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys)))); - - send("del", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #exists(String[], Options, ResponseListener)} - */ - public void exists(String[] keys, final ResponseListener listener) { - exists(keys, null, listener); - } - - /** - * Check if the specified keys exist - * - * @param keys Key IDs - * @param options Request options - * @param listener Response callback listener - */ - public void exists(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - send("exists", query, options, getCallbackLong(listener)); - } - - /** - * {@link #expire(String, long, Options, ResponseListener)} - */ - public MemoryStorage expire(String key, long seconds) { - return expire(key, seconds, null, null); - } - - /** - * {@link #expire(String, long, Options, ResponseListener)} - */ - public MemoryStorage expire(String key, long seconds, Options options) { - return expire(key, seconds, options, null); - } - - /** - * {@link #expire(String, long, Options, ResponseListener)} - */ - public MemoryStorage expire(String key, long seconds, final ResponseListener listener) { - return expire(key, seconds, null, listener); - } - - /** - * Set an expiration timeout on a key - * @param key Key ID - * @param seconds Timeout (in seconds) - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage expire(String key, long seconds, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("seconds", seconds) - ); - - send("expire", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #expireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage expireat(String key, long timestamp) { - return expireat(key, timestamp, null, null); - } - - /** - * {@link #expireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage expireat(String key, long timestamp, Options options) { - return expireat(key, timestamp, options, null); - } - - /** - * {@link #expireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage expireat(String key, long timestamp, final ResponseListener listener) { - return expireat(key, timestamp, null, listener); - } - - /** - * Set an expiration timestamp to a key - * @param key Key ID - * @param timestamp Expiration timestamp (Epoch Time) - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage expireat(String key, long timestamp, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("timestamp", timestamp) - ); - - send("expireat", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #flushdb(Options, ResponseListener)} - */ - public MemoryStorage flushdb() { - return flushdb(null, null); - } - - /** - * {@link #flushdb(Options, ResponseListener)} - */ - public MemoryStorage flushdb(final ResponseListener listener) { - return flushdb(null, listener); - } - - - /** - * {@link #flushdb(Options, ResponseListener)} - */ - public MemoryStorage flushdb(Options options) { - return flushdb(options, null); - } - - /** - * Delete all keys from the database - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage flushdb(Options options, final ResponseListener listener) { - send("flushdb", new KuzzleJSONObject(), options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #geoadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage geoadd(String key, JSONObject[] points) { - return geoadd(key, points, null, null); - } - - /** - * {@link #geoadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage geoadd(String key, JSONObject[] points, final ResponseListener listener) { - return geoadd(key, points, null, listener); - } - - /** - * {@link #geoadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage geoadd(String key, JSONObject[] points, Options options) { - return geoadd(key, points, options, null); - } - - /** - * Add geospatial points to a key - * @param key Key ID - * @param points Geospatial points to add - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage geoadd(String key, JSONObject[] points, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("points", new JSONArray(Arrays.asList(points))) - ); - - send("geoadd", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #geodist(String, String, String, Options, ResponseListener)} - */ - public void geodist(String key, String member1, String member2, final ResponseListener listener) { - geodist(key, member1, member2, null, listener); - } - - /** - * Get the distance between two geospatial members of a key (see geoadd) - * @param key Key ID - * @param member1 Geospatial point 1 - * @param member2 Geospatial point 2 - * @param options Request options - * @param listener Response callback listener - */ - public void geodist(String key, String member1, String member2, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("member1", member1) - .put("member2", member2); - - if (options != null) { - if (options.getUnit() != null) { - query.put("unit", options.getUnit()); - } - } - - send("geodist", query, options, getCallbackDouble(listener)); - } - - /** - * {@link #geohash(String, String[], Options, ResponseListener)} - */ - public void geohash(String key, String[] members, final ResponseListener listener) { - geohash(key, members, null, listener); - } - - /** - * Return the geohash values for the provided key's members - * @param key Key ID - * @param members List of geospatial members - * @param options Request options - * @param listener Response callback listener - */ - public void geohash(String key, String[] members, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("members", new JSONArray(Arrays.asList(members))); - - send("geohash", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #geopos(String, String[], Options, ResponseListener)} - */ - public void geopos(String key, String[] members, final ResponseListener listener) { - geopos(key, members, null, listener); - } - - /** - * Return the longitude/latitude values for the provided key's members - * @param key Key ID - * @param members List of geospatial members - * @param options Request options - * @param listener Response callback listener - */ - public void geopos(String key, String[] members, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("members", new JSONArray(Arrays.asList(members))); - - send( - "geopos", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - /* - Converts the resulting array of arrays of strings, - into an array of arrays of doubles - */ - JSONArray raw = response.getJSONArray("result"); - Double[][] result = new Double[raw.length()][2]; - - for (int i = 0; i < raw.length(); i++) { - JSONArray rawPos = raw.getJSONArray(i); - - for (int j = 0; j < rawPos.length(); j++) { - result[i][j] = Double.parseDouble(rawPos.getString(j)); - } - } - - listener.onSuccess(result); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #georadius(String, double, double, double, String, Options, ResponseListener)} - */ - public void georadius(String key, double lon, double lat, double distance, String unit, final ResponseListener listener) { - georadius(key, lon, lat, distance, unit, null, listener); - } - - /** - * Return the geospatial members of a key inside the provided radius - * @param key Key ID - * @param lon Longitude value for the radius center - * @param lat Latitude value for the radius center - * @param distance Radius value - * @param unit Radius distance unit - * @param options Request options - * @param listener Response callback listener - */ - public void georadius(String key, double lon, double lat, double distance, String unit, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("lon", lon) - .put("lat", lat) - .put("distance", distance) - .put("unit", unit); - - assignGeoradiusOptions(query, options); - - send( - "georadius", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapGeoradiusResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #georadiusbymember(String, String, double, String, Options, ResponseListener)} - */ - public void georadiusbymember(String key, String member, double distance, String unit, final ResponseListener listener) { - georadiusbymember(key, member, distance, unit, null, listener); - } - - /** - * Returns the members (added with geoadd) of a given key inside - * the provided geospatial radius, centered around one of a - * key's member. - * - * @param key Key ID - * @param member Geospatial member, center of the radius - * @param distance Radius value - * @param unit Radius distance unit - * @param options Request options - * @param listener Response callback listener - */ - public void georadiusbymember(String key, String member, double distance, String unit, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("member", member) - .put("distance", distance) - .put("unit", unit); - - assignGeoradiusOptions(query, options); - - send( - "georadiusbymember", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapGeoradiusResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #get(String, Options, ResponseListener)} - */ - public void get(String key, final ResponseListener listener) { - get(key, null, listener); - } - - - /** - * Get a key's value - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void get(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("get", query, options, getCallbackString(listener)); - } - - /** - * {@link #getbit(String, long, Options, ResponseListener)} - */ - public void getbit(String key, long offset, final ResponseListener listener) { - getbit(key, offset, null, listener); - } - - /** - * Returns the bit value at offset, in the string value stored in a key. - * @param key Key ID - * @param offset Offset value - * @param options Request options - * @param listener Response callback listener - */ - public void getbit(String key, long offset, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("offset", offset); - - send("getbit", query, options, getCallbackInt(listener)); - } - - /** - * {@link #getrange(String, long, long, Options, ResponseListener)} - */ - public void getrange(String key, long start, long end, final ResponseListener listener) { - getrange(key, start, end, null, listener); - } - - /** - * Returns a substring of a key's value (index starts at position 0). - * @param key Key ID - * @param start Substring starting position - * @param end Substring ending position - * @param options Request options - * @param listener Response callback listener - */ - public void getrange(String key, long start, long end, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("start", start) - .put("end", end); - - send("getrange", query, options, getCallbackString(listener)); - } - - /** - * {@link #getset(String, String, Options, ResponseListener)} - */ - public MemoryStorage getset(String key, String value) { - return getset(key, value, null, null); - } - - /** - * {@link #getset(String, String, Options, ResponseListener)} - */ - public MemoryStorage getset(String key, String value, final ResponseListener listener) { - return getset(key, value, null, listener); - } - - /** - * {@link #getset(String, String, Options, ResponseListener)} - */ - public MemoryStorage getset(String key, String value, Options options) { - return getset(key, value, options, null); - } - - /** - * Sets a new value for a key and returns its previous value. - * @param key Key ID - * @param value New value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage getset(String key, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("getset", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #hdel(String, String[], Options, ResponseListener)} - */ - public MemoryStorage hdel(String key, String[] fields) { - return hdel(key, fields, null, null); - } - - /** - * {@link #hdel(String, String[], Options, ResponseListener)} - */ - public MemoryStorage hdel(String key, String[] fields, final ResponseListener listener) { - return hdel(key, fields, null, listener); - } - - /** - * {@link #hdel(String, String[], Options, ResponseListener)} - */ - public MemoryStorage hdel(String key, String[] fields, Options options) { - return hdel(key, fields, options, null); - } - - /** - * Remove fields from a hash - * @param key Hash key ID - * @param fields Fields to remove - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hdel(String key, String[] fields, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("fields", new JSONArray(Arrays.asList(fields))) - ); - - send("hdel", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #hexists(String, String, Options, ResponseListener)} - */ - public void hexists(String key, String field, final ResponseListener listener) { - hexists(key, field, null, listener); - } - - /** - * Check if a field exists in a hash - * @param key Hash key ID - * @param field Field name - * @param options Request options - * @param listener Response callback listener - */ - public void hexists(String key, String field, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("field", field); - - send("hexists", query, options, getCallbackInt(listener)); - } - - /** - * {@link #hget(String, String, Options, ResponseListener)} - */ - public void hget(String key, String field, final ResponseListener listener) { - hget(key, field, null, listener); - } - - /** - * Return the field's value of a hash - * @param key Hash key ID - * @param field Field name - * @param options Request options - * @param listener Response callback listener - */ - public void hget(String key, String field, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("field", field); - - send("hget", query, options, getCallbackString(listener)); - } - - /** - * {@link #hgetall(String, Options, ResponseListener)} - */ - public void hgetall(String key, final ResponseListener listener) { - hgetall(key, null, listener); - } - - /** - * Return all fields and values of a hash - * @param key Hash key ID - * @param options Request options - * @param listener Response callback listener - */ - public void hgetall(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send( - "hgetall", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #hincrby(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage hincrby(String key, String field, long value) { - return hincrby(key, field, value, null, null); - } - - /** - * {@link #hincrby(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage hincrby(String key, String field, long value, final ResponseListener listener) { - return hincrby(key, field, value, null, listener); - } - - /** - * {@link #hincrby(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage hincrby(String key, String field, long value, Options options) { - return hincrby(key, field, value, options, null); - } - - /** - * Increments the number stored in a hash field by the provided integer value. - * @param key Hash Key ID - * @param field Field to increment - * @param value Increment value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hincrby(String key, String field, long value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("field", field) - .put("value", value) - ); - - send("hincrby", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #hincrbyfloat(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage hincrbyfloat(String key, String field, double value) { - return hincrbyfloat(key, field, value, null, null); - } - - /** - * {@link #hincrbyfloat(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage hincrbyfloat(String key, String field, double value, final ResponseListener listener) { - return hincrbyfloat(key, field, value, null, listener); - } - - /** - * {@link #hincrbyfloat(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage hincrbyfloat(String key, String field, double value, Options options) { - return hincrbyfloat(key, field, value, options, null); - } - - /** - * Increments the number stored in a hash field by the provided float value. - * @param key Hash key ID - * @param field Field to increment - * @param value Increment value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hincrbyfloat(String key, String field, double value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("field", field) - .put("value", value) - ); - - send("hincrbyfloat", query, options, listener != null ? getCallbackDouble(listener) : null); - - return this; - } - - /** - * {@link #hkeys(String, Options, ResponseListener)} - */ - public void hkeys(String key, final ResponseListener listener) { - hkeys(key, null, listener); - } - - /** - * Return all the field names contained in a hash - * @param key Hash key ID - * @param options Request options - * @param listener Response callback listener - */ - public void hkeys(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("hkeys", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #hlen(String, Options, ResponseListener)} - */ - public void hlen(String key, final ResponseListener listener) { - hlen(key, null, listener); - } - - /** - * Return the number of members of a hash - * @param key Hash key ID - * @param options Request options - * @param listener Response callback listener - */ - public void hlen(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("hlen", query, options, getCallbackLong(listener)); - } - - /** - * {@link #hmget(String, String[], Options, ResponseListener)} - */ - public void hmget(String key, String[] fields, final ResponseListener listener) { - hmget(key, fields, null, listener); - } - - /** - * Returns the values of the specified hash’s fields. - * @param key Hash key ID - * @param fields Field names to return - * @param options Request options - * @param listener Response callback listener - */ - public void hmget(String key, String[] fields, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("fields", new JSONArray(Arrays.asList(fields))); - - send("hmget", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #hmset(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage hmset(String key, JSONObject[] entries) { - return hmset(key, entries, null, null); - } - - /** - * {@link #hmset(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage hmset(String key, JSONObject[] entries, final ResponseListener listener) { - return hmset(key, entries, null, listener); - } - - /** - * {@link #hmset(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage hmset(String key, JSONObject[] entries, Options options) { - return hmset(key, entries, options, null); - } - - /** - * Sets multiple fields at once in a hash. - * @param key Hash key ID - * @param entries Name-Value pairs to set - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hmset(String key, JSONObject[] entries, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("entries", new JSONArray(Arrays.asList(entries))) - ); - - send("hmset", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #hscan(String, long, Options, ResponseListener)} - */ - public void hscan(String key, long cursor, final ResponseListener listener) { - hscan(key, cursor, null, listener); - } - - /** - * Identical to scan, except that hscan iterates the fields contained in a hash. - * @param key Hash key ID - * @param cursor Cursor position (0 to start a new scan) - * @param options Request options - * @param listener Response callback listener - */ - public void hscan(String key, long cursor, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("cursor", cursor); - - if (options != null) { - if (options.getCount() != null) { - query.put("count", options.getCount()); - } - - if (options.getMatch() != null) { - query.put("match", options.getMatch()); - } - } - - send("hscan", query, options, getCallbackScanResult(listener)); - } - - /** - * {@link #hset(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hset(String key, String field, String value) { - return hset(key, field, value, null, null); - } - - /** - * {@link #hset(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hset(String key, String field, String value, final ResponseListener listener) { - return hset(key, field, value, null, listener); - } - - /** - * {@link #hset(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hset(String key, String field, String value, Options options) { - return hset(key, field, value, options, null); - } - - /** - * Sets a field and its value in a hash. - * If the key does not exist, a new key holding a hash is created. - * @param key Hash key ID - * @param field Field name to set - * @param value Value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hset(String key, String field, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("field", field) - .put("value", value) - ); - - send("hset", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #hsetnx(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hsetnx(String key, String field, String value) { - return hsetnx(key, field, value, null, null); - } - - /** - * {@link #hsetnx(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hsetnx(String key, String field, String value, final ResponseListener listener) { - return hsetnx(key, field, value, null, listener); - } - - /** - * {@link #hsetnx(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage hsetnx(String key, String field, String value, Options options) { - return hsetnx(key, field, value, options, null); - } - - /** - * Sets a field and its value in a hash, only if the field does not already exist. - * @param key Hash key ID - * @param field Field name to set - * @param value Value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage hsetnx(String key, String field, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("field", field) - .put("value", value) - ); - - send("hsetnx", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #hstrlen(String, String, Options, ResponseListener)} - */ - public void hstrlen(String key, String field, final ResponseListener listener) { - hstrlen(key, field, null, listener); - } - - /** - * Returns the string length of a field’s value in a hash. - * @param key Hash key ID - * @param field Field name - * @param options Request options - * @param listener Response callback listener - */ - public void hstrlen(String key, String field, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("field", field); - - send("hstrlen", query, options, getCallbackLong(listener)); - } - - /** - * {@link #hvals(String, Options, ResponseListener)} - */ - public void hvals(String key, final ResponseListener listener) { - hvals(key, null, listener); - } - - /** - * Returns all values contained in a hash. - * @param key Hash key ID - * @param options Request options - * @param listener Response callback listener - */ - public void hvals(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("hvals", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #incr(String, Options, ResponseListener)} - */ - public MemoryStorage incr(String key) { - return incr(key, null, null); - } - - /** - * {@link #incr(String, Options, ResponseListener)} - */ - public MemoryStorage incr(String key, Options options) { - return incr(key, options, null); - } - - /** - * {@link #incr(String, Options, ResponseListener)} - */ - public MemoryStorage incr(String key, final ResponseListener listener) { - return incr(key, null, listener); - } - - /** - * Increments the number stored at key by 1. - * If the key does not exist, it is set to 0 before performing the operation. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage incr(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("incr", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #incrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage incrby(String key, long value) { - return incrby(key, value, null, null); - } - - /** - * {@link #incrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage incrby(String key, long value, Options options) { - return incrby(key, value, options, null); - } - - /** - * {@link #incrby(String, long, Options, ResponseListener)} - */ - public MemoryStorage incrby(String key, long value, final ResponseListener listener) { - return incrby(key, value, null, listener); - } - - /** - * Increments the number stored at key by the provided integer value. - * If the key does not exist, it is set to 0 before performing the operation. - * @param key Key ID - * @param value Increment value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage incrby(String key, long value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("incrby", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #incrbyfloat(String, double, Options, ResponseListener)} - */ - public MemoryStorage incrbyfloat(String key, double value) { - return incrbyfloat(key, value, null, null); - } - - /** - * {@link #incrbyfloat(String, double, Options, ResponseListener)} - */ - public MemoryStorage incrbyfloat(String key, double value, final ResponseListener listener) { - return incrbyfloat(key, value, null, listener); - } - - /** - * {@link #incrbyfloat(String, double, Options, ResponseListener)} - */ - public MemoryStorage incrbyfloat(String key, double value, Options options) { - return incrbyfloat(key, value, options, null); - } - - /** - * Increments the number stored at key by the provided float value. - * If the key does not exist, it is set to 0 before performing the operation. - * @param key Key ID - * @param value Increment value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage incrbyfloat(String key, double value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("incrbyfloat", query, options, listener != null ? getCallbackDouble(listener) : null); - - return this; - } - - /** - * {@link #keys(String, Options, ResponseListener)} - */ - public void keys(String pattern, final ResponseListener listener) { - keys(pattern, null, listener); - } - - /** - * Returns all keys matching the provided pattern. - * @param pattern Match pattern - * @param options Request options - * @param listener Response callback listener - */ - public void keys(String pattern, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("pattern", pattern); - - send("keys", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #lindex(String, long, Options, ResponseListener)} - */ - public void lindex(String key, long index, final ResponseListener listener) { - lindex(key, index, null, listener); - } - - /** - * Returns the element at the provided index in a list. - * @param key List ID - * @param index Index position - * @param options [description] - * @param listener Response callback listener - */ - public void lindex(String key, long index, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("index", index); - - send("lindex", query, options, getCallbackString(listener)); - } - - /** - * {@link #linsert(String, String, String, String, Options, ResponseListener)} - */ - public MemoryStorage linsert(String key, String position, String pivot, String value) { - return linsert(key, position, pivot, value, null, null); - } - - /** - * {@link #linsert(String, String, String, String, Options, ResponseListener)} - */ - public MemoryStorage linsert(String key, String position, String pivot, String value, final ResponseListener listener) { - return linsert(key, position, pivot, value, null, listener); - } - - /** - * {@link #linsert(String, String, String, String, Options, ResponseListener)} - */ - public MemoryStorage linsert(String key, String position, String pivot, String value, Options options) { - return linsert(key, position, pivot, value, options, null); - } - - - /** - * Inserts a value in a list, either before or after the reference pivot value. - * @param key List ID - * @param position Either "after" or "before" - * @param pivot Pivot value in the list - * @param value Value to insert - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage linsert(String key, String position, String pivot, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("position", position) - .put("pivot", pivot) - .put("value", value) - ); - - send("linsert", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #llen(String, Options, ResponseListener)} - */ - public void llen(String key, final ResponseListener listener) { - llen(key, null, listener); - } - - /** - * Counts the number of items in a list. - * @param key List ID - * @param options Request options - * @param listener Response callback listener - */ - public void llen(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("llen", query, options, getCallbackLong(listener)); - } - - /** - * {@link #lpop(String, Options, ResponseListener)} - */ - public MemoryStorage lpop(String key) { - return lpop(key, null, null); - } - - /** - * {@link #lpop(String, Options, ResponseListener)} - */ - public MemoryStorage lpop(String key, final ResponseListener listener) { - return lpop(key, null, listener); - } - - /** - * {@link #lpop(String, Options, ResponseListener)} - */ - public MemoryStorage lpop(String key, Options options) { - return lpop(key, options, null); - } - - /** - * Removes and returns the first element of a list. - * @param key List ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage lpop(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("lpop", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #lpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage lpush(String key, String[] values) { - return lpush(key, values, null, null); - } - - /** - * {@link #lpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage lpush(String key, String[] values, final ResponseListener listener) { - return lpush(key, values, null, listener); - } - - /** - * {@link #lpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage lpush(String key, String[] values, Options options) { - return lpush(key, values, options, null); - } - - /** - * Prepends the specified values to a list. - * If the key does not exist, it is created holding - * an empty list before performing the operation. - * @param key List ID - * @param values Values to prepend - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage lpush(String key, String[] values, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("values", new JSONArray(Arrays.asList(values))) - ); - - send("lpush", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #lpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage lpushx(String key, final String value) { - return lpushx(key, value, null, null); - } - - /** - * {@link #lpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage lpushx(String key, final String value, Options options) { - return lpushx(key, value, options, null); - } - - /** - * {@link #lpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage lpushx(String key, final String value, final ResponseListener listener) { - return lpushx(key, value, null, listener); - } - - /** - * Prepends the specified value to a list, - * only if the key already exists and if it holds a list. - * @param key List ID - * @param value Value to prepend - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage lpushx(String key, final String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("lpushx", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #lrange(String, long, long, Options, ResponseListener)} - */ - public void lrange(String key, long start, long stop, final ResponseListener listener) { - lrange(key, start, stop, null, listener); - } - - /** - * Returns the list elements between the start and stop positions (inclusive). - * @param key List ID - * @param start Start position - * @param stop End position - * @param options Request options - * @param listener Response callback listener - */ - public void lrange(String key, long start, long stop, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("start", start) - .put("stop", stop); - - send("lrange", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #lrem(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lrem(String key, long count, String value) { - return lrem(key, count, value, null, null); - } - - /** - * {@link #lrem(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lrem(String key, long count, String value, final ResponseListener listener) { - return lrem(key, count, value, null, listener); - } - - /** - * {@link #lrem(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lrem(String key, long count, String value, Options options) { - return lrem(key, count, value, options, null); - } - - /** - * Removes the first count occurences of elements equal to value from a list. - * @param key List ID - * @param count Number of elements to remove - * @param value Value to remove - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage lrem(String key, long count, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("count", count) - .put("value", value) - ); - - send("lrem", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #lset(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lset(String key, long index, String value) { - return lset(key, index, value, null, null); - } - - /** - * {@link #lset(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lset(String key, long index, String value, final ResponseListener listener) { - return lset(key, index, value, null, listener); - } - - /** - * {@link #lset(String, long, String, Options, ResponseListener)} - */ - public MemoryStorage lset(String key, long index, String value, Options options) { - return lset(key, index, value, options, null); - } - - /** - * Sets the list element at index with the provided value. - * @param key List ID - * @param index Index of the element to set - * @param value Element new value - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage lset(String key, long index, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("index", index) - .put("value", value) - ); - - send("lset", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #ltrim(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage ltrim(String key, long start, long stop) { - return ltrim(key, start, stop, null, null); - } - - /** - * {@link #ltrim(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage ltrim(String key, long start, long stop, final ResponseListener listener) { - return ltrim(key, start, stop, null, listener); - } - - /** - * {@link #ltrim(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage ltrim(String key, long start, long stop, Options options) { - return ltrim(key, start, stop, options, null); - } - - /** - * Trims an existing list so that it will - * contain only the specified range of elements specified. - * @param key List ID - * @param start Start position - * @param stop End position - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage ltrim(String key, long start, long stop, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("start", start) - .put("stop", stop) - ); - - send("ltrim", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #mget(String[], Options, ResponseListener)} - */ - public void mget(String[] keys, final ResponseListener listener) { - mget(keys, null, listener); - } - - /** - * Returns the values of the provided keys. - * @param keys List of key identifiers - * @param options Request options - * @param listener Response callback listener - */ - public void mget(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - send("mget", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #mset(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage mset(JSONObject[] entries) { - return mset(entries, null, null); - } - - /** - * {@link #mset(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage mset(JSONObject[] entries, Options options) { - return mset(entries, options, null); - } - - /** - * {@link #mset(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage mset(JSONObject[] entries, final ResponseListener listener) { - return mset(entries, null, listener); - } - - /** - * Sets the provided keys to their respective values. - * If a key does not exist, it is created. Otherwise, the key’s value is overwritten. - * @param entries Key-Value pairs - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage mset(JSONObject[] entries, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject().put("entries", new JSONArray(Arrays.asList(entries)))); - - send("mset", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #msetnx(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage msetnx(JSONObject[] entries) { - return msetnx(entries, null, null); - } - - /** - * {@link #msetnx(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage msetnx(JSONObject[] entries, Options options) { - return msetnx(entries, options, null); - } - - /** - * {@link #msetnx(JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage msetnx(JSONObject[] entries, final ResponseListener listener) { - return msetnx(entries, null, listener); - } - - /** - * Sets the provided keys to their respective values, only if they do not exist. - * If a key exists, then the whole operation is aborted and no key is set - * @param entries Key-Value pairs to set - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage msetnx(JSONObject[] entries, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject().put("entries", new JSONArray(Arrays.asList(entries)))); - - send("msetnx", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #object(String, String, Options, ResponseListener)} - */ - public void object(String key, String subcommand, final ResponseListener listener) { - object(key, subcommand, null, listener); - } - - /** - * Inspects the low-level properties of a key. - * @param key Key ID - * @param subcommand Name of the low-level property to get - * @param options Request options - * @param listener Response callback listener - */ - public void object(String key, String subcommand, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("subcommand", subcommand); - - send("object", query, options, getCallbackString(listener)); - } - - /** - * {@link #persist(String, Options, ResponseListener)} - */ - public MemoryStorage persist(String key) { - return persist(key, null, null); - } - - /** - * {@link #persist(String, Options, ResponseListener)} - */ - public MemoryStorage persist(String key, final ResponseListener listener) { - return persist(key, null, listener); - } - - /** - * {@link #persist(String, Options, ResponseListener)} - */ - public MemoryStorage persist(String key, Options options) { - return persist(key, options, null); - } - - /** - * Removes the expiration delay or timestamp from a key, making it persistent. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage persist(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("persist", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #pexpire(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpire(String key, long milliseconds) { - return pexpire(key, milliseconds, null, null); - } - - /** - * {@link #pexpire(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpire(String key, long milliseconds, Options options) { - return pexpire(key, milliseconds, options, null); - } - - /** - * {@link #pexpire(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpire(String key, long milliseconds, final ResponseListener listener) { - return pexpire(key, milliseconds, null, listener); - } - - /** - * Sets a timeout (in milliseconds) on a key. - * After the timeout has expired, the key will automatically be deleted. - * @param key Key ID - * @param milliseconds Expiration time in milliseconds - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage pexpire(String key, long milliseconds, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("milliseconds", milliseconds) - ); - - send("pexpire", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #pexpireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpireat(String key, long timestamp) { - return pexpireat(key, timestamp, null, null); - } - - /** - * {@link #pexpireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpireat(String key, long timestamp, Options options) { - return pexpireat(key, timestamp, options, null); - } - - /** - * {@link #pexpireat(String, long, Options, ResponseListener)} - */ - public MemoryStorage pexpireat(String key, long timestamp, final ResponseListener listener) { - return pexpireat(key, timestamp, null, listener); - } - - /** - * Sets an expiration timestamp on a key. - * After the timestamp has been reached, the key will automatically be deleted. - * @param key Key ID - * @param timestamp Expiration timestamp (Epoch-time in milliseconds) - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage pexpireat(String key, long timestamp, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("timestamp", timestamp) - ); - - send("pexpireat", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #pfadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfadd(String key, String[] elements) { - return pfadd(key, elements, null, null); - } - - /** - * {@link #pfadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfadd(String key, String[] elements, final ResponseListener listener) { - return pfadd(key, elements, null, listener); - } - - /** - * {@link #pfadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfadd(String key, String[] elements, Options options) { - return pfadd(key, elements, options, null); - } - - /** - * Adds elements to an HyperLogLog data structure. - * @param key HyperLogLog ID - * @param elements Array of elements to add - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage pfadd(String key, String[] elements, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("elements", new JSONArray(Arrays.asList(elements))) - ); - - send("pfadd", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #pfcount(String[], Options, ResponseListener)} - */ - public void pfcount(String[] keys, final ResponseListener listener) { - pfcount(keys, null, listener); - } - - /** - * Returns the probabilistic cardinality of a HyperLogLog data structure, - * or of the merged HyperLogLog structures if more than 1 is provided (see pfadd). - * @param keys HyperLogLog ID - * @param options Request options - * @param listener Response callback listener - */ - public void pfcount(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - send("pfcount", query, options, getCallbackLong(listener)); - } - - /** - * {@link #pfmerge(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfmerge(String key, String[] sources) { - return pfmerge(key, sources, null, null); - } - - /** - * {@link #pfmerge(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfmerge(String key, String[] sources, final ResponseListener listener) { - return pfmerge(key, sources, null, listener); - } - - /** - * {@link #pfmerge(String, String[], Options, ResponseListener)} - */ - public MemoryStorage pfmerge(String key, String[] sources, Options options) { - return pfmerge(key, sources, options, null); - } - - /** - * Merges multiple HyperLogLog data structures into an unique HyperLogLog structure - * stored at key, approximating the cardinality of the union of the source structures. - * @param key Destination key ID - * @param sources Array of HyperLogLog ID to merge - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage pfmerge(String key, String[] sources, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("sources", new JSONArray(Arrays.asList(sources))) - ); - - send("pfmerge", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #ping(Options, ResponseListener)} - */ - public void ping(final ResponseListener listener) { - ping(null, listener); - } - - /** - * Pings the memory storage database. - * @param options Request options - * @param listener Response callback listener - */ - public void ping(Options options, final ResponseListener listener) { - send("ping", new KuzzleJSONObject(), options, getCallbackString(listener)); - } - - /** - * {@link #psetex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage psetex(String key, String value, long milliseconds) { - return psetex(key, value, milliseconds, null, null); - } - - /** - * {@link #psetex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage psetex(String key, String value, long milliseconds, final ResponseListener listener) { - return psetex(key, value, milliseconds, null, listener); - } - - /** - * {@link #psetex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage psetex(String key, String value, long milliseconds, Options options) { - return psetex(key, value, milliseconds, options, null); - } - - /** - * Sets a key with the provided value, and an expiration delay - * expressed in milliseconds. If the key does not exist, it is created beforehand. - * @param key Key ID - * @param value Value to set - * @param milliseconds Expiration delay in milliseconds - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage psetex(String key, String value, long milliseconds, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - .put("milliseconds", milliseconds) - ); - - send("psetex", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #pttl(String, Options, ResponseListener)} - */ - public void pttl(String key, final ResponseListener listener) { - pttl(key, null, listener); - } - - /** - * Returns the remaining time to live of a key, in milliseconds. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void pttl(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("pttl", query, options, getCallbackLong(listener)); - } - - /** - * {@link #randomkey(Options, ResponseListener)} - */ - public void randomkey(final ResponseListener listener) { - randomkey(null, listener); - } - - /** - * Returns a random key from the memory storage. - * @param options Request options - * @param listener Response callback listener - */ - public void randomkey(Options options, final ResponseListener listener) { - send("randomkey", new KuzzleJSONObject(), options, getCallbackString(listener)); - } - - /** - * {@link #rename(String, String, Options, ResponseListener)} - */ - public MemoryStorage rename(String key, String newkey) { - return rename(key, newkey, null, null); - } - - /** - * {@link #rename(String, String, Options, ResponseListener)} - */ - public MemoryStorage rename(String key, String newkey, final ResponseListener listener) { - return rename(key, newkey, null, listener); - } - - /** - * {@link #rename(String, String, Options, ResponseListener)} - */ - public MemoryStorage rename(String key, String newkey, Options options) { - return rename(key, newkey, options, null); - } - - /** - * Renames a key to newkey. If newkey already exists, it is overwritten. - * @param key Key ID - * @param newkey New key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage rename(String key, String newkey, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("newkey", newkey) - ); - - send("rename", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #renamenx(String, String, Options, ResponseListener)} - */ - public MemoryStorage renamenx(String key, String newkey) { - return renamenx(key, newkey, null, null); - } - - /** - * {@link #renamenx(String, String, Options, ResponseListener)} - */ - public MemoryStorage renamenx(String key, String newkey, final ResponseListener listener) { - return renamenx(key, newkey, null, listener); - } - - /** - * {@link #renamenx(String, String, Options, ResponseListener)} - */ - public MemoryStorage renamenx(String key, String newkey, Options options) { - return renamenx(key, newkey, options, null); - } - - /** - * Renames a key to newkey, only if newkey does not already exist. - * @param key Key ID - * @param newkey New key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage renamenx(String key, String newkey, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("newkey", newkey) - ); - - send("renamenx", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #rpop(String, Options, ResponseListener)} - */ - public MemoryStorage rpop(String key) { - return rpop(key, null, null); - } - - /** - * {@link #rpop(String, Options, ResponseListener)} - */ - public MemoryStorage rpop(String key, final ResponseListener listener) { - return rpop(key, null, listener); - } - - /** - * {@link #rpop(String, Options, ResponseListener)} - */ - public MemoryStorage rpop(String key, Options options) { - return rpop(key, options, null); - } - - /** - * Removes and returns the last element of a list. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public MemoryStorage rpop(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("rpop", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #rpoplpush(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpoplpush(String source, String destination) { - return rpoplpush(source, destination, null, null); - } - - /** - * {@link #rpoplpush(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpoplpush(String source, String destination, final ResponseListener listener) { - return rpoplpush(source, destination, null, listener); - } - - /** - * {@link #rpoplpush(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpoplpush(String source, String destination, Options options) { - return rpoplpush(source, destination, options, null); - } - - /** - * Removes the last element of the list at source and - * pushes it back at the start of the list at destination. - * @param source Source key ID - * @param destination Destination key ID - * @param options [description] - * @param listener [description] - * @return [description] - */ - public MemoryStorage rpoplpush(String source, String destination, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject() - .put("source", source) - .put("destination", destination) - ); - - send("rpoplpush", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #rpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage rpush(String key, String[] values) { - return rpush(key, values, null, null); - } - - /** - * {@link #rpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage rpush(String key, String[] values, final ResponseListener listener) { - return rpush(key, values, null, listener); - } - - /** - * {@link #rpush(String, String[], Options, ResponseListener)} - */ - public MemoryStorage rpush(String key, String[] values, Options options) { - return rpush(key, values, options, null); - } - - /** - * Appends the specified values at the end of a list. - * If the key does not exist, it is created holding an empty - * list before performing the operation. - * @param key List ID - * @param values Values to append - * @param options [description] - * @param listener [description] - * @return [description] - */ - public MemoryStorage rpush(String key, String[] values, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("values", new JSONArray(Arrays.asList(values))) - ); - - send("rpush", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #rpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpushx(String key, final String value) { - return rpushx(key, value, null, null); - } - - /** - * {@link #rpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpushx(String key, final String value, Options options) { - return rpushx(key, value, options, null); - } - - /** - * {@link #rpushx(String, String, Options, ResponseListener)} - */ - public MemoryStorage rpushx(String key, final String value, final ResponseListener listener) { - return rpushx(key, value, null, listener); - } - - /** - * Appends the specified value at the end of a list, - * only if the key already exists and if it holds a list. - * @param key List ID - * @param value Value to append - * @param options [description] - * @param listener [description] - * @return [description] - */ - public MemoryStorage rpushx(String key, final String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("rpushx", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #sadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sadd(String key, String[] members) { - return sadd(key, members, null, null); - } - - /** - * {@link #sadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sadd(String key, String[] members, final ResponseListener listener) { - return sadd(key, members, null, listener); - } - - /** - * {@link #sadd(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sadd(String key, String[] members, Options options) { - return sadd(key, members, options, null); - } - - /** - * Adds members to a set of unique values stored at key. - * If the key does not exist, it is created beforehand. - * @param key Set ID - * @param members Members to add - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage sadd(String key, String[] members, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - send("sadd", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #scan(long, Options, ResponseListener)} - */ - public void scan(long cursor, final ResponseListener listener) { - scan(cursor, null, listener); - } - - /** - * Iterates incrementally the set of keys in the database using a cursor. - * - * @param cursor Cursor position (0 to start an iteration) - * @param options Request options - * @param listener Response callback listener - */ - public void scan(long cursor, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("cursor", cursor); - - if (options != null) { - if (options.getCount() != null) { - query.put("count", options.getCount()); - } - - if (options.getMatch() != null) { - query.put("match", options.getMatch()); - } - } - - send("scan", query, options, getCallbackScanResult(listener)); - } - - /** - * {@link #scard(String, Options, ResponseListener)} - */ - public void scard(String key, final ResponseListener listener) { - scard(key, null, listener); - } - - /** - * Returns the number of members stored in a set of unique values. - * @param key Set ID - * @param options Request options - * @param listener Response callback listener - */ - public void scard(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("scard", query, options, getCallbackLong(listener)); - } - - /** - * {@link #sdiff(String, String[], Options, ResponseListener)} - */ - public void sdiff(String key, String[] keys, final ResponseListener listener) { - sdiff(key, keys, null, listener); - } - - /** - * Returns the difference between the set of unique - * values stored at key and the other provided sets. - * @param key Reference set ID - * @param keys Set IDs to compare - * @param options Request options - * @param listener Response callback listener - */ - public void sdiff(String key, String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("keys", new JSONArray(Arrays.asList(keys))); - - send("sdiff", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #sdiffstore(String, String[], String, Options, ResponseListener)} - */ - public MemoryStorage sdiffstore(String key, String[] keys, String destination) { - return sdiffstore(key, keys, destination, null, null); - } - - /** - * {@link #sdiffstore(String, String[], String, Options, ResponseListener)} - */ - public MemoryStorage sdiffstore(String key, String[] keys, String destination, final ResponseListener listener) { - return sdiffstore(key, keys, destination, null, listener); - } - - /** - * {@link #sdiffstore(String, String[], String, Options, ResponseListener)} - */ - public MemoryStorage sdiffstore(String key, String[] keys, String destination, Options options) { - return sdiffstore(key, keys, destination, options, null); - } - - /** - * Computes the difference between the set of unique values stored at key and - * the other provided sets, and stores the result in the key stored at destination. - * @param key Reference set ID - * @param keys Set IDs to compare - * @param destination Destination set ID - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage sdiffstore(String key, String[] keys, String destination, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("destination", destination) - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - send("sdiffstore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #set(String, String, Options, ResponseListener)} - */ - public MemoryStorage set(String key, String value) { - return set(key, value, null, null); - } - - /** - * {@link #set(String, String, Options, ResponseListener)} - */ - public MemoryStorage set(String key, String value, final ResponseListener listener) { - return set(key, value, null, listener); - } - - /** - * {@link #set(String, String, Options, ResponseListener)} - */ - public MemoryStorage set(String key, String value, Options options) { - return set(key, value, options, null); - } - - /** - * Creates a key holding the provided value, or overwrites it if it already exists. - * @param key Key ID - * @param value Value to set - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage set(String key, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - KuzzleJSONObject body = new KuzzleJSONObject().put("value", value); - - if (options != null) { - if (options.getEx() != null) { - body.put("ex", options.getEx()); - } - - if (options.getPx() != null) { - body.put("px", options.getPx()); - } - - body.put("nx", options.getNx()); - body.put("xx", options.getXx()); - } - - query.put("body", body); - - send("set", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #setex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage setex(String key, String value, long seconds) { - return setex(key, value, seconds, null, null); - } - - /** - * {@link #setex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage setex(String key, String value, long seconds, final ResponseListener listener) { - return setex(key, value, seconds, null, listener); - } - - /** - * {@link #setex(String, String, long, Options, ResponseListener)} - */ - public MemoryStorage setex(String key, String value, long seconds, Options options) { - return setex(key, value, seconds, options, null); - } - - /** - * Sets a key with the provided value, and an expiration delay - * expressed in seconds. If the key does not exist, it is created beforehand. - * @param key Key ID - * @param value Value to set - * @param seconds Expiration delay, in seconds - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage setex(String key, String value, long seconds, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - .put("seconds", seconds) - ); - - send("setex", query, options, listener != null ? getCallbackString(listener) : null); - - return this; - } - - /** - * {@link #setnx(String, String, Options, ResponseListener)} - */ - public MemoryStorage setnx(String key, String value) { - return setnx(key, value, null, null); - } - - /** - * {@link #setnx(String, String, Options, ResponseListener)} - */ - public MemoryStorage setnx(String key, String value, final ResponseListener listener) { - return setnx(key, value, null, listener); - } - - /** - * {@link #setnx(String, String, Options, ResponseListener)} - */ - public MemoryStorage setnx(String key, String value, Options options) { - return setnx(key, value, options, null); - } - - /** - * Sets a value on a key, only if it does not already exist. - * @param key Key ID - * @param value Value to set - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage setnx(String key, String value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("value", value) - ); - - send("setnx", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #sinter(String[], Options, ResponseListener)} - */ - public void sinter(String[] keys, final ResponseListener listener) { - sinter(keys, null, listener); - } - - /** - * Returns the intersection of the provided sets of unique values. - * @param keys Array of set IDs to intersect - * @param options Request options - * @param listener Response callback listener - */ - public void sinter(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - send("sinter", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #sinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sinterstore(String destination, String[] keys) { - return sinterstore(destination, keys, null, null); - } - - /** - * {@link #sinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sinterstore(String destination, String[] keys, final ResponseListener listener) { - return sinterstore(destination, keys, null, listener); - } - - /** - * {@link #sinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sinterstore(String destination, String[] keys, Options options) { - return sinterstore(destination, keys, options, null); - } - - /** - * Computes the intersection of the provided sets of unique values - * and stores the result in the destination key. - * @param destination Destination key ID - * @param keys Array of set IDs to intersect - * @param options [description] - * @param listener [description] - * @return [description] - */ - public MemoryStorage sinterstore(String destination, String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject() - .put("destination", destination) - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - send("sinterstore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #sismember(String, String, Options, ResponseListener)} - */ - public void sismember(String key, String member, final ResponseListener listener) { - sismember(key, member, null, listener); - } - - /** - * Checks if member is a member of the set of unique values stored at key. - * @param key Set ID - * @param member Member name - * @param options Request options - * @param listener Response callback listener - */ - public void sismember(String key, String member, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("member", member); - - send("sismember", query, options, getCallbackInt(listener)); - } - - /** - * {@link #smembers(String, Options, ResponseListener)} - */ - public void smembers(String key, final ResponseListener listener) { - smembers(key, null, listener); - } - - /** - * Returns the members of a set of unique values. - * @param key Set ID - * @param options Request options - * @param listener Response callback listener - */ - public void smembers(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("smembers", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #smove(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage smove(String key, String destination, String member) { - return smove(key, destination, member, null, null); - } - - /** - * {@link #smove(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage smove(String key, String destination, String member, final ResponseListener listener) { - return smove(key, destination, member, null, listener); - } - - /** - * {@link #smove(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage smove(String key, String destination, String member, Options options) { - return smove(key, destination, member, options, null); - } - - /** - * Moves a member from a set of unique values to another. - * @param key Source set ID - * @param destination Destination set ID - * @param member Member to move - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage smove(String key, String destination, String member, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("destination", destination) - .put("member", member) - ); - - send("smove", query, options, listener != null ? getCallbackInt(listener) : null); - - return this; - } - - /** - * {@link #sort(String, Options, ResponseListener)} - */ - public void sort(String key, final ResponseListener listener) { - sort(key, null, listener); - } - - /** - * Sorts and returns elements contained in a list, a set of unique values or a - * sorted set. By default, sorting is numeric and elements are compared by their - * value interpreted as double precision floating point number. - * @param key ID of the key to sort - * @param options Request options - * @param listener Response callback listener - */ - public void sort(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - if (options != null) { - if (options.getBy() != null) { - query.put("by", options.getBy()); - } - - if (options.getDirection() != null) { - query.put("direction", options.getDirection()); - } - - if (options.getGet() != null) { - query.put("get", new JSONArray(Arrays.asList(options.getGet()))); - } - - if (options.getLimit() != null) { - query.put("limit", new JSONArray(Arrays.asList(options.getLimit()))); - } - - query.put("alpha", options.getAlpha()); - } - - send("sort", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #spop(String, Options, ResponseListener)} - */ - public MemoryStorage spop(String key) { - return spop(key, null, null); - } - - /** - * {@link #spop(String, Options, ResponseListener)} - */ - public MemoryStorage spop(String key, final ResponseListener listener) { - return spop(key, null, listener); - } - - /** - * {@link #spop(String, Options, ResponseListener)} - */ - public MemoryStorage spop(String key, Options options) { - return spop(key, options, null); - } - - /** - * Removes and returns one or more elements at random from a set of unique values. - * @param key Set ID - * @param listener [description] - * @return this - */ - public MemoryStorage spop(String key, Options options, final ResponseListener listener) { - ResponseListener callback = null; - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - if (options != null && options.getCount() != null) { - query.put("body", new KuzzleJSONObject().put("count", options.getCount())); - } - - if (listener != null) { - callback = new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (response.get("result") instanceof String) { - listener.onSuccess(new String[]{response.getString("result")}); - } - else { - JSONArray arr = response.getJSONArray("result"); - String[] elements = new String[arr.length()]; - - for (int i = 0; i < arr.length(); i++) { - elements[i] = arr.getString(i); - } - - listener.onSuccess(elements); - } - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - send("spop", query, options, callback); - - return this; - } - - /** - * {@link #srandmember(String, Options, ResponseListener)} - */ - public MemoryStorage srandmember(String key, final ResponseListener listener) { - return srandmember(key, null, listener); - } - - /** - * Returns one or more members of a set of unique values, at random. - * @param key Set ID - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage srandmember(String key, Options options, final ResponseListener listener) { - ResponseListener callback = null; - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - if (options != null && options.getCount() != null) { - query.put("count", options.getCount()); - } - - if (listener != null) { - callback = new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (response.get("result") instanceof String) { - listener.onSuccess(new String[]{response.getString("result")}); - } - else { - JSONArray arr = response.getJSONArray("result"); - String[] elements = new String[arr.length()]; - - for (int i = 0; i < arr.length(); i++) { - elements[i] = arr.getString(i); - } - - listener.onSuccess(elements); - } - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }; - } - - send("srandmember", query, options, callback); - - return this; - } - - /** - * {@link #srem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage srem(String key, String[] members) { - return srem(key, members, null, null); - } - - /** - * {@link #srem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage srem(String key, String[] members, final ResponseListener listener) { - return srem(key, members, null, listener); - } - - /** - * {@link #srem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage srem(String key, String[] members, Options options) { - return srem(key, members, options, null); - } - - /** - * Removes members from a set of unique values. - * @param key Set ID - * @param members Members to remove - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage srem(String key, String[] members, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - send("srem", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #sscan(String, long, Options, ResponseListener)} - */ - public void sscan(String key, long cursor, final ResponseListener listener) { - sscan(key, cursor, null, listener); - } - - /** - * Identical to scan, except that sscan iterates the members contained in a set - * @param key Set ID - * @param cursor Cursor position (0 to start a new scan) - * @param options Request options - * @param listener Response callback listener - */ - public void sscan(String key, long cursor, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("cursor", cursor); - - if (options != null) { - if (options.getCount() != null) { - query.put("count", options.getCount()); - } - - if (options.getMatch() != null) { - query.put("match", options.getMatch()); - } - } - - send("sscan", query, options, getCallbackScanResult(listener)); - } - - /** - * {@link #strlen(String, Options, ResponseListener)} - */ - public void strlen(String key, final ResponseListener listener) { - strlen(key, null, listener); - } - - /** - * Returns the length of a value stored at key. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void strlen(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("strlen", query, options, getCallbackLong(listener)); - } - - /** - * {@link #sunion(String[], Options, ResponseListener)} - */ - public void sunion(String[] keys, final ResponseListener listener) { - sunion(keys, null, listener); - } - - /** - * Returns the union of the provided sets of unique values. - * @param keys Set IDs - * @param options Request options - * @param listener Response callback listener - */ - public void sunion(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - send("sunion", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #sunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sunionstore(String destination, String[] keys) { - return sunionstore(destination, keys, null, null); - } - - /** - * {@link #sunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sunionstore(String destination, String[] keys, final ResponseListener listener) { - return sunionstore(destination, keys, null, listener); - } - - /** - * {@link #sunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage sunionstore(String destination, String[] keys, Options options) { - return sunionstore(destination, keys, options, null); - } - - /** - * Computes the union of the provided sets of unique values - * and stores the result in the destination key. - * @param destination Destination set ID - * @param keys Array of set IDs - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage sunionstore(String destination, String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject() - .put("destination", destination) - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - send("sunionstore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #time(Options, ResponseListener)} - */ - public void time(final ResponseListener listener) { - time(null, listener); - } - - /** - * Returns the current server time. - * @param options Request options - * @param listener Response callback listener - */ - public void time(Options options, final ResponseListener listener) { - send( - "time", - new KuzzleJSONObject(), - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray raw = response.getJSONArray("result"); - listener.onSuccess(new Long[]{ - Long.parseLong(raw.getString(0)), - Long.parseLong(raw.getString(1)) - }); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #touch(String[], Options, ResponseListener)} - */ - public MemoryStorage touch(String[] keys) { - return touch(keys, null, null); - } - - /** - * {@link #touch(String[], Options, ResponseListener)} - */ - public MemoryStorage touch(String[] keys, Options options) { - return touch(keys, options, null); - } - - /** - * {@link #touch(String[], Options, ResponseListener)} - */ - public MemoryStorage touch(String[] keys, final ResponseListener listener) { - return touch(keys, null, listener); - } - - /** - * Alters the last access time of one or multiple keys. - * A key is ignored if it does not exist. - * @param keys Array of key IDs to alter - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage touch(String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("body", new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys)))); - - send("touch", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #ttl(String, Options, ResponseListener)} - */ - public void ttl(String key, final ResponseListener listener) { - ttl(key, null, listener); - } - - /** - * Returns the remaining time to live of a key, in seconds, or a negative value - * if the key does not exist or if it is persistent. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void ttl(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("ttl", query, options, getCallbackLong(listener)); - } - - /** - * {@link #type(String, Options, ResponseListener)} - */ - public void type(String key, final ResponseListener listener) { - type(key, null, listener); - } - - /** - * Returns the type of the value held by a key. - * @param key Key ID - * @param options Request options - * @param listener Response callback listener - */ - public void type(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("type", query, options, getCallbackString(listener)); - } - - /** - * {@link #zadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage zadd(String key, JSONObject[] elements) { - return zadd(key, elements, null, null); - } - - /** - * {@link #zadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage zadd(String key, JSONObject[] elements, final ResponseListener listener) { - return zadd(key, elements, null, listener); - } - - /** - * {@link #zadd(String, JSONObject[], Options, ResponseListener)} - */ - public MemoryStorage zadd(String key, JSONObject[] elements, Options options) { - return zadd(key, elements, options, null); - } - - /** - * Adds the specified elements to the sorted set stored at key. - * If the key does not exist, it is created, holding an empty sorted set. - * If it already exists and does not hold a sorted set, an error is returned. - * @param key Sorted set ID - * @param elements Elements to add - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zadd(String key, JSONObject[] elements, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - KuzzleJSONObject body = new KuzzleJSONObject().put("elements", new JSONArray(Arrays.asList(elements))); - - if (options != null) { - body.put("nx", options.getNx()); - body.put("xx", options.getXx()); - body.put("ch", options.getCh()); - body.put("incr", options.getIncr()); - } - - query.put("body", body); - - send("zadd", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zcard(String, Options, ResponseListener)} - */ - public void zcard(String key, final ResponseListener listener) { - zcard(key, null, listener); - } - - /** - * Returns the number of elements held by a sorted set. - * @param key Sorted set ID - * @param options Request options - * @param listener Response callback listener - */ - public void zcard(String key, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key); - - send("zcard", query, options, getCallbackLong(listener)); - } - - /** - * {@link #zcount(String, long, long, Options, ResponseListener)} - */ - public void zcount(String key, long min, long max, final ResponseListener listener) { - zcount(key, min, max, null, listener); - } - - /** - * Returns the number of elements held by a sorted set - * with a score between the provided min and max values. - * @param key Sorted set ID - * @param min Minimum score - * @param max Maximum score - * @param options Request options - * @param listener Response callback listener - */ - public void zcount(String key, long min, long max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max); - - send("zcount", query, options, getCallbackLong(listener)); - } - - /** - * {@link #zincrby(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage zincrby(String key, String member, double value) { - return zincrby(key, member, value, null, null); - } - - /** - * {@link #zincrby(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage zincrby(String key, String member, double value, final ResponseListener listener) { - return zincrby(key, member, value, null, listener); - } - - /** - * {@link #zincrby(String, String, double, Options, ResponseListener)} - */ - public MemoryStorage zincrby(String key, String member, double value, Options options) { - return zincrby(key, member, value, options, null); - } - - /** - * Increments the score of a member in a sorted set by the provided value. - * @param key Sorted set ID - * @param member Member to increment - * @param value Increment value - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zincrby(String key, String member, double value, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("member", member) - .put("value", value) - ); - - - send("zincrby", query, options, listener != null ? getCallbackDouble(listener) : null); - - return this; - } - - /** - * {@link #zinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zinterstore(String destination, String[] keys) { - return zinterstore(destination, keys, null, null); - } - - /** - * {@link #zinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zinterstore(String destination, String[] keys, final ResponseListener listener) { - return zinterstore(destination, keys, null, listener); - } - - /** - * {@link #zinterstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zinterstore(String destination, String[] keys, Options options) { - return zinterstore(destination, keys, options, null); - } - - /** - * Computes the intersection of the provided sorted sets and - * stores the result in the destination key. - * @param destination Destination ID - * @param keys Array of sorted set IDs - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zinterstore(String destination, String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", destination); - KuzzleJSONObject body = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - if (options != null) { - if (options.getAggregate() != null) { - body.put("aggregate", options.getAggregate()); - } - - if (options.getWeights() != null) { - body.put("weights", new JSONArray(Arrays.asList(options.getWeights()))); - } - } - - query.put("body", body); - - send("zinterstore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zlexcount(String, String, String, Options, ResponseListener)} - */ - public void zlexcount(String key, String min, String max, final ResponseListener listener) { - zlexcount(key, min, max, null, listener); - } - - /** - * Counts elements in a sorted set where all members have equal - * score, using lexicographical ordering. - * @param key Sorted set ID - * @param min Minimum value - * @param max Maximum value - * @param options Request options - * @param listener Response callback listener - */ - public void zlexcount(String key, String min, String max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max); - - send("zlexcount", query, options, getCallbackLong(listener)); - } - - /** - * {@link #zrange(String, long, long, Options, ResponseListener)} - */ - public void zrange(String key, long start, long stop, final ResponseListener listener) { - zrange(key, start, stop, null, listener); - } - - /** - * Returns elements from a sorted set depending on their position in the set, - * from a start position index to a stop position index (inclusives). - * @param key Sorted set ID - * @param start Start position - * @param stop End position - * @param options Request options - * @param listener Response callback listener - */ - public void zrange(String key, long start, long stop, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("start", start) - .put("stop", stop) - .put("options", new JSONArray().put("withscores")); - - send( - "zrange", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapZrangeResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #zrangebylex(String, String, String, Options, ResponseListener)} - */ - public void zrangebylex(String key, String min, String max, final ResponseListener listener) { - zrangebylex(key, min, max, null, listener); - } - - /** - * Returns elements in a sorted set where all members have equal - * score, using lexicographical ordering. - * @param key Sorted set ID - * @param min Minimum value - * @param max Maximum value - * @param options Request options - * @param listener Response callback listener - */ - public void zrangebylex(String key, String min, String max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max); - - if (options != null) { - if (options.getLimit() != null) { - query.put("limit", new JSONArray(Arrays.asList(options.getLimit()))); - } - } - - send("zrangebylex", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #zrangebyscore(String, double, double, Options, ResponseListener)} - */ - public void zrangebyscore(String key, double min, double max, final ResponseListener listener) { - zrangebyscore(key, min, max, null, listener); - } - - /** - * Returns all the elements in the sorted set at key with a - * score between min and max (inclusive). T - * @param key Sorted set ID - * @param min Minimum score - * @param max Maximum score - * @param options Request options - * @param listener Response callback listener - */ - public void zrangebyscore(String key, double min, double max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max) - .put("options", new JSONArray().put("withscores")); - - if (options != null) { - if (options.getLimit() != null) { - query.put("limit", new JSONArray(Arrays.asList(options.getLimit()))); - } - } - - send( - "zrangebyscore", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapZrangeResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #zrank(String, String, Options, ResponseListener)} - */ - public void zrank(String key, String member, final ResponseListener listener) { - zrank(key, member, null, listener); - } - - /** - * Returns the position of an element in a sorted set, with scores in ascending order. - * @param key Sorted set ID - * @param member Member value - * @param options Request options - * @param listener Response callback listener - */ - public void zrank(String key, String member, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("member", member); - - send("zrank", query, options, getCallbackLong(listener)); - } - - /** - * {@link #zrem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zrem(String key, String[] members) { - return zrem(key, members, null, null); - } - - /** - * {@link #zrem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zrem(String key, String[] members, final ResponseListener listener) { - return zrem(key, members, null, listener); - } - - /** - * {@link #zrem(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zrem(String key, String[] members, Options options) { - return zrem(key, members, options, null); - } - - /** - * Removes members from a sorted set. - * @param key Sorted set ID - * @param members Members to remove - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zrem(String key, String[] members, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - send("zrem", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zremrangebylex(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage zremrangebylex(String key, String min, String max) { - return zremrangebylex(key, min, max, null, null); - } - - /** - * {@link #zremrangebylex(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage zremrangebylex(String key, String min, String max, final ResponseListener listener) { - return zremrangebylex(key, min, max, null, listener); - } - - /** - * {@link #zremrangebylex(String, String, String, Options, ResponseListener)} - */ - public MemoryStorage zremrangebylex(String key, String min, String max, Options options) { - return zremrangebylex(key, min, max, options, null); - } - - /** - * Removes members from a sorted set where all elements have - * the same score, using lexicographical ordering. - * @param key Sorted set ID - * @param min Minimum value - * @param max Maximum value - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zremrangebylex(String key, String min, String max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("min", min) - .put("max", max) - ); - - send("zremrangebylex", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zremrangebyrank(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyrank(String key, long min, long max) { - return zremrangebyrank(key, min, max, null, null); - } - - /** - * {@link #zremrangebyrank(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyrank(String key, long min, long max, final ResponseListener listener) { - return zremrangebyrank(key, min, max, null, listener); - } - - /** - * {@link #zremrangebyrank(String, long, long, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyrank(String key, long min, long max, Options options) { - return zremrangebyrank(key, min, max, options, null); - } - - /** - * Removes members from a sorted set with their position - * in the set - * @param key Sorted set ID - * @param min Start position - * @param max End position - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zremrangebyrank(String key, long min, long max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("start", min) - .put("stop", max) - ); - - send("zremrangebyrank", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zremrangebyscore(String, double, double, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyscore(String key, double min, double max) { - return zremrangebyscore(key, min, max, null, null); - } - - /** - * {@link #zremrangebyscore(String, double, double, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyscore(String key, double min, double max, final ResponseListener listener) { - return zremrangebyscore(key, min, max, null, listener); - } - - /** - * {@link #zremrangebyscore(String, double, double, Options, ResponseListener)} - */ - public MemoryStorage zremrangebyscore(String key, double min, double max, Options options) { - return zremrangebyscore(key, min, max, options, null); - } - - /** - * Removes members from a sorted set with a score - * @param key Sorted set ID - * @param min Minimum score - * @param max Maximum score - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zremrangebyscore(String key, double min, double max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("body", new KuzzleJSONObject() - .put("min", min) - .put("max", max) - ); - - send("zremrangebyscore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } - - /** - * {@link #zrevrange(String, long, long, Options, ResponseListener)} - */ - public void zrevrange(String key, long start, long stop, final ResponseListener listener) { - zrevrange(key, start, stop, null, listener); - } - - /** - * Identical to zrange, except that the sorted set is traversed in descending order. - * @param key Sorted set ID - * @param start Start position - * @param stop End position - * @param options Request options - * @param listener Response callback listener - */ - public void zrevrange(String key, long start, long stop, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("start", start) - .put("stop", stop) - .put("options", new JSONArray().put("withscores")); - - send( - "zrevrange", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapZrangeResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #zrevrangebylex(String, String, String, Options, ResponseListener)} - */ - public void zrevrangebylex(String key, String min, String max, final ResponseListener listener) { - zrevrangebylex(key, min, max, null, listener); - } - - /** - * Identical to zrangebylex except that the sorted set is traversed in descending order. - * @param key Sorted set ID - * @param min Minimum value - * @param max Maximum value - * @param options Request options - * @param listener Response callback listener - */ - public void zrevrangebylex(String key, String min, String max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max); - - if (options != null) { - if (options.getLimit() != null) { - query.put("limit", new JSONArray(Arrays.asList(options.getLimit()))); - } - } - - send("zrevrangebylex", query, options, getCallbackStringArray(listener)); - } - - /** - * {@link #zrevrangebyscore(String, double, double, Options, ResponseListener)} - */ - public void zrevrangebyscore(String key, double min, double max, final ResponseListener listener) { - zrevrangebyscore(key, min, max, null, listener); - } - - /** - * Identical to zrangebyscore except that the sorted set is traversed in descending order. - * @param key Sorted set ID - * @param min Minimum score - * @param max Maximum score - * @param options Request options - * @param listener Response callback listener - */ - public void zrevrangebyscore(String key, double min, double max, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("min", min) - .put("max", max) - .put("options", new JSONArray().put("withscores")); - - if (options != null) { - if (options.getLimit() != null) { - query.put("limit", new JSONArray(Arrays.asList(options.getLimit()))); - } - } - - send( - "zrevrangebyscore", - query, - options, - new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(mapZrangeResults(response.getJSONArray("result"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - } - ); - } - - /** - * {@link #zrevrank(String, String, Options, ResponseListener)} - */ - public void zrevrank(String key, String member, final ResponseListener listener) { - zrevrank(key, member, null, listener); - } - - /** - * Returns the position of an element in a sorted set, with scores in descending order. - * @param key Sorted set ID - * @param member Member value - * @param options Request options - * @param listener Response callback listener - */ - public void zrevrank(String key, String member, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("member", member); - - send("zrevrank", query, options, getCallbackLong(listener)); - } - - /** - * {@link #zscan(String, long, Options, ResponseListener)} - */ - public void zscan(String key, long cursor, final ResponseListener listener) { - zscan(key, cursor, null, listener); - } - - /** - * Identical to scan, except that zscan iterates the members held by a sorted set. - * @param key Sorted set ID - * @param cursor Cursor position (0 to start an iteration) - * @param options Request options - * @param listener Response callback listener - */ - public void zscan(String key, long cursor, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject() - .put("_id", key) - .put("cursor", cursor); - - if (options != null) { - if (options.getCount() != null) { - query.put("count", options.getCount()); - } - - if (options.getMatch() != null) { - query.put("match", options.getMatch()); - } - } - - send("zscan", query, options, getCallbackScanResult(listener)); - } - - /** - * {@link #zscore(String, String, Options, ResponseListener)} - */ - public void zscore(String key, String member, final ResponseListener listener) { - zscore(key, member, null, listener); - } - - /** - * Returns the score of a member in a sorted set. - * @param key Sorted set ID - * @param member Member value - * @param options Request options - * @param listener Response callback listener - */ - public void zscore(String key, String member, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", key).put("member", member); - - send("zscore", query, options, getCallbackDouble(listener)); - } - - /** - * {@link #zunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zunionstore(String destination, String[] keys) { - return zunionstore(destination, keys, null, null); - } - - /** - * {@link #zunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zunionstore(String destination, String[] keys, final ResponseListener listener) { - return zunionstore(destination, keys, null, listener); - } - - /** - * {@link #zunionstore(String, String[], Options, ResponseListener)} - */ - public MemoryStorage zunionstore(String destination, String[] keys, Options options) { - return zunionstore(destination, keys, options, null); - } - - /** - * Computes the union of the provided sorted sets and stores the result in the destination key. - * @param destination Destination key ID - * @param keys Array of sorted set IDs - * @param options [description] - * @param listener [description] - * @return this - */ - public MemoryStorage zunionstore(String destination, String[] keys, Options options, final ResponseListener listener) { - KuzzleJSONObject query = new KuzzleJSONObject().put("_id", destination); - KuzzleJSONObject body = new KuzzleJSONObject().put("keys", new JSONArray(Arrays.asList(keys))); - - if (options != null) { - if (options.getAggregate() != null) { - body.put("aggregate", options.getAggregate()); - } - - if (options.getWeights() != null) { - body.put("weights", new JSONArray(Arrays.asList(options.getWeights()))); - } - } - - query.put("body", body); - - send("zunionstore", query, options, listener != null ? getCallbackLong(listener) : null); - - return this; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/Options.java b/src/main/java/io/kuzzle/sdk/core/Options.java deleted file mode 100644 index 45230045..00000000 --- a/src/main/java/io/kuzzle/sdk/core/Options.java +++ /dev/null @@ -1,982 +0,0 @@ -package io.kuzzle.sdk.core; - - - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import io.kuzzle.sdk.enums.CollectionType; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.responses.SearchResult; - -public class Options { - // Default values - private boolean autoQueue = false; - private boolean autoReconnect = true; - private boolean autoReplay = false; - private boolean autoResubscribe = true; - private JSONObject headers = new JSONObject(); - private JSONObject _volatile = new JSONObject(); - private int queueMaxSize = 500; - private int queueTTL = 120000; - private long reconnectionDelay = 1000; - private String ifExist = "error"; - private Mode connect = Mode.AUTO; - private Mode offlineMode = Mode.MANUAL; - private int replayInterval = 10; - private boolean queuable = true; - private String defaultIndex = null; - private boolean replaceIfExist = false; - private String refresh = null; - private Long from = null; - private Long size = null; - private Integer port = 7512; - private String scroll = null; - - private boolean ssl = false; - private SearchResult previous = null; - private String scrollId = null; - private int retryOnConflict = 0; - - // MemoryStorage specific options - private Long start = null; - private Long end = null; - private String unit = null; - private boolean withcoord = false; - private boolean withdist = false; - private Long count = null; - private String sort = null; - private String match = null; - private Long ex = null; - private boolean nx = false; - private Long px = null; - private boolean xx = false; - private boolean alpha = false; - private String by = null; - private String direction = null; - private String[] get = null; - private Integer[] limit = null; - private boolean ch = false; - private boolean incr = false; - private String aggregate = null; - private Integer[] weights = null; - - // Used for getting collections - private CollectionType collectionType = CollectionType.ALL; - - public Options() { - // Default constructor - } - - public Options(Options originalOptions) throws JSONException { - this.autoQueue = originalOptions.autoQueue; - this.autoReconnect = originalOptions.autoReconnect; - this.autoResubscribe = originalOptions.autoResubscribe; - this.headers = new JSONObject(originalOptions.headers.toString()); - this._volatile = new JSONObject(originalOptions._volatile.toString()); - this.queueMaxSize = originalOptions.queueMaxSize; - this.queueTTL = originalOptions.queueTTL; - this.reconnectionDelay = originalOptions.reconnectionDelay; - this.ifExist = originalOptions.ifExist; - this.connect = originalOptions.connect; - this.offlineMode = originalOptions.offlineMode; - this.replayInterval = originalOptions.replayInterval; - this.queuable = originalOptions.queuable; - this.defaultIndex = originalOptions.defaultIndex; - this.replaceIfExist = originalOptions.replaceIfExist; - this.refresh = originalOptions.refresh; - this.from = originalOptions.from; - this.size = originalOptions.size; - this.port = originalOptions.port; - this.scroll = originalOptions.scroll; - this.previous = originalOptions.previous; - this.scrollId = originalOptions.scrollId; - } - - /** - * autoReconnect option getter - * - * @return isAutoReconnection option value - */ - public boolean isAutoReconnect() { - return autoReconnect; - } - - /** - * autoReconnect option setter - * - * @param autoReconnect New autoReconnect option value - * @return this - */ - public Options setAutoReconnect(boolean autoReconnect) { - this.autoReconnect = autoReconnect; - return this; - } - - /** - * headers getter - * - * @return headers option value - */ - public JSONObject getHeaders() { - return headers; - } - - /** - * headers setter - * - * @param headers New headers value - * @return this - */ - public Options setHeaders(JSONObject headers) { - this.headers = headers; - return this; - } - - /** - * exists option getter - * - * @return exists option value - */ - public String getIfExist() { - return ifExist; - } - - /** - * exists option setter - * - * @param value new exists option value - * @return this - */ - public Options setIfExist(String value) { - if (value != "error" && value != "replace") { - throw new IllegalArgumentException("Invalid value for option 'ifExists': " + value); - } - - this.ifExist = value; - return this; - } - - /** - * Gets volatile data. - * - * @return the volatile property - */ - public JSONObject getVolatile() { - return _volatile; - } - - /** - * Sets volatile data. - * - * @param _volatile new volatile data value - * @return this - */ - public Options setVolatile(JSONObject _volatile) { - this._volatile = _volatile; - return this; - } - - /** - * Gets connect property value - * - * @return the connect property value - */ - public Mode getConnect() { - return connect; - } - - /** - * Sets connect property value - * - * @param connect New connect property value - * @return this - */ - public Options setConnect(Mode connect) { - this.connect = connect; - return this; - } - - /** - * reconnectionDelay property getter - * - * @return the reconnectionDelay property value - */ - public long getReconnectionDelay() { - return reconnectionDelay; - } - - /** - * reconnectionDelay property setter - * - * @param reconnectionDelay New reconnectionDelay property value - * @return this - */ - public Options setReconnectionDelay(long reconnectionDelay) { - this.reconnectionDelay = reconnectionDelay; - return this; - } - - /** - * offlineMode property getter - * - * @return the offlineMode option value - */ - public Mode getOfflineMode() { - return offlineMode; - } - - /** - * offlineMode property setter - * - * @param offlineMode New offlineMode value - * @return this - */ - public Options setOfflineMode(Mode offlineMode) { - this.offlineMode = offlineMode; - return this; - } - - /** - * queueTTL property getter - * - * @return queueTTL property value - */ - public int getQueueTTL() { - return queueTTL; - } - - /** - * queueTTL property setter - * - * @param queueTTL New queueTTL value - * @return this - */ - public Options setQueueTTL(int queueTTL) { - this.queueTTL = queueTTL; - return this; - } - - /** - * autoReplay property getter - * - * @return autoReplay property value - */ - public boolean isAutoReplay() { - return autoReplay; - } - - /** - * autoReplay property setter - * - * @param autoReplay New autoReplay value - * @return this - */ - public Options setAutoReplay(boolean autoReplay) { - this.autoReplay = autoReplay; - return this; - } - - /** - * queuable property getter - * - * @return queuable property value - */ - public boolean isQueuable() { - return queuable; - } - - /** - * queuable property setter - * - * @param queuable New queuable value - * @return this - */ - public Options setQueuable(boolean queuable) { - this.queuable = queuable; - return this; - } - - /** - * queueMaxSize property getter - * - * @return queueMaxSize value - */ - public int getQueueMaxSize() { - return queueMaxSize; - } - - /** - * queueMaxSize property setter - * - * @param queueMaxSize New queueMaxSize value - * @return this - */ - public Options setQueueMaxSize(int queueMaxSize) { - this.queueMaxSize = queueMaxSize; - return this; - } - - /** - * replayInterval property getter - * - * @return replayInterval property value - */ - public int getReplayInterval() { - return replayInterval; - } - - /** - * replayInterval property setter - * - * @param replayInterval New replayInterval value - * @return this - */ - public Options setReplayInterval(int replayInterval) { - this.replayInterval = replayInterval; - return this; - } - - /** - * autoResubscribe property getter - * - * @return autoResubscribe property value - */ - public boolean isAutoResubscribe() { - return autoResubscribe; - } - - /** - * autoResubscribe property setter - * - * @param autoResubscribe New autoResubscribe value - * @return this - */ - public Options setAutoResubscribe(boolean autoResubscribe) { - this.autoResubscribe = autoResubscribe; - return this; - } - - /** - * collectionType property getter - * - * @return collectionType property value - */ - public CollectionType getCollectionType() { - return collectionType; - } - - /** - * collectionType property setter - * - * @param type New collectionType value - * @return this - */ - public Options setCollectionType(CollectionType type) { - this.collectionType = type; - return this; - } - - /** - * defaultIndex property setter - * - * @param index New defaultIndex value - * @return this - */ - public Options setDefaultIndex(final String index) { - this.defaultIndex = index; - return this; - } - - /** - * defaultIndex property getter - * - * @return defaultIndex property value - */ - public String getDefaultIndex() { - return this.defaultIndex; - } - - /** - * autoQueue property setter - * - * @param autoQueue New autoQueue value - * @return this - */ - public Options setAutoQueue(boolean autoQueue) { - this.autoQueue = autoQueue; - return this; - } - - /** - * autoQueue property getter - * - * @return autoQueue property value - */ - public boolean isAutoQueue() { - return this.autoQueue; - } - - /** - * replaceIfExist property setter - * - * @param replace New replaceIfExist value - * @return this - */ - public Options setReplaceIfExist(boolean replace) { - this.replaceIfExist = replace; - return this; - } - - /** - * replaceIfExist property getter - * - * @return replaceIfExist property value - */ - public boolean isReplaceIfExist() { - return this.replaceIfExist; - } - - /** - * from property getter - * @return from property value - */ - public Long getFrom() { - return from; - } - - /** - * from property setter - * @param from New from value - * @return this - */ - public Options setFrom(Long from) { - this.from = from; - return this; - } - - /** - * size property getter - * @return size property value - */ - public Long getSize() { - return size; - } - - /** - * size property setter - * @param size New size value - * @return this - */ - public Options setSize(Long size) { - this.size = size; - return this; - } - - /** - * port property setter - * @param port New port value - * @return this - */ - public Options setPort(Integer port) { - this.port = port; - return this; - } - - /** - * port property getter - * @return port property value - */ - public Integer getPort() { - return this.port; - } - - /** - * ssl property getter - * @return ssl property value - */ - public boolean isSsl() { - return ssl; - } - - /** - * ssl property setter - * @param ssl New port value - */ - public void setSsl(boolean ssl) { - this.ssl = ssl; - } - - /** - * refresh property getter - * @return refresh property value - */ - public String getRefresh() { - return refresh; - } - - /** - * refresh property setter - * @param refresh New refresh property value - * @return [description] - */ - public Options setRefresh(String refresh) { - this.refresh = refresh; - return this; - } - - /** - * scroll property getter - * @return scroll property value - */ - public String getScroll() { - return scroll; - } - - /** - * scroll property setter - * @param scroll New scroll value - * @return this - */ - public Options setScroll(String scroll) { - this.scroll = scroll; - return this; - } - - /** - * previous property getter - * @return previous property value - */ - public SearchResult getPrevious() { - return previous; - } - - /** - * previous property setter - * @param previous New previous value - * @return this - */ - public Options setPrevious(SearchResult previous) { - this.previous = previous; - return this; - } - - /** - * scrollId property getter - * @return scrollId property value - */ - public String getScrollId() { - return scrollId; - } - - /** - * scrollId property setter - * @param scrollId New scrollId value - * @return this - */ - public Options setScrollId(String scrollId) { - this.scrollId = scrollId; - return this; - } - - /** - * retryOnConflict property getter - * @return retryOnConflict property value - */ - public int getRetryOnConflict() { - return retryOnConflict; - } - - /** - * retryOnConflict property setter - * @param retryOnConflict New retryOnConflict value - * @return this - */ - public Options setRetryOnConflict(int retryOnConflict) { - if (retryOnConflict < 0) { - throw new IllegalArgumentException("Invalid value for the retryOnConflict option (positive or null integer allowed)"); - } - - this.retryOnConflict = retryOnConflict; - return this; - } - - /** - * start property getter - * @return start property value - */ - public Long getStart() { - return start; - } - - /** - * start property setter - * @param start New start value - * @return this - */ - public Options setStart(Long start) { - this.start = start; - return this; - } - - /** - * end property getter - * @return end property value - */ - public Long getEnd() { - return end; - } - - /** - * end property setter - * @param end New end value - * @return this - */ - public Options setEnd(Long end) { - this.end = end; - return this; - } - - /** - * unit property getter - * @return unit property value - */ - public String getUnit() { - return unit; - } - - /** - * unit property setter - * @param unit New unit value - * @return this - */ - public Options setUnit(String unit) { - this.unit = unit; - return this; - } - - /** - * withcoord property getter - * @return withcoord property value - */ - public boolean getWithcoord() { - return withcoord; - } - - /** - * withcoord property setter - * @param withcoord New withcoord value - * @return this - */ - public Options setWithcoord(boolean withcoord) { - this.withcoord = withcoord; - return this; - } - - /** - * withdist property getter - * @return withdist property value - */ - public boolean getWithdist() { - return withdist; - } - - /** - * withdist property setter - * @param withdist New withdist value - * @return this - */ - public Options setWithdist(boolean withdist) { - this.withdist = withdist; - return this; - } - - /** - * count property getter - * @return count property value - */ - public Long getCount() { - return count; - } - - /** - * count property setter - * @param count New count value - * @return this - */ - public Options setCount(Long count) { - this.count = count; - return this; - } - - /** - * sort property getter - * @return sort property value - */ - public String getSort() { - return sort; - } - - /** - * sort property setter - * @param sort New sort value - * @return this - */ - public Options setSort(String sort) { - this.sort = sort; - return this; - } - - /** - * match property getter - * @return match property value - */ - public String getMatch() { - return match; - } - - /** - * match property setter - * @param match New match value - * @return this - */ - public Options setMatch(String match) { - this.match = match; - return this; - } - - /** - * ex property getter - * @return ex property value - */ - public Long getEx() { - return ex; - } - - /** - * ex property setter - * @param ex New ex value - * @return this - */ - public Options setEx(Long ex) { - this.ex = ex; - return this; - } - - /** - * nx property getter - * @return nx property value - */ - public boolean getNx() { - return nx; - } - - /** - * nx property setter - * @param nx New nx value - * @return this - */ - public Options setNx(boolean nx) { - this.nx = nx; - return this; - } - - /** - * px property getter - * @return px property value - */ - public Long getPx() { - return px; - } - - /** - * px property setter - * @param px New px value - * @return this - */ - public Options setPx(Long px) { - this.px = px; - return this; - } - - /** - * xx property getter - * @return xx property value - */ - public boolean getXx() { - return xx; - } - - /** - * xx property setter - * @param xx New xx value - * @return this - */ - public Options setXx(boolean xx) { - this.xx = xx; - return this; - } - - /** - * alpha property getter - * @return alpha property value - */ - public boolean getAlpha() { - return alpha; - } - - /** - * alpha property setter - * @param alpha New alpha value - * @return this - */ - public Options setAlpha(boolean alpha) { - this.alpha = alpha; - return this; - } - - /** - * by property getter - * @return by property value - */ - public String getBy() { - return by; - } - - /** - * by property setter - * @param by New by value - * @return this - */ - public Options setBy(String by) { - this.by = by; - return this; - } - - /** - * direction property getter - * @return direction property value - */ - public String getDirection() { - return direction; - } - - /** - * direction property setter - * @param direction New direction value - * @return this - */ - public Options setDirection(String direction) { - this.direction = direction; - return this; - } - - /** - * get property getter - * @return get property value - */ - public String[] getGet() { - return get; - } - - /** - * get property setter - * @param get New get value - * @return this - */ - public Options setGet(String[] get) { - this.get = get; - return this; - } - - /** - * limit property getter - * @return limit property value - */ - public Integer[] getLimit() { - return limit; - } - - /** - * limit property setter - * @param limit New limit value - * @return this - */ - public Options setLimit(Integer[] limit) { - this.limit = limit; - return this; - } - - /** - * ch property getter - * @return ch property value - */ - public boolean getCh() { - return ch; - } - - /** - * ch property setter - * @param ch New ch value - * @return this - */ - public Options setCh(boolean ch) { - this.ch = ch; - return this; - } - - /** - * incr property getter - * @return incr property value - */ - public boolean getIncr() { - return incr; - } - - /** - * incr property setter - * @param incr New incr value - * @return this - */ - public Options setIncr(boolean incr) { - this.incr = incr; - return this; - } - - /** - * aggregate property getter - * @return aggregate property value - */ - public String getAggregate() { - return aggregate; - } - - /** - * aggregate property setter - * @param aggregate New aggregate value - * @return this - */ - public Options setAggregate(String aggregate) { - this.aggregate = aggregate; - return this; - } - - /** - * weights property getter - * @return weights property value - */ - public Integer[] getWeights() { - return weights; - } - - /** - * weights property setter - * @param weights New weights value - * @return this - */ - public Options setWeights(Integer[] weights) { - this.weights = weights; - return this; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/Room.java b/src/main/java/io/kuzzle/sdk/core/Room.java deleted file mode 100644 index e81b55f7..00000000 --- a/src/main/java/io/kuzzle/sdk/core/Room.java +++ /dev/null @@ -1,560 +0,0 @@ -package io.kuzzle.sdk.core; - - - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Scope; -import io.kuzzle.sdk.enums.State; -import io.kuzzle.sdk.enums.Users; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.SubscribeListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.NotificationResponse; -import io.kuzzle.sdk.state.States; - -public class Room { - - private String id = UUID.randomUUID().toString(); - protected String collection; - protected Collection dataCollection; - protected JSONObject filters = new JSONObject(); - protected JSONObject headers; - protected JSONObject _volatile; - protected boolean subscribeToSelf; - protected String roomId; - protected Kuzzle kuzzle; - protected String channel; - protected Scope scope; - protected State state; - protected Users users; - protected ResponseListener listener; - - // Used to avoid subscription renewals to trigger multiple times because of - // multiple but similar events - private long lastRenewal = 0; - private long renewalDelay = 500; - - // Used to delay method calls when subscription is in progress - protected boolean subscribing = false; - private ArrayList queue = new ArrayList<>(); - private SubscribeListener doneListener; - - /** - * Constructor - * - * @param kuzzleDataCollection Data collection to link - */ - public Room(final Collection kuzzleDataCollection) { - this(kuzzleDataCollection, null); - } - - /** - * This object is the result of a subscription request, allowing to manipulate the subscription itself. - * In Kuzzle, you don't exactly subscribe to a room or a topic but, instead, you subscribe to documents. - * What it means is that, to subscribe, you provide to Kuzzle a set of matching filters. - * Once you have subscribed, if a pub/sub message is published matching your filters, or if a matching stored - * document change (because it is created, updated or deleted), then you'll receive a notification about it. - * - * @param kuzzleDataCollection Data collection to link - * @param options Subscription options - */ - public Room(final Collection kuzzleDataCollection, final RoomOptions options) { - RoomOptions opts = options != null ? options : new RoomOptions(); - - if (kuzzleDataCollection == null) { - throw new IllegalArgumentException("Room: missing dataCollection"); - } - kuzzleDataCollection.getKuzzle().isValid(); - - this.dataCollection = kuzzleDataCollection; - this.kuzzle = kuzzleDataCollection.getKuzzle(); - this.collection = kuzzleDataCollection.getCollection(); - - try { - this.headers = new JSONObject(kuzzleDataCollection.getHeaders().toString()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - - this.subscribeToSelf = opts.isSubscribeToSelf(); - this._volatile = opts.getVolatile(); - this.scope = opts.getScope(); - this.state = opts.getState(); - this.users = opts.getUsers(); - } - - /** - * Returns the number of other subscriptions on that room. - * - * @param listener Response callback listener - */ - public void count(final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Room.count: a callback listener is required"); - } - - // Delays this call until after the subscription is finished - if (!this.isReady()) { - this.queue.add(new Runnable() { - @Override - public void run() { - Room.this.count(listener); - } - }); - return; - } - - if (this.roomId == null) { - throw new IllegalStateException("Room.count: cannot count subscriptions on an inactive room"); - } - - try { - JSONObject data = new JSONObject().put("body", new JSONObject().put("roomId", this.roomId)); - this.kuzzle.addHeaders(data, this.headers); - - this.kuzzle.query(this.dataCollection.makeQueryArgs("realtime", "count"), data, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getInt("count")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * Call after renew. - * - * @param args the args - */ - protected void callAfterRenew(final Object args) { - if (args == null) { - throw new IllegalArgumentException("Room.renew: response required"); - } - - try { - String requestId = ((JSONObject) args).has("requestId") ? ((JSONObject) args).getString("requestId") : null; - - if (((JSONObject) args).getString("type").equals("TokenExpired")) { - Room.this.kuzzle.jwtToken = null; - Room.this.kuzzle.emitEvent(Event.tokenExpired); - } - - if (requestId != null && Room.this.kuzzle.getRequestHistory().containsKey(requestId)) { - if (Room.this.subscribeToSelf) { - listener.onSuccess(new NotificationResponse(kuzzle, (JSONObject) args)); - } - Room.this.kuzzle.getRequestHistory().remove(requestId); - } else { - listener.onSuccess(new NotificationResponse(kuzzle, (JSONObject) args)); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #renew(JSONObject, ResponseListener, SubscribeListener)} - */ - public Room renew(final ResponseListener listener) { - return this.renew(null, listener, null); - } - - /** - * {@link #renew(JSONObject, ResponseListener, SubscribeListener)} - */ - public Room renew(final ResponseListener listener, final SubscribeListener subscribeResponseListener) { - return this.renew(null, listener, subscribeResponseListener); - } - - /** - * Renew the subscription. Force a resubscription using the same filters - * if no new ones are provided. - * Unsubscribes first if this Room was already listening to events. - * - * @param filters Subscription filters, using Kuzzle DSL - * @param listener Response callback listener - * @return this - */ - public Room renew(final JSONObject filters, final ResponseListener listener, final SubscribeListener subscribeResponseListener) { - long now = System.currentTimeMillis(); - - if (listener == null) { - throw new IllegalArgumentException("Room.renew: a callback listener is required"); - } - - // Skip subscription renewal if another one was performed just a moment before - if (this.lastRenewal > 0 && (now - this.lastRenewal) <= this.renewalDelay) { - return this; - } - - if (filters != null) { - this.filters = filters; - } - - /* - If not yet connected, registers itself into the subscriptions list and wait for the - main Kuzzle object to renew subscriptions once online - */ - if (this.kuzzle.state != States.CONNECTED) { - this.listener = listener; - this.doneListener = subscribeResponseListener; - this.kuzzle.addPendingSubscription(this.id, this); - return this; - } - - if (this.subscribing) { - this.queue.add(new Runnable() { - @Override - public void run() { - Room.this.renew(filters, listener, subscribeResponseListener); - } - }); - - return this; - } - - this.unsubscribe(); - this.roomId = null; - this.subscribing = true; - this.listener = listener; - this.doneListener = subscribeResponseListener; - this.kuzzle.addPendingSubscription(this.id, this); - - try { - final Options options = new Options(); - final JSONObject - subscribeQuery = new JSONObject() - .put("body", this.filters) - .put("scope", this.scope.toString().toLowerCase()) - .put("state", this.state.toString().toLowerCase()) - .put("users", this.users.toString().toLowerCase()); - - options.setVolatile(this._volatile); - this.kuzzle.addHeaders(subscribeQuery, this.headers); - - new Thread(new Runnable() { - @Override - public void run() { - try { - Room.this.kuzzle.query(Room.this.dataCollection.makeQueryArgs("realtime", "subscribe"), subscribeQuery, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject args) { - try { - Room.this.kuzzle.deletePendingSubscription(Room.this.id); - Room.this.subscribing = false; - Room.this.lastRenewal = System.currentTimeMillis(); - - JSONObject result = args.getJSONObject("result"); - Room.this.channel = result.getString("channel"); - Room.this.roomId = result.getString("roomId"); - if (subscribeResponseListener != null) { - subscribeResponseListener.done(null, Room.this); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - - Room.this.kuzzle.addSubscription(Room.this.roomId, Room.this.id, Room.this); - - Room.this.kuzzle.addRoom(Room.this.channel, new EventListener() { - @Override - public void trigger(final Object... args) { - callAfterRenew(args[0]); - } - }); - - Room.this.dequeue(); - } - - @Override - public void onError(JSONObject arg) { - Room.this.subscribing = false; - Room.this.queue.clear(); - if (subscribeResponseListener != null) { - subscribeResponseListener.done(arg, null); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }).start(); - - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * Unsubscribes from Kuzzle. - * Stop listening immediately. If there is no listener left on that room, - * sends an unsubscribe request to Kuzzle, once - * pending subscriptions reaches 0, and only if there is still no listener on that room. - * We wait for pending subscriptions to finish to avoid unsubscribing while - * another subscription on that room is - * - * @return this - */ - public Room unsubscribe() { - if (!this.isReady()) { - this.queue.add(new Runnable() { - @Override - public void run() { - Room.this.unsubscribe(); - } - }); - return this; - } - - if (this.roomId == null) { - return this; - } - - try { - final JSONObject data = new JSONObject().put("body", new JSONObject().put("roomId", this.roomId)); - this.kuzzle.addHeaders(data, this.headers); - - this.kuzzle.removeRoom(Room.this.channel); - this.kuzzle.deleteSubscription(this.roomId, this.id); - - if (this.kuzzle.getSubscriptions(this.roomId) == null) { - final String roomId = this.roomId; - if (this.kuzzle.getPendingSubscriptions().isEmpty()) { - this.kuzzle.query(this.dataCollection.makeQueryArgs("realtime", "unsubscribe"), data); - } else { - final Timer timer = new Timer(UUID.randomUUID().toString()); - unsubscribeTask(timer, roomId, data).run(); - } - } - - this.roomId = null; - } - catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * Unsubscribe task timer task. - * - * @param timer the timer - * @param roomId the room id - * @param data the data - * @return the timer task - */ - protected TimerTask unsubscribeTask(final Timer timer, final String roomId, final JSONObject data) { - return new TimerTask() { - @Override - public void run() { - try { - if (Room.this.kuzzle.getPendingSubscriptions().isEmpty()) { - if (Room.this.kuzzle.getSubscriptions(roomId) == null) { - Room.this.kuzzle.query(Room.this.dataCollection.makeQueryArgs("realtime", "unsubscribe"), data); - } - } else { - timer.schedule(unsubscribeTask(timer, roomId, data), 100); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }; - } - - /** - * Linked data collection name getter - * - * @return linked data collection name - */ - public String getCollection() { - return collection; - } - - /** - * Subscription filters getter - * - * @return subscription filters - */ - public JSONObject getFilters() { - return filters; - } - - /** - * Subscription filters setter. - * renew must be called for this to take effect - * - * @param filters New subscription filters - * @return this - */ - public Room setFilters(final JSONObject filters) { - this.filters = filters; - return this; - } - - /** - * headers property getters - * - * @return headers value - */ - public JSONObject getHeaders() { - return this.headers; - } - - /** - * {@link #setHeaders(JSONObject, boolean)} - */ - public Room setHeaders(final JSONObject content) { - return this.setHeaders(content, false); - } - - /** - * Subscription headers setter - * - * @param content - new headers content - * @param replace - default: false = append the content, true = replace - * @return this - */ - public Room setHeaders(final JSONObject content, final boolean replace) { - if (this.headers == null) { - this.headers = new JSONObject(); - } - if (replace) { - this.headers = content; - } else { - if (content != null) { - try { - for (Iterator ite = content.keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - this.headers.put(key, content.get(key)); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - return this; - } - - /** - * Gets volatile data. - * - * @return the volatile property - */ - public JSONObject getVolatile() { - return _volatile; - } - - /** - * Sets volatile metadata. - * - * @param _volatile New volatile data value - * @return this - */ - public Room setVolatile(final JSONObject _volatile) { - this._volatile = _volatile; - return this; - } - - /** - * subscribeToSelf property getter - * - * @return subscribeToSelf property value - */ - public boolean isSubscribeToSelf() { - return subscribeToSelf; - } - - /** - * subscribeToSelf property setter - * - * @param subscribeToSelf New subscribeToSelf value - * @return this - */ - public Room setSubscribeToSelf(final boolean subscribeToSelf) { - this.subscribeToSelf = subscribeToSelf; - return this; - } - - /** - * roomId property getter - * - * @return roomId property value - */ - public String getRoomId() { - return this.roomId; - } - - /** - * listener property getter - * - * @return listener property value - */ - public ResponseListener getListener() { - return this.listener; - } - - /** - * subscribeListener property getter - * @return subscribeListener property value - */ - public SubscribeListener getSubscribeListener() { - return doneListener; - } - - /** - * Runs all queued methods called while subscription was in progress - */ - protected void dequeue() { - if (this.queue.size() > 0) { - ExecutorService threadPool = Executors.newSingleThreadExecutor(); - - for(Runnable r: this.queue) { - threadPool.execute(r); - } - - threadPool.shutdown(); - - try { - threadPool.awaitTermination(1, TimeUnit.SECONDS); - } - catch (InterruptedException e) { - // do nothing - } - finally { - this.queue.clear(); - } - } - } - - private boolean isReady() { - return this.kuzzle.state == States.CONNECTED && !this.subscribing; - } -} diff --git a/src/main/java/io/kuzzle/sdk/core/RoomOptions.java b/src/main/java/io/kuzzle/sdk/core/RoomOptions.java deleted file mode 100644 index 2c1dbafd..00000000 --- a/src/main/java/io/kuzzle/sdk/core/RoomOptions.java +++ /dev/null @@ -1,114 +0,0 @@ -package io.kuzzle.sdk.core; - -import org.json.JSONObject; - -import io.kuzzle.sdk.enums.Scope; -import io.kuzzle.sdk.enums.State; -import io.kuzzle.sdk.enums.Users; - -public class RoomOptions { - - private boolean subscribeToSelf = true; - private JSONObject _volatile = new JSONObject(); - private Scope scope = Scope.ALL; - private State state = State.DONE; - private Users users = Users.NONE; - - /** - * subscribeToSelf property getter - * - * @return subscribeToSelf property value - */ - public boolean isSubscribeToSelf() { - return subscribeToSelf; - } - - /** - * subscribeToSelf property setter - * - * @param subscribeToSelf New subscribeToSelf value - * @return this - */ - public RoomOptions setSubscribeToSelf(boolean subscribeToSelf) { - this.subscribeToSelf = subscribeToSelf; - - return this; - } - - /** - * volatile property getter - * @return volatile property value - */ - public JSONObject getVolatile() { - return _volatile; - } - - /** - * volatile property setter - * @param _volatile New volatile value - * @return this - */ - public RoomOptions setVolatile(JSONObject _volatile) { - this._volatile = _volatile; - - return this; - } - - /** - * scope property getter - * @return scope property value - */ - public Scope getScope() { - return scope; - } - - /** - * scope property setter - * @param scope New scope value - * @return this - */ - public RoomOptions setScope(Scope scope) { - this.scope = scope; - - return this; - } - - /** - * state property getter - * @return state property value - */ - public State getState() { - return state; - } - - /** - * state property setter - * @param state New state value - * @return this - */ - public RoomOptions setState(State state) { - this.state = state; - - return this; - } - - /** - * users property getter - * @return users property value - */ - public Users getUsers() { - return users; - } - - /** - * users property setter - * @param users New users value - * @return this - */ - public RoomOptions setUsers(Users users) { - this.users = users; - - return this; - } - -} diff --git a/src/main/java/io/kuzzle/sdk/enums/CollectionType.java b/src/main/java/io/kuzzle/sdk/enums/CollectionType.java deleted file mode 100644 index 5d7865ea..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/CollectionType.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum CollectionType { - STORED, - REALTIME, - ALL -} diff --git a/src/main/java/io/kuzzle/sdk/enums/Event.java b/src/main/java/io/kuzzle/sdk/enums/Event.java deleted file mode 100644 index 6c9d7fb2..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/Event.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.kuzzle.sdk.enums; - -/** - * The enum Event type. - */ -public enum Event { - disconnected, - reconnected, - connected, - error, - tokenExpired, - loginAttempt, - offlineQueuePush, - offlineQueuePop -} diff --git a/src/main/java/io/kuzzle/sdk/enums/Mode.java b/src/main/java/io/kuzzle/sdk/enums/Mode.java deleted file mode 100644 index 8f3e76a7..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/Mode.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum Mode { - AUTO, MANUAL -} diff --git a/src/main/java/io/kuzzle/sdk/enums/Policies.java b/src/main/java/io/kuzzle/sdk/enums/Policies.java deleted file mode 100644 index 4ace1803..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/Policies.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum Policies { - allowed, denied, conditional -} diff --git a/src/main/java/io/kuzzle/sdk/enums/Scope.java b/src/main/java/io/kuzzle/sdk/enums/Scope.java deleted file mode 100644 index 04b1cc9e..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/Scope.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum Scope { - IN, - OUT, - ALL, - NONE, - UNKNOWN -} diff --git a/src/main/java/io/kuzzle/sdk/enums/State.java b/src/main/java/io/kuzzle/sdk/enums/State.java deleted file mode 100644 index eb66eb1f..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/State.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum State { - PENDING, - ALL, - DONE -} diff --git a/src/main/java/io/kuzzle/sdk/enums/Users.java b/src/main/java/io/kuzzle/sdk/enums/Users.java deleted file mode 100644 index b8f38fa5..00000000 --- a/src/main/java/io/kuzzle/sdk/enums/Users.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.enums; - -public enum Users { - IN, - OUT, - ALL, - NONE -} diff --git a/src/main/java/io/kuzzle/sdk/listeners/EventListener.java b/src/main/java/io/kuzzle/sdk/listeners/EventListener.java deleted file mode 100644 index 9661803e..00000000 --- a/src/main/java/io/kuzzle/sdk/listeners/EventListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.kuzzle.sdk.listeners; - -/** - * The interface Event listener. - */ -public interface EventListener { - - /** - * Trigger. - * - * @param args the args - */ - void trigger(Object ... args); - -} diff --git a/src/main/java/io/kuzzle/sdk/listeners/OnConnectionEvent.java b/src/main/java/io/kuzzle/sdk/listeners/OnConnectionEvent.java deleted file mode 100644 index 3afa1527..00000000 --- a/src/main/java/io/kuzzle/sdk/listeners/OnConnectionEvent.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.listeners; - -import org.json.JSONObject; - -public interface OnConnectionEvent { - void onSuccess(JSONObject success); - void onError(JSONObject error); -} diff --git a/src/main/java/io/kuzzle/sdk/listeners/OnQueryDoneListener.java b/src/main/java/io/kuzzle/sdk/listeners/OnQueryDoneListener.java deleted file mode 100644 index 82412433..00000000 --- a/src/main/java/io/kuzzle/sdk/listeners/OnQueryDoneListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.listeners; - -import org.json.JSONObject; - -public interface OnQueryDoneListener { - void onSuccess(JSONObject response); - void onError(JSONObject error); -} diff --git a/src/main/java/io/kuzzle/sdk/listeners/ResponseListener.java b/src/main/java/io/kuzzle/sdk/listeners/ResponseListener.java deleted file mode 100644 index 3972da96..00000000 --- a/src/main/java/io/kuzzle/sdk/listeners/ResponseListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.kuzzle.sdk.listeners; - -import org.json.JSONObject; - -/** - * The interface Response listener. - */ -public interface ResponseListener { - /** - * On success. - * - * @param response Raw Kuzzle API response - */ - void onSuccess(T response); - - /** - * On error. - * - * @param error Raw Kuzzle API error content - */ - void onError(JSONObject error); -} diff --git a/src/main/java/io/kuzzle/sdk/listeners/SubscribeListener.java b/src/main/java/io/kuzzle/sdk/listeners/SubscribeListener.java deleted file mode 100644 index 48e46105..00000000 --- a/src/main/java/io/kuzzle/sdk/listeners/SubscribeListener.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.kuzzle.sdk.listeners; - -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import io.kuzzle.sdk.core.Room; - -public class SubscribeListener { - private JSONObject error; - private Room room; - private List> cbs = new ArrayList<>(); - - public void onDone(ResponseListener cb) { - if (this.error != null) { - cb.onError(this.error); - } else if (this.room != null) { - cb.onSuccess(this.room); - } else { - this.cbs.add(cb); - } - } - - public SubscribeListener done(JSONObject error, Room room) { - this.error = error; - this.room = room; - - for (ResponseListener cb : cbs) { - if (this.error != null) { - cb.onError(this.error); - } else if (this.room != null) { - cb.onSuccess(this.room); - } - } - return this; - } - - public JSONObject getError() { - return error; - } - - public Room getRoom() { - return room; - } -} diff --git a/src/main/java/io/kuzzle/sdk/responses/KuzzleList.java b/src/main/java/io/kuzzle/sdk/responses/KuzzleList.java deleted file mode 100644 index 19103c79..00000000 --- a/src/main/java/io/kuzzle/sdk/responses/KuzzleList.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.responses; - -import java.util.List; - -public interface KuzzleList { - public List getDocuments(); - public long getTotal(); -} diff --git a/src/main/java/io/kuzzle/sdk/responses/NotificationResponse.java b/src/main/java/io/kuzzle/sdk/responses/NotificationResponse.java deleted file mode 100644 index 522eb911..00000000 --- a/src/main/java/io/kuzzle/sdk/responses/NotificationResponse.java +++ /dev/null @@ -1,142 +0,0 @@ -package io.kuzzle.sdk.responses; - -import org.json.JSONException; -import org.json.JSONObject; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.enums.Scope; -import io.kuzzle.sdk.enums.State; -import io.kuzzle.sdk.enums.Users; - -public class NotificationResponse { - private int status; - private String index; - private String collection; - private String controller; - private String action; - private State state; - private Scope scope; - private Users users; - private JSONObject _volatile; - private String requestId; - private Document document; - private JSONObject result; - - /** - * Response notification representation - * @see SDK Reference - * @param kuzzle Kuzzle instance to attach - * @param object Raw Kuzzle API notification - */ - public NotificationResponse(final Kuzzle kuzzle, final JSONObject object) { - try { - this.status = object.getInt("status"); - this.index = object.getString("index"); - this.collection = object.getString("collection"); - this.controller = object.getString("controller"); - this.action = object.getString("action"); - this.state = (object.isNull("state") ? null : State.valueOf(object.getString("state").toUpperCase())); - this._volatile = object.isNull("volatile") ? new JSONObject() : object.getJSONObject("volatile"); - this.requestId = object.isNull("requestId") ? null : object.getString("requestId"); - this.result = (object.isNull("result") ? null : object.getJSONObject("result")); - this.scope = (object.isNull("scope") ? null : Scope.valueOf(object.getString("scope").toUpperCase())); - this.users = (object.isNull("user") ? null : Users.valueOf(object.getString("user").toUpperCase())); - if (!object.getJSONObject("result").isNull("_source")) { - JSONObject content = object.getJSONObject("result"); - String id = content.getString("_id"); - JSONObject meta = content.isNull("_meta") ? new JSONObject() : content.getJSONObject("_meta"); - content.remove("_id"); - content.remove("_meta"); - this.document = new Document(new Collection(kuzzle, this.collection, this.index), id, content, meta); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * @return Notification status value - */ - public int getStatus() { - return status; - } - - /** - * @return Impacted data index value - */ - public String getIndex() { - return index; - } - - /** - * @return Impacted data collection value - */ - public String getCollection() { - return collection; - } - - /** - * @return Invoked Kuzzle API controller - */ - public String getController() { - return controller; - } - - /** - * @return Executed API controller action - */ - public String getAction() { - return action; - } - - /** - * @return Notification state - */ - public State getState() { - return state; - } - - /** - * @return Notification scope - */ - public Scope getScope() { - return scope; - } - - /** - * @return Notification volatile data - */ - public JSONObject getVolatile() { - return _volatile; - } - - /** - * @return Origin request unique ID - */ - public String getRequestId() { - return requestId; - } - - /** - * @return Notification content - */ - public Document getDocument() { - return document; - } - - /** - * @return Notification raw content - */ - public JSONObject getResult() { - return result; - } - - /** - * @return Notification users state - */ - public Users getUsers() { - return users; - } -} diff --git a/src/main/java/io/kuzzle/sdk/responses/SearchResult.java b/src/main/java/io/kuzzle/sdk/responses/SearchResult.java deleted file mode 100644 index a49eba94..00000000 --- a/src/main/java/io/kuzzle/sdk/responses/SearchResult.java +++ /dev/null @@ -1,191 +0,0 @@ -package io.kuzzle.sdk.responses; - - - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; - -public class SearchResult implements KuzzleList { - private Collection collection; - private long total; - private List documents; - private JSONObject aggregations; - private Options options; - private JSONObject filters; - private long fetchedDocument; - - public SearchResult(Collection collection, long total, List documents) { - this(collection, total, documents, null, new Options(), new JSONObject(), null); - } - - public SearchResult(Collection collection, long total, List documents, JSONObject aggregations) { - this(collection, total, documents, aggregations, new Options(), new JSONObject(), null); - } - - public SearchResult(Collection collection, long total, List documents, JSONObject aggregations, Options options, JSONObject filters) { - this(collection, total, documents, aggregations, options, filters, null); - } - - public SearchResult(Collection collection, long total, List documents, JSONObject aggregations, Options options, JSONObject filters, SearchResult previous) { - this.collection = collection; - this.total = total; - this.documents = documents; - this.aggregations = aggregations; - this.options = options; - this.filters = filters; - this.fetchedDocument = previous != null ? documents.size() + previous.getFetchedDocument() : documents.size(); - } - - /** - * @return Fetched documents list - */ - public List getDocuments() { - return documents; - } - - /** - * @return Total number of fetchable documents - */ - public long getTotal() { - return total; - } - - /** - * @return Search request aggregations parameters - */ - public JSONObject getAggregations() { - return aggregations; - } - - /** - * @return Number of fetched documents so far - */ - public long getFetchedDocument() { - return fetchedDocument; - } - - /** - * @return Parent data collection - */ - public Collection getCollection() { - return collection; - } - - /** - * @return Search request options - */ - public Options getOptions() { - return options; - } - - /** - * @return Search request filters - */ - public JSONObject getFilters() { - return filters; - } - - /** - * Fetches the next batch of documents - * @param listener Response callback listener - */ - public void fetchNext(ResponseListener listener) { - JSONObject filters; - Options options; - - try { - options = new Options(this.options); - } catch (JSONException e) { - throw new RuntimeException(e); - } - options.setPrevious(this); - - // retrieve next results with scroll if original search use it - if (options.getScrollId() != null) { - if (this.fetchedDocument >= this.getTotal()) { - listener.onSuccess(null); - - return; - } - - if (options.getFrom() != null) { - options.setFrom(null); - } - - if (options.getSize() != null) { - options.setSize(null); - } - - this.collection.scroll(options.getScrollId(), options, this.filters, listener); - - return; - } - - // retrieve next results using ES's search_after - if (options.getSize() != null && this.filters.has("sort")) { - if (this.fetchedDocument >= this.getTotal()) { - listener.onSuccess(null); - - return; - } - - if (options.getFrom() != null) { - options.setFrom(null); - } - - try { - JSONArray searchAfter = new JSONArray(); - - for (int i = 0; i < this.filters.getJSONArray("sort").length(); i++) { - Document doc = this.getDocuments().get(this.getDocuments().size() - 1); - searchAfter.put(doc.getContent().get(this.filters.getJSONArray("sort").getJSONObject(i).keys().next())); - } - - this.filters.put("search_after", searchAfter); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - this.collection.search(this.filters, options, listener); - - return; - } - - // retrieve next results with from/size if original search use it - if (options.getFrom() != null && options.getSize() != null) { - try { - filters = new JSONObject(this.filters.toString()); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - options.setFrom(options.getFrom() + options.getSize()); - - if (options.getFrom() >= this.getTotal()) { - listener.onSuccess(null); - - return; - } - - this.collection.search(filters, options, listener); - - return; - } - - JSONObject error; - try { - error = new JSONObject("Unable to retrieve next results from search: missing scrollId or from/size params"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - listener.onError(error); - } -} diff --git a/src/main/java/io/kuzzle/sdk/responses/SecurityDocumentList.java b/src/main/java/io/kuzzle/sdk/responses/SecurityDocumentList.java deleted file mode 100644 index 423f6977..00000000 --- a/src/main/java/io/kuzzle/sdk/responses/SecurityDocumentList.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.kuzzle.sdk.responses; - - -import java.util.List; - -import io.kuzzle.sdk.security.AbstractSecurityDocument; -import io.kuzzle.sdk.util.Scroll; - -public class SecurityDocumentList implements KuzzleList { - private List documents; - private long total; - private Scroll scroll; - - public SecurityDocumentList(List roles, long total, Scroll scroll) { - this.documents = roles; - this.total = total; - this.scroll = scroll; - } - - public SecurityDocumentList(List roles, long total) { - this(roles, total, new Scroll()); - } - - public List getDocuments() { - return documents; - } - - public long getTotal() { - return total; - } - - public Scroll getScroll() { return scroll; } -} diff --git a/src/main/java/io/kuzzle/sdk/responses/TokenValidity.java b/src/main/java/io/kuzzle/sdk/responses/TokenValidity.java deleted file mode 100644 index b86e7992..00000000 --- a/src/main/java/io/kuzzle/sdk/responses/TokenValidity.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.kuzzle.sdk.responses; - -import java.util.Date; - -public class TokenValidity { - private boolean valid; - private String state; - private Date expiresAt; - - public boolean isValid() { - return valid; - } - - public void setValid(boolean valid) { - this.valid = valid; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - public Date getExpiresAt() { - return expiresAt; - } - - public void setExpiresAt(Date expiresAt) { - this.expiresAt = expiresAt; - } -} diff --git a/src/main/java/io/kuzzle/sdk/security/AbstractSecurityDocument.java b/src/main/java/io/kuzzle/sdk/security/AbstractSecurityDocument.java deleted file mode 100644 index bd8032b5..00000000 --- a/src/main/java/io/kuzzle/sdk/security/AbstractSecurityDocument.java +++ /dev/null @@ -1,226 +0,0 @@ -package io.kuzzle.sdk.security; - - - -import org.json.JSONException; -import org.json.JSONObject; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -/** - * Base class for the Role, Profile and User classes - */ -public class AbstractSecurityDocument { - protected final Kuzzle kuzzle; - protected final Security kuzzleSecurity; - protected String deleteActionName; - protected String updateActionName; - public final String id; - public JSONObject content; - public JSONObject meta; - - /** - * Instantiates a new Abstract kuzzle security document. - * - * @param kuzzle Kuzzle instance to link - * @param id Security document unique ID - * @param content Security document content - * @throws JSONException - */ - public AbstractSecurityDocument(final Kuzzle kuzzle, final String id, final JSONObject content, final JSONObject meta) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Cannot initialize with a null ID"); - } - - this.kuzzle = kuzzle; - this.kuzzleSecurity = kuzzle.security; - this.id = id; - - if (content != null) { - setContent(content); - } else { - this.content = new JSONObject(); - } - - if (meta != null) { - this.meta = new JSONObject(meta.toString()); - } - } - - /** - * Sets the content of this object - * - * @param content New content - * @return this - * @throws JSONException - */ - public AbstractSecurityDocument setContent(final JSONObject content) throws JSONException { - if (content == null) { - throw new IllegalArgumentException("AbstractSecurityDocument.setContent: cannot set null content"); - } - - this.content = new JSONObject(content.toString()); - - return this; - } - - /** - * Serializes this object to a plain-old JSON object - * - * @return The serialized version of this object - * @throws JSONException - */ - public JSONObject serialize() throws JSONException { - JSONObject data; - - data = new JSONObject() - .put("_id", this.id) - .put("body", content); - - return data; - } - - /** - * Delete this role/profile/user from Kuzzle - * - * @param options Optional configuration - * @param listener Optional response callback - * @throws JSONException - */ - public void delete(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = new JSONObject().put("_id", this.id); - - if (listener != null) { - this.kuzzle.query(kuzzleSecurity.buildQueryArgs(this.deleteActionName), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getString("_id")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(kuzzleSecurity.buildQueryArgs(this.deleteActionName), data, options); - } - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete(final ResponseListener listener) throws JSONException { - this.delete(null, listener); - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete(final Options options) throws JSONException { - this.delete(options, null); - } - - /** - * {@link #delete(Options, ResponseListener)} - */ - public void delete() throws JSONException { - this.delete(null, null); - } - - /** - * Getter for the "id" property - * - * @return the document id - */ - public String getId() { - return this.id; - } - - /** - * Getter for the "content" property - * - * @return the document content - */ - public JSONObject getContent() { - return this.content; - } - - /** - * Getter for the "meta" property - * - * @return the document metadata - */ - public JSONObject getMeta() { - return this.meta; - } - - /** - * {@link #update(JSONObject, Options, ResponseListener)} - */ - public AbstractSecurityDocument update(final JSONObject content) throws JSONException { - return this.update(content, null, null); - } - - /** - * {@link #update(JSONObject, Options, ResponseListener)} - */ - public AbstractSecurityDocument update(final JSONObject content, final Options options) throws JSONException { - return this.update(content, options, null); - } - - /** - * {@link #update(JSONObject, Options, ResponseListener)} - */ - public AbstractSecurityDocument update(final JSONObject content, final ResponseListener listener) throws JSONException { - return this.update(content, null, listener); - } - - /** - * Perform a partial update on this object - * - * @param content Content used to update the object - * @param options Request optional parameters - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public AbstractSecurityDocument update(final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = new JSONObject() - .put("_id", this.id) - .put("body", content); - - if (listener != null) { - this.kuzzle.query(kuzzleSecurity.buildQueryArgs(this.updateActionName), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject updatedContent = response.getJSONObject("result").getJSONObject("_source"); - AbstractSecurityDocument.this.setContent(updatedContent); - listener.onSuccess(AbstractSecurityDocument.this); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(kuzzleSecurity.buildQueryArgs(this.updateActionName), data, options); - } - - return this; - } -} diff --git a/src/main/java/io/kuzzle/sdk/security/Profile.java b/src/main/java/io/kuzzle/sdk/security/Profile.java deleted file mode 100644 index 1cbded45..00000000 --- a/src/main/java/io/kuzzle/sdk/security/Profile.java +++ /dev/null @@ -1,211 +0,0 @@ -package io.kuzzle.sdk.security; - - - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Arrays; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -/** - * This class handles profiles management in Kuzzle - */ -public class Profile extends AbstractSecurityDocument { - private ArrayList policies = new ArrayList<>(); - - /** - * Instantiates a new Kuzzle profile. - * - * @param kuzzle Kuzzle instance to attach - * @param id Profile unique ID - * @param content Profile content - * @param meta Profile metadata - * @throws JSONException - */ - public Profile(final Kuzzle kuzzle, final String id, final JSONObject content, final JSONObject meta) throws JSONException { - super(kuzzle, id, null, meta); - this.deleteActionName = "deleteProfile"; - this.updateActionName = "updateProfile"; - - if (content != null) { - this.content = new JSONObject(content.toString()); - - if (content.has("policies")) { - JSONArray arr = content.getJSONArray("policies"); - - for (int i = 0; i < arr.length(); i++) { - this.policies.add(arr.getJSONObject(i)); - } - - this.content.remove("policies"); - } - } - } - - /** - * Save this profile in Kuzzle - * - * @param options Request optional arguments - * @param listener Callback listener - * @return this - * @throws JSONException - */ - public Profile save(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data; - - if (this.policies.size() == 0) { - throw new IllegalArgumentException("Cannot save the profile " + this.id + ": no policy defined"); - } - - data = this.serialize(); - - if (listener != null) { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createOrReplaceProfile"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(Profile.this); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createOrReplaceProfile"), data, options); - } - - return this; - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Profile save(final ResponseListener listener) throws JSONException { - return this.save(null, listener); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Profile save(final Options options) throws JSONException { - return this.save(options, null); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Profile save() throws JSONException { - return this.save(null, null); - } - - /** - * Add a new role to the list of allowed roles of this profile - * - * @param policy Policy to add to this profile - * @return this - * @throws IllegalArgumentException - */ - public Profile addPolicy(final JSONObject policy) throws IllegalArgumentException { - if (!policy.has("roleId")) { - throw new IllegalArgumentException("The policy must have, at least, a roleId set."); - } - - this.policies.add(policy); - return this; - } - - /** - * Add a new policy to the list of policies of this profile via its roleId - * - * @param roleId Name of the role to add to this profile - * @return this - */ - public Profile addPolicy(final String roleId) { - JSONObject policy = new JSONObject(); - try { - policy.put("roleId", roleId); - } catch (JSONException e) { - throw new RuntimeException(e); - } - this.policies.add(policy); - return this; - } - - /** - * Replace the current policies list with a new one - * - * @param policies New policies list - * @return this - * @throws IllegalArgumentException - */ - public Profile setPolicies(final JSONObject[] policies) throws IllegalArgumentException { - for(JSONObject policy : policies) { - if (!policy.has("roleId")) { - throw new IllegalArgumentException("All pocicies must have at least a roleId set."); - } - } - - this.policies = new ArrayList<>(Arrays.asList(policies)); - - return this; - } - - /** - * Replace the current policies list with a new one via its rolesIds - * - * @param roleIds New roles identifiers list - * @return this - */ - public Profile setPolicies(final String[] roleIds) { - this.policies.clear(); - - try { - for (String roleId : roleIds) { - this.policies.add(new JSONObject().put("roleId", roleId)); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * Serialize the content of this object to a JSON Object - * @return a serialized version of this object - * @throws JSONException - */ - public JSONObject serialize() throws JSONException { - JSONObject - data = new JSONObject(), - content = new JSONObject(this.content.toString()); - - if (this.policies.size() > 0) { - content.put("policies", new JSONArray(this.policies)); - } - - data - .put("_id", this.id) - .put("body", content); - - return data; - } - - /** - * Return the list of the policies assigned to this profile - * - * @return a JSONArray of policies objects - */ - public JSONObject[] getPolicies() { - return this.policies.toArray(new JSONObject[0]); - } -} diff --git a/src/main/java/io/kuzzle/sdk/security/Role.java b/src/main/java/io/kuzzle/sdk/security/Role.java deleted file mode 100644 index cde4b343..00000000 --- a/src/main/java/io/kuzzle/sdk/security/Role.java +++ /dev/null @@ -1,83 +0,0 @@ -package io.kuzzle.sdk.security; - - - -import org.json.JSONException; -import org.json.JSONObject; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -/** - * This class handles roles management in Kuzzle - */ -public class Role extends AbstractSecurityDocument { - /** - * Instantiates a new Kuzzle role. - * - * @param kuzzle Kuzzle instance to attach - * @param id Role unique identifier - * @param content Role content - * @param meta Role metadata - * @throws JSONException - */ - public Role(final Kuzzle kuzzle, final String id, final JSONObject content, final JSONObject meta) throws JSONException { - super(kuzzle, id, content, meta); - this.deleteActionName = "deleteRole"; - this.updateActionName = "updateRole"; - } - - /** - * Save this role in Kuzzle - * - * @param options Request optional configuration - * @param listener Optional callback listener - * @return this - * @throws JSONException - */ - public Role save(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = this.serialize(); - - if (listener != null) { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createOrReplaceRole"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(Role.this); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createOrReplaceRole"), data, options); - } - - return this; - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Role save(final ResponseListener listener) throws JSONException { - return this.save(null, listener); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Role save(final Options options) throws JSONException { - return this.save(options, null); - } - - /** - * {@link #save(Options, ResponseListener)} - */ - public Role save() throws JSONException { - return this.save(null, null); - } -} diff --git a/src/main/java/io/kuzzle/sdk/security/Security.java b/src/main/java/io/kuzzle/sdk/security/Security.java deleted file mode 100644 index d7bae736..00000000 --- a/src/main/java/io/kuzzle/sdk/security/Security.java +++ /dev/null @@ -1,1847 +0,0 @@ -package io.kuzzle.sdk.security; - - - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Arrays; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Policies; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.util.Scroll; - -/** - * Kuzzle security API - */ -public class Security { - private final Kuzzle kuzzle; - - /** - * Instantiates a new Kuzzle security instance - * - * @param kuzzle Kuzzle instance to attach - */ - public Security(final Kuzzle kuzzle) { - this.kuzzle = kuzzle; - } - - /** - * Helper function meant to easily build the first Kuzzle.query() argument - * - * @param action Security controller action name - * @return Kuzzle.query() 1st argument object - * @throws JSONException - */ - protected Kuzzle.QueryArgs buildQueryArgs(final String controller, final String action) throws JSONException { - io.kuzzle.sdk.core.Kuzzle.QueryArgs args = new io.kuzzle.sdk.core.Kuzzle.QueryArgs(); - args.action = action; - args.controller = "security"; - - if (controller != null) { - args.controller = controller; - } - return args; - } - - protected Kuzzle.QueryArgs buildQueryArgs(final String action) throws JSONException { - return buildQueryArgs(null, action); - } - - /** - * Retrieves a single Role using its unique Role ID - * - * @param id Unique role ID - * @param options Optional query arguments - * @param listener Response callback listener - */ - public void fetchRole(final String id, Options options, final ResponseListener listener) { - JSONObject data; - - if (id == null) { - throw new IllegalArgumentException("Security.fetchRole: a role ID is required"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.fetchRole: a listener is required"); - } - - try { - data = new JSONObject().put("_id", id); - this.kuzzle.query(buildQueryArgs("getRole"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new Role(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #fetchRole(String, Options, ResponseListener)} - */ - public void fetchRole(final String id, final ResponseListener listener) { - fetchRole(id, null, listener); - } - - - /** - * Executes a search on roles using a set of filters - * - * @param filters Search filters (see ElasticSearch filters) - * @param options Optional query arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void searchRoles(final JSONObject filters, final Options options, final ResponseListener listener) throws JSONException { - if (filters == null) { - throw new IllegalArgumentException("Security.searchRoles: filters cannot be null"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.searchRoles: a callback listener is required"); - } - - JSONObject data = new JSONObject().put("body", filters); - - this.kuzzle.query(buildQueryArgs("searchRoles"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - JSONArray documents = result.getJSONArray("hits"); - int documentsLength = documents.length(); - ArrayList roles = new ArrayList<>(); - - for (int i = 0; i < documentsLength; i++) { - JSONObject document = documents.getJSONObject(i); - roles.add(new Role(Security.this.kuzzle, document.getString("_id"), document.getJSONObject("_source"), document.getJSONObject("_meta"))); - } - - listener.onSuccess(new SecurityDocumentList(roles, result.getLong("total"))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - - /** - * {@link #searchRoles(JSONObject, Options, ResponseListener)} - */ - public void searchRoles(final JSONObject filters, final ResponseListener listener) throws JSONException { - searchRoles(filters, null, listener); - } - - /** - * Create a new role in Kuzzle. - * If the same role already exists: throw an error by default - * (see the replaceIfExist request optional argument) - * - * @param id New role ID - * @param content New role rights definitions - * @param options Request optional parameters - * @param listener Response callback listener - * @throws JSONException - */ - public void createRole(final String id, final JSONObject content, Options options, final ResponseListener listener) throws JSONException { - String action = "createRole"; - - if (id == null || content == null) { - throw new IllegalArgumentException("Security.createRole: cannot create a role without an ID or a content"); - } - - JSONObject data = new JSONObject().put("_id", id).put("body", content); - - if (options != null && options.isReplaceIfExist()) { - action = "createOrReplaceRole"; - } - - if (listener != null) { - this.kuzzle.query(buildQueryArgs(action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new Role(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs(action), data, options); - } - } - - /** - * {@link #createRole(String, JSONObject, Options, ResponseListener)} - */ - public void createRole(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - createRole(id, content, null, listener); - } - - /** - * {@link #createRole(String, JSONObject, Options, ResponseListener)} - */ - public void createRole(final String id, final JSONObject content, Options options) throws JSONException { - createRole(id, content, options, null); - } - - /** - * {@link #createRole(String, JSONObject, Options, ResponseListener)} - */ - public void createRole(final String id, final JSONObject content) throws JSONException { - createRole(id, content, null, null); - } - - /** - * Delete a role from Kuzzle - * - * @param id ID of the role to delete - * @param options Request optional arguments - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security deleteRole(final String id, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.deleteRole: cannot delete role without an ID"); - } - - JSONObject data = new JSONObject().put("_id", id); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("deleteRole"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getString("_id")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("deleteRole"), data, options); - } - - return this; - } - - /** - * {@link #deleteRole(String, Options, ResponseListener)} - */ - public Security deleteRole(final String id, final ResponseListener listener) throws JSONException { - return deleteRole(id, null, listener); - } - - /** - * {@link #deleteRole(String, Options, ResponseListener)} - */ - public Security deleteRole(final String id, final Options options) throws JSONException { - return deleteRole(id, options, null); - } - - /** - * {@link #deleteRole(String, Options, ResponseListener)} - */ - public Security deleteRole(final String id) throws JSONException { - return deleteRole(id, null, null); - } - - /** - * Update a role's content - * - * @param id ID of the role to update - * @param content Role content to update - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security updateRole(final String id, final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.updateRole: cannot update role without an ID"); - } - - JSONObject data = new JSONObject().put("_id", id); - data.put("body", content); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("updateRole"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(new Role(Security.this.kuzzle, response.getJSONObject("result").getString("_id"), response.getJSONObject("result").getJSONObject("_source"), response.getJSONObject("result").getJSONObject("_meta"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("updateRole"), data, options); - } - - return this; - } - - /** - * {@link #updateRole(String, JSONObject, Options, ResponseListener)} - */ - public Security updateRole(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - return updateRole(id, content, null, listener); - } - - /** - * {@link #updateRole(String, JSONObject, Options, ResponseListener)} - */ - public Security updateRole(final String id, final JSONObject content, final Options options) throws JSONException { - return updateRole(id, content, options, null); - } - - /** - * {@link #updateRole(String, JSONObject, Options, ResponseListener)} - */ - public Security updateRole(final String id, final JSONObject content) throws JSONException { - return updateRole(id, content, null, null); - } - - /** - * Instantiate a new Role object. - * Does not automatically create it in Kuzzle - * - * @param id Role unique identifier - * @param content Role content - * @param meta Role metadata - * @return new Role object - * @throws JSONException - */ - public Role role(final String id, final JSONObject content, final JSONObject meta) throws JSONException { - return new Role(this.kuzzle, id, content, meta); - } - - /** - * {@link #role(String, JSONObject, JSONObject)} - */ - public Role role(final String id, final JSONObject content) throws JSONException { - return new Role(this.kuzzle, id, content, null); - } - - /** - * {@link #role(String, JSONObject, JSONObject)} - */ - public Role role(final String id) throws JSONException { - return new Role(this.kuzzle, id, null, null); - } - - /** - * Get a specific profile from kuzzle - * - * @param id ID of the profile to retrieve - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void fetchProfile(final String id, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.fetchProfile: cannot get 'null' profile"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.fetchProfile: a listener callback is required"); - } - - JSONObject data = new JSONObject().put("_id", id); - - this.kuzzle.query(buildQueryArgs("getProfile"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - JSONArray formattedPolicies = new JSONArray(); - JSONArray policies = result.getJSONObject("_source").getJSONArray("policies"); - - for (int i = 0; i < policies.length(); i++) { - JSONObject formattedPolicy = new JSONObject() - .put("roleId", policies.getJSONObject(i).getString("roleId")); - if (((JSONObject) policies.get(i)).has("restrictedTo")) { - formattedPolicy.put("restrictedTo", policies.getJSONObject(i).getJSONArray("restrictedTo")); - } - if (((JSONObject) policies.get(i)).has("allowInternalIndex")) { - formattedPolicy.put("allowInternalIndex", policies.getJSONObject(i).getBoolean("allowInternalIndex")); - } - formattedPolicies.put(formattedPolicy); - } - - result.getJSONObject("_source").remove("policies"); - result.getJSONObject("_source").put("policies", formattedPolicies); - - listener.onSuccess(new Profile(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - - /** - * {@link #fetchProfile(String, Options, ResponseListener)} - */ - public void fetchProfile(final String id, final ResponseListener listener) throws JSONException { - fetchProfile(id, null, listener); - } - - /** - * Executes a search on profiles according to a set of filters - * - * @param filters Search filters - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void searchProfiles(JSONObject filters, final Options options, final ResponseListener listener) throws JSONException { - if (filters == null) { - throw new IllegalArgumentException("Security.searchProfiles: cannot perform a search on null filters"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.searchProfiles: a listener callback is required"); - } - - JSONObject data = new JSONObject().put("body", filters); - - this.kuzzle.query(buildQueryArgs("searchProfiles"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - JSONArray documents = result.getJSONArray("hits"); - int documentsLength = documents.length(); - ArrayList profiles = new ArrayList<>(); - - for (int i = 0; i < documentsLength; i++) { - JSONObject document = documents.getJSONObject(i); - profiles.add(new Profile(Security.this.kuzzle, document.getString("_id"), document.getJSONObject("_source"), document.getJSONObject("_meta"))); - } - - Scroll scroll = new Scroll(); - - if (result.has("scrollId")) { - scroll.setScrollId(result.getString("scrollId")); - } - - listener.onSuccess(new SecurityDocumentList(profiles, result.getLong("total"), scroll)); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - - /** - * {@link #searchProfiles(JSONObject, Options, ResponseListener)} - */ - public void searchProfiles(JSONObject filters, final ResponseListener listener) throws JSONException { - searchProfiles(filters, null, listener); - } - - /** - * Create a new profile in Kuzzle. - * Throws an error if the profile already exists, unless - * "replaceIfExists" is set to true in request options - * - * @param id ID of the new profile - * @param policies List of policies attached to the new profile - * @param options Request optional arguments - * @param listener Callback lisener - * @throws JSONException - */ - public void createProfile(final String id, final JSONObject[] policies, final Options options, final ResponseListener listener) throws JSONException { - String action = "createProfile"; - - if (id == null || policies == null) { - throw new IllegalArgumentException("Security.createProfile: cannot create a profile with null ID or policies"); - } - - JSONObject data = new JSONObject() - .put("_id", id) - .put("body", new JSONObject().put("policies", new JSONArray(Arrays.asList(policies)))); - - if (options != null && options.isReplaceIfExist()) { - action = "createOrReplaceProfile"; - } - - if (listener != null) { - this.kuzzle.query(buildQueryArgs(action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new Profile(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs(action), data, options); - } - } - - /** - * {@link #createProfile(String, JSONObject[], Options, ResponseListener)} - */ - public void createProfile(final String id, final JSONObject[] policies, final Options options) throws JSONException { - createProfile(id, policies, options, null); - } - - /** - * {@link #createProfile(String, JSONObject[], Options, ResponseListener)} - */ - public void createProfile(final String id, final JSONObject[] policies, final ResponseListener listener) throws JSONException { - createProfile(id, policies, null, listener); - } - - /** - * {@link #createProfile(String, JSONObject[], Options, ResponseListener)} - */ - public void createProfile(final String id, final JSONObject[] policies) throws JSONException { - createProfile(id, policies, null, null); - } - - /** - * Delete a profile from Kuzzle - * - * @param id ID of the profile to delete - * @param options Request optional arguments - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security deleteProfile(final String id, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.deleteProfile: cannot delete a profile with ID null"); - } - - JSONObject data = new JSONObject().put("_id", id); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("deleteProfile"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getString("_id")); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("deleteProfile"), data, options); - } - - return this; - } - - /** - * {@link #deleteProfile(String, Options, ResponseListener)} - */ - public Security deleteProfile(final String id, final ResponseListener listener) throws JSONException { - return deleteProfile(id, null, listener); - } - - /** - * {@link #deleteProfile(String, Options, ResponseListener)} - */ - public Security deleteProfile(final String id, final Options options) throws JSONException { - return deleteProfile(id, options, null); - } - - /** - * {@link #deleteProfile(String, Options, ResponseListener)} - */ - public Security deleteProfile(final String id) throws JSONException { - return deleteProfile(id, null, null); - } - - /** - * Returns the next batch of searched profiles with scroll - * - * @param scroll Scroll object obtained doing a scroll search - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void scrollProfiles(final Scroll scroll, final Options options, final ResponseListener listener) throws JSONException { - JSONObject request; - - try { - request = new JSONObject().put("body", new JSONObject()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - if (scroll.getScrollId() == null) { - throw new IllegalArgumentException("Security.scrollProfiles: scrollId is required"); - } - - options.setScrollId(scroll.getScrollId()); - - try { - this.kuzzle.query(buildQueryArgs("scrollProfiles"), request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - JSONArray hits = object.getJSONObject("result").getJSONArray("hits"); - ArrayList profiles = new ArrayList<>(); - - for (int i = 0; i < hits.length(); i++) { - JSONObject hit = hits.getJSONObject(i); - Profile profile = new Profile(Security.this.kuzzle, hit.getString("_id"), hit.getJSONObject("_source"), hit.getJSONObject("_meta")); - - profiles.add(profile); - } - - SecurityDocumentList response = new SecurityDocumentList(profiles, hits.length(), scroll); - - listener.onSuccess(response); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #scrollProfiles(Scroll, Options, ResponseListener)} - */ - public void scrollProfiles(Scroll scroll, final ResponseListener listener) throws JSONException { - this.scrollProfiles(scroll, new Options(), listener); - } - - /** - * Update a profile's content - * - * @param id ID of the profile to update - * @param policies List of policies to apply to this profile - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security updateProfile(final String id, final JSONObject[] policies, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.updateProfile: cannot update a profile with ID null"); - } - - JSONObject data = new JSONObject().put("_id", id); - data.put("body", new JSONObject().put("policies", new JSONArray(Arrays.asList(policies)))); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("updateProfile"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(new Profile(Security.this.kuzzle, response.getJSONObject("result").getString("_id"), response.getJSONObject("result").getJSONObject("_source"), response.getJSONObject("result").getJSONObject("_meta"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("updateProfile"), data, options); - } - - return this; - } - - /** - * {@link #updateProfile(String, JSONObject[], Options, ResponseListener)} - */ - public Security updateProfile(final String id, final JSONObject[] policies, final Options options) throws JSONException { - return updateProfile(id, policies, options, null); - } - - /** - * {@link #updateProfile(String, JSONObject[], Options, ResponseListener)} - */ - public Security updateProfile(final String id, final JSONObject[] policies, final ResponseListener listener) throws JSONException { - return this.updateProfile(id, policies, null, listener); - } - - /** - * {@link #updateProfile(String, JSONObject[], Options, ResponseListener)} - */ - public Security updateProfile(final String id, final JSONObject[] policies) throws JSONException { - return updateProfile(id, policies, null, null); - } - - /** - * Instantiate a new Profile object. - * Does not create it in Kuzzle. - * - * @param id Profile unique identifier - * @param content Profile content - * @param meta Profile metadata - * @return new Profile object - * @throws JSONException - */ - public Profile profile(final String id, final JSONObject content, final JSONObject meta) throws JSONException { - return new Profile(this.kuzzle, id, content, meta); - } - - /** - * {@link #profile(String, JSONObject, JSONObject)} - */ - public Profile profile(final String id, final JSONObject content) throws JSONException { - return new Profile(this.kuzzle, id, content, null); - } - - /** - * {@link #profile(String, JSONObject, JSONObject)} - */ - public Profile profile(final String id) throws JSONException { - return new Profile(this.kuzzle, id, null, null); - } - - /** - * Get a specific user from kuzzle using its unique ID - * - * @param id User ID to retrieve - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void fetchUser(final String id, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.fetchUser: cannot get user with ID null"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.fetchUser: a callback listener is required"); - } - - JSONObject data = new JSONObject().put("_id", id); - - this.kuzzle.query(buildQueryArgs("getUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new User(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - - /** - * {@link #fetchUser(String, Options, ResponseListener)} - */ - public void fetchUser(final String id, final ResponseListener listener) throws JSONException { - fetchUser(id, null, listener); - } - - /** - * Replaces an existing user in Kuzzle. - * The new content must contain a "profileIds" attribute, an array - * listing the attached profiles for this user - * - * @param id ID of the user to replace - * @param content New user content - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void replaceUser(final String id, final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.replaceUser: cannot replace user without an ID"); - } - - String action = "replaceUser"; - - JSONObject data = new JSONObject().put("_id", id).put("body", content); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs(action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new User(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs(action), data, options); - } - } - - /** - * {@link #replaceUser(String, JSONObject, Options, ResponseListener)} - */ - public void replaceUser(final String id, final JSONObject content, final Options options) throws JSONException { - replaceUser(id, content, options, null); - } - - /** - * {@link #replaceUser(String, JSONObject, Options, ResponseListener)} - */ - public void replaceUser(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - replaceUser(id, content, null, listener); - } - - /** - * {@link #replaceUser(String, JSONObject, Options, ResponseListener)} - */ - public void replaceUser(final String id, final JSONObject content) throws JSONException { - replaceUser(id, content, null, null); - } - - /** - * Searches users using a set of filters - * - * @param filters Search filters - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void searchUsers(JSONObject filters, final Options options, final ResponseListener listener) throws JSONException { - - if (filters == null) { - throw new IllegalArgumentException("Security.searchUsers: cannot perform a search with null filters"); - } - - if (listener == null) { - throw new IllegalArgumentException("Security.searchUsers: a callback listener is required"); - } - - JSONObject data = new JSONObject().put("body", filters); - - this.kuzzle.query(buildQueryArgs("searchUsers"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - JSONArray documents = result.getJSONArray("hits"); - int documentsLength = documents.length(); - ArrayList users = new ArrayList<>(); - - for (int i = 0; i < documentsLength; i++) { - JSONObject document = documents.getJSONObject(i); - users.add(new User(Security.this.kuzzle, document.getString("_id"), document.getJSONObject("_source"), document.getJSONObject("_meta"))); - } - - Scroll scroll = new Scroll(); - - if (result.has("scrollId")) { - scroll.setScrollId(result.getString("scrollId")); - } - - listener.onSuccess(new SecurityDocumentList(users, result.getLong("total"), scroll)); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - - /** - * {@link #searchUsers(JSONObject, Options, ResponseListener)} - */ - public void searchUsers(JSONObject filters, final ResponseListener listener) throws JSONException { - searchUsers(filters, null, listener); - } - - /** - * Create a new user in Kuzzle. - * - * @param id ID of the user to create - * @param content User content - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void createUser(final String id, final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - String action = "createUser"; - if (id == null || content == null) { - throw new IllegalArgumentException("Security.createUser: cannot create a user with a null ID or content"); - } - - JSONObject data = new JSONObject().put("_id", id).put("body", content); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs(action), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new User(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs(action), data, options); - } - } - - /** - * {@link #createUser(String, JSONObject, Options, ResponseListener)} - */ - public void createUser(final String id, final JSONObject content, final Options options) throws JSONException { - createUser(id, content, options, null); - } - - /** - * {@link #createUser(String, JSONObject, Options, ResponseListener)} - */ - public void createUser(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - createUser(id, content, null, listener); - } - - /** - * {@link #createUser(String, JSONObject, Options, ResponseListener)} - */ - public void createUser(final String id, final JSONObject content) throws JSONException { - createUser(id, content, null, null); - } - - /** - * Create a new restricted user in Kuzzle. - * - * This function will create a new user. It is not usable to update an existing user. - * This function allows anonymous users to create a "restricted" user with predefined rights. - * - * @param id ID of the user to create - * @param content New user content - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void createRestrictedUser(final String id, final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - if (id == null || content == null) { - throw new IllegalArgumentException("Security.createRestrictedUser: cannot create a user with a null ID or content"); - } - - if (content.has("profileIds")) { - throw new IllegalArgumentException("Security.createRestrictedUser: cannot provide profileIds"); - } - - JSONObject data = new JSONObject().put("_id", id).put("body", content); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("createRestrictedUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONObject result = response.getJSONObject("result"); - listener.onSuccess(new User(Security.this.kuzzle, result.getString("_id"), result.getJSONObject("_source"), result.getJSONObject("_meta"))); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("createRestrictedUser"), data, options); - } - } - - /** - * {@link #createRestrictedUser(String, JSONObject, Options, ResponseListener)} - */ - public void createRestrictedUser(final String id, final JSONObject content, final Options options) throws JSONException { - createRestrictedUser(id, content, options, null); - } - - /** - * {@link #createRestrictedUser(String, JSONObject, Options, ResponseListener)} - */ - public void createRestrictedUser(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - createRestrictedUser(id, content, null, listener); - } - - /** - * {@link #createRestrictedUser(String, JSONObject, Options, ResponseListener)} - */ - public void createRestrictedUser(final String id, final JSONObject content) throws JSONException { - createRestrictedUser(id, content, null, null); - } - - /** - * Delete a user from Kuzzle - * - * @param id ID of the user to delete - * @param options Request optional arguments - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security deleteUser(final String id, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.deleteUser: cannot delete user with ID null"); - } - - JSONObject data = new JSONObject().put("_id", id); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("deleteUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result").getString("_id")); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("deleteUser"), data, options); - } - - return this; - } - - /** - * {@link #deleteUser(String, Options, ResponseListener)} - */ - public Security deleteUser(final String id, final Options options) throws JSONException { - return deleteUser(id, options, null); - } - - /** - * {@link #deleteUser(String, Options, ResponseListener)} - */ - public Security deleteUser(final String id, final ResponseListener listener) throws JSONException { - return deleteUser(id, null, listener); - } - - /** - * {@link #deleteUser(String, Options, ResponseListener)} - */ - public Security deleteUser(final String id) throws JSONException { - return deleteUser(id, null, null); - } - - /** - * Returns the next batch of searched users - * - * @param scroll Scroll object, obtained using a scroll search - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void scrollUsers(final Scroll scroll, final Options options, final ResponseListener listener) throws JSONException { - JSONObject request; - - try { - request = new JSONObject().put("body", new JSONObject()); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - - if (listener == null) { - throw new IllegalArgumentException("listener cannot be null"); - } - - if (scroll.getScrollId() == null) { - throw new IllegalArgumentException("Security.scrollUsers: scrollId is required"); - } - - options.setScrollId(scroll.getScrollId()); - - try { - this.kuzzle.query(buildQueryArgs("scrollUsers"), request, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - try { - JSONArray hits = object.getJSONObject("result").getJSONArray("hits"); - ArrayList users = new ArrayList<>(); - - for (int i = 0; i < hits.length(); i++) { - JSONObject hit = hits.getJSONObject(i); - User user = new User(Security.this.kuzzle, hit.getString("_id"), hit.getJSONObject("_source"), hit.getJSONObject("_meta")); - - users.add(user); - } - - SecurityDocumentList response = new SecurityDocumentList(users, hits.length(), scroll); - - listener.onSuccess(response); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #scrollUsers(Scroll, Options, ResponseListener)} - */ - public void scrollUsers(Scroll scroll, final ResponseListener listener) throws JSONException { - this.scrollUsers(scroll, new Options(), listener); - } - - /** - * Update a user. - * - * @param id ID of the user to update - * @param content User content to update - * @param options Request options - * @param listener Response callback listener - * @return this - * @throws JSONException - */ - public Security updateUser(final String id, final JSONObject content, final Options options, final ResponseListener listener) throws JSONException { - if (id == null) { - throw new IllegalArgumentException("Security.updateUser: cannot update user without an ID"); - } - - JSONObject data = new JSONObject().put("_id", id); - data.put("body", content); - - if (listener != null) { - this.kuzzle.query(buildQueryArgs("updateUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(new User(Security.this.kuzzle, response.getJSONObject("result").getString("_id"), response.getJSONObject("result").getJSONObject("_source"), response.getJSONObject("result").getJSONObject("_meta"))); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(buildQueryArgs("updateUser"), data, options); - } - - return this; - } - - /** - * {@link #updateUser(String, JSONObject, Options, ResponseListener)} - */ - public Security updateUser(final String id, final JSONObject content, final ResponseListener listener) throws JSONException { - return updateUser(id, content, null, listener); - } - - /** - * {@link #updateUser(String, JSONObject, Options, ResponseListener)} - */ - public Security updateUser(final String id, final JSONObject content, final Options options) throws JSONException { - return updateUser(id, content, options, null); - } - - /** - * {@link #updateUser(String, JSONObject, Options, ResponseListener)} - */ - public Security updateUser(final String id, final JSONObject content) throws JSONException { - return updateUser(id, content, null, null); - } - - /** - * Instantiate a new User object - * Does not create it in Kuzzle - * - * @param id User unique identifier - * @param content User content - * @param meta User metadata - * @return new User object - * @throws JSONException - */ - public User user(final String id, final JSONObject content, final JSONObject meta) throws JSONException { - return new User(this.kuzzle, id, content, meta); - } - - /** - * {@link #user(String, JSONObject, JSONObject)} - */ - public User user(final String id, final JSONObject content) throws JSONException { - return new User(this.kuzzle, id, content, null); - } - - /** - * {@link #user(String, JSONObject, JSONObject)} - */ - public User user(final String id) throws JSONException { - return new User(this.kuzzle, id, null, null); - } - - /** - * {@link #isActionAllowed(JSONObject[], String, String, String, String)} - */ - public Policies isActionAllowed(final JSONObject[] policies, final String controller, final String action) { - return this.isActionAllowed(policies, controller, action, null, null); - } - - /** - * {@link #isActionAllowed(JSONObject[], String, String, String, String)} - */ - public Policies isActionAllowed(final JSONObject[] policies, final String controller, final String action, final String index) { - return this.isActionAllowed(policies, controller, action, index, null); - } - - /** - * Tells whether an action is allowed, denied or conditional based on the rights - * policies provided as the first argument. An action is defined as a couple of - * action and controller (required), plus a data index and a collection (optional). - * - * @param policies List of policies containing the current authorizations - * @param controller Kuzzle API Controller - * @param action Controller action - * @param index Data index - * @param collection Data collection - * @return action authorization status - */ - public Policies isActionAllowed(final JSONObject[] policies, final String controller, final String action, final String index, final String collection) { - if (policies == null) { - throw new IllegalArgumentException("Security.isActionAllowed: policies are mandatory."); - } - if (controller == null || controller.isEmpty()) { - throw new IllegalArgumentException("Security.isActionAllowed: controller is mandatory."); - } - if (action == null || action.isEmpty()) { - throw new IllegalArgumentException("Security.isActionAllowed: action is mandatory."); - } - - JSONObject[] filteredPolicies; - try { - filteredPolicies = filterPolicy(policies, "controller", controller); - filteredPolicies = filterPolicy(filteredPolicies, "action", action); - filteredPolicies = filterPolicy(filteredPolicies, "index", index); - filteredPolicies = filterPolicy(filteredPolicies, "collection", collection); - - for (JSONObject filteredPolicy : filteredPolicies) { - if (filteredPolicy.getString("value").equals(Policies.allowed.toString())) { - return Policies.allowed; - } - } - - for (JSONObject filteredPolicy : filteredPolicies) { - if (filteredPolicy.getString("value").equals(Policies.conditional.toString())) { - return Policies.conditional; - } - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return Policies.denied; - } - - private JSONObject[] filterPolicy(final JSONObject[] policies, final String attr, final String attrInput) throws JSONException { - ArrayList filteredPolicies = new ArrayList<>(); - - for (JSONObject policy : policies) { - String attrObject = policy.getString(attr); - if (attrObject.equals(attrInput) || attrObject.equals("*")) { - filteredPolicies.add(policy); - } - } - return filteredPolicies.toArray(new JSONObject[0]); - } - - /** - * {@link #getUserRights(String, Options, ResponseListener)} - */ - public Security getUserRights(final String id, final ResponseListener listener) { - return getUserRights(id, null, listener); - } - - /** - * Gets the rights array of a given user. - * - * @param id User ID to retrieve the rights from - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Security getUserRights(final String id, final Options options, final ResponseListener listener) { - if (id == null || id.isEmpty()) { - throw new IllegalArgumentException("Security.getUserRights: id is mandatory."); - } - if (listener == null) { - throw new IllegalArgumentException("Security.getUserRights: listener is mandatory."); - } - try { - JSONObject data = new JSONObject() - .put("_id", id); - kuzzle.query(buildQueryArgs("getUserRights"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray arr = response.getJSONObject("result").getJSONArray("hits"); - JSONObject[] rights = new JSONObject[arr.length()]; - - for (int i = 0; i < arr.length(); i++) { - rights[i] = arr.getJSONObject(i); - } - listener.onSuccess(rights); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - /** - * {@link #createCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security createCredentials(final String strategy, final String kuid, final JSONObject credentials) { - return createCredentials(strategy, kuid, credentials, null, null); - } - - /** - * {@link #createCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security createCredentials(final String strategy, final String kuid, final JSONObject credentials, final Options options) { - return createCredentials(strategy, kuid, credentials, options, null); - } - - /** - * {@link #createCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security createCredentials(final String strategy, final String kuid, final JSONObject credentials, final ResponseListener listener) { - return createCredentials(strategy, kuid, credentials, null, listener); - } - - /** - * Create credentials of the specified strategy for the provided user. - * - * @param strategy Strategy name to add to the user - * @param kuid Kuzzle User unique Identifier for the user to update - * @param credentials Credentials content - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Security createCredentials(final String strategy, final String kuid, final JSONObject credentials, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("_id", kuid) - .put("body", credentials); - kuzzle.query(buildQueryArgs("security", "createCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #deleteCredentials(String, String, Options, ResponseListener)} - */ - public Security deleteCredentials(final String strategy, final String kuid) { - return deleteCredentials(strategy, kuid, null, null); - } - - /** - * {@link #deleteCredentials(String, String, Options, ResponseListener)} - */ - public Security deleteCredentials(final String strategy, final String kuid, final Options options) { - return deleteCredentials(strategy, kuid, options, null); - } - - /** - * {@link #deleteCredentials(String, String, Options, ResponseListener)} - */ - public Security deleteCredentials(final String strategy, final String kuid, final ResponseListener listener) { - return deleteCredentials(strategy, kuid, null, listener); - } - - /** - * Delete credentials of the specified strategy for the user kuid . - * - * @param strategy Strategy name to delete from the user - * @param kuid Kuzzle User unique Identifier for the user to update - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Security deleteCredentials(final String strategy, final String kuid, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("_id", kuid); - kuzzle.query(buildQueryArgs("security", "deleteCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #getAllCredentialFields(Options, ResponseListener)} - */ - public void getAllCredentialFields(final ResponseListener listener) { - getAllCredentialFields(null, listener); - } - - /** - * Gets a list of all accepted fields per authentication strategy. - * - * @param options - Request options - * @param listener - Response callback listener - */ - public void getAllCredentialFields(final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.getAllCredentialFields: listener is mandatory."); - } - try { - JSONObject body = new JSONObject(); - kuzzle.query(buildQueryArgs("security", "getAllCredentialFields"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getCredentialFields(String, Options, ResponseListener)} - */ - public void getCredentialFields(final String strategy, final ResponseListener listener) { - getCredentialFields(strategy, null, listener); - } - - /** - * Retrieve the list of accepted field names by the specified strategy. - * - * @param strategy Name of the strategy to get - * @param options Request options - * @param listener Response callback listener - */ - public void getCredentialFields(final String strategy, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.getAllCredentialFields: listener is mandatory."); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy); - kuzzle.query(buildQueryArgs("security", "getCredentialFields"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONArray array = response.getJSONObject("result").getJSONArray("hits"); - int length = array.length(); - String[] fields = new String[length]; - for (int i = 0; i < length; i++) { - fields[i] = array.getString(i); - } - listener.onSuccess(fields); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #getCredentials(String, String, Options, ResponseListener)} - */ - public void getCredentials(final String strategy, final String kuid, final ResponseListener listener) { - getCredentials(strategy, kuid, null, listener); - } - - /** - * Get credential information of the specified strategy for the user kuid. - * - * @param strategy Strategy name to get - * @param kuid User unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void getCredentials(final String strategy, final String kuid, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.getCredentials: listener is mandatory."); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("_id", kuid); - kuzzle.query(buildQueryArgs("security", "getCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getJSONObject("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #hasCredentials(String, String, Options, ResponseListener)} - */ - public void hasCredentials(final String strategy, final String kuid, final ResponseListener listener) { - hasCredentials(strategy, kuid, null, listener); - } - - /** - * Check the existence of the specified strategy’s credentials for the user kuid. - * - * @param strategy Strategy name to check - * @param kuid User unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void hasCredentials(final String strategy, final String kuid, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.hasCredentials: listener is mandatory."); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("_id", kuid); - kuzzle.query(buildQueryArgs("security", "hasCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getBoolean("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - /** - * {@link #updateCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security updateCredentials(final String strategy, final String kuid, final JSONObject credentials) { - return updateCredentials(strategy, kuid, credentials, null, null); - } - - /** - * {@link #updateCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security updateCredentials(final String strategy, final String kuid, final JSONObject credentials, final Options options) { - return updateCredentials(strategy, kuid, credentials, options, null); - } - - /** - * {@link #updateCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public Security updateCredentials(final String strategy, final String kuid, final JSONObject credentials, final ResponseListener listener) { - return updateCredentials(strategy, kuid, credentials, null, listener); - } - - /** - * Updates credentials of the specified strategy for the user kuid. - * - * @param strategy Strategy name to update - * @param kuid User unique identifier - * @param credentials Credentials content to update - * @param options Request options - * @param listener Response callback listener - * @return this - */ - public Security updateCredentials(final String strategy, final String kuid, final JSONObject credentials, final Options options, final ResponseListener listener) { - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("_id", kuid) - .put("body", credentials); - kuzzle.query(buildQueryArgs("security", "updateCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - if (listener != null) { - listener.onSuccess(response.getJSONObject("result")); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - if (listener != null) { - listener.onError(error); - } - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return this; - } - - /** - * {@link #validateCredentials(String, String, JSONObject, Options, ResponseListener)} - */ - public void validateCredentials(final String strategy, final String kuid, final JSONObject credentials, final ResponseListener listener) { - validateCredentials(strategy, kuid, credentials, null, listener); - } - - /** - * Validate credentials of the specified strategy for the user kuid. - * - * @param strategy Strategy name to validate - * @param kuid User unique identifier - * @param options Request options - * @param listener Response callback listener - */ - public void validateCredentials(final String strategy, final String kuid, final JSONObject credentials, final Options options, final ResponseListener listener) { - if (listener == null) { - throw new IllegalArgumentException("Security.getCredentials: listener is mandatory."); - } - try { - JSONObject body = new JSONObject() - .put("strategy", strategy) - .put("credentials", credentials) - .put("_id", kuid); - kuzzle.query(buildQueryArgs("security", "validateCredentials"), body, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - try { - listener.onSuccess(response.getBoolean("result")); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/src/main/java/io/kuzzle/sdk/security/User.java b/src/main/java/io/kuzzle/sdk/security/User.java deleted file mode 100644 index 568f8670..00000000 --- a/src/main/java/io/kuzzle/sdk/security/User.java +++ /dev/null @@ -1,360 +0,0 @@ -package io.kuzzle.sdk.security; - - - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Arrays; -import java.util.ArrayList; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -/** - * This class handles users management in Kuzzle - */ -public class User extends AbstractSecurityDocument { - private ArrayList profileIds = new ArrayList<>(); - - private JSONObject credentials = new JSONObject(); - - /** - * Instantiates a new Kuzzle user. - * - * @param kuzzle Kuzzle instance to attach - * @param id User unique identifier - * @param content User content - * @param meta User metadata - * @throws JSONException - */ - public User(final Kuzzle kuzzle, final String id, final JSONObject content, final JSONObject meta) throws JSONException { - super(kuzzle, id, null, meta); - this.deleteActionName = "deleteUser"; - this.updateActionName = "updateUser"; - - if (content != null) { - this.content = new JSONObject(content.toString()); - - if (content.has("profileIds")) { - JSONArray profiles = content.getJSONArray("profileIds"); - - for (int i = 0; i < profiles.length(); i++) { - this.profileIds.add(profiles.getString(i)); - } - } - } - } - - /** - * Set a new profiles set for this user - * - * @param profileIds Array of profile identifiers - * @return this - */ - public User setProfiles(final String[] profileIds) { - if (profileIds == null) { - throw new IllegalArgumentException("User.setProfiles: you must provide an array of profiles IDs strings"); - } - - this.profileIds.clear(); - this.profileIds.addAll(Arrays.asList(profileIds)); - - return this; - } - - /** - * Adds a new profile to the profiles set of this user - * - * @param profile Profile unique ID to add - * @return this - */ - public User addProfile(final String profile) { - if (profile == null) { - throw new IllegalArgumentException("User.addProfile: you must provide a string"); - } - - this.profileIds.add(profile); - - return this; - } - - /** - * Replace a user in Kuzzle with this object's content - * - * @param options Request optional arguments - * @param listener -Callback listener - * @return this - * @throws JSONException - */ - public User replace(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = this.serialize(); - - if (listener != null) { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("replaceUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(User.this); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("replaceUser"), data, options); - } - - return this; - } - - /** - * {@link #replace(Options, ResponseListener)} - */ - public User replace(final ResponseListener listener) throws JSONException { - return replace(null, listener); - } - - /** - * {@link #replace(Options, ResponseListener)} - */ - public User replace(final Options options) throws JSONException { - return replace(options, null); - } - - /** - * {@link #replace(Options, ResponseListener)} - */ - public User replace() throws JSONException { - return replace(null, null); - } - - /** - * Create this user into Kuzzle. - * - * @param options Request optional arguments - * @param listener Callback listener - * @return this - * @throws JSONException - */ - public User create(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = this.creationSerialize(); - - if (listener != null) { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(User.this); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createUser"), data, options); - } - - return this; - } - - /** - * {@link #create(Options, ResponseListener)} - */ - public User create(final ResponseListener listener) throws JSONException { - return create(null, listener); - } - - /** - * {@link #create(Options, ResponseListener)} - */ - public User create(final Options options) throws JSONException { - return create(options, null); - } - - /** - * {@link #create(Options, ResponseListener)} - */ - public User create() throws JSONException { - return create(null, null); - } - - /** - * Saves this object's content as a restricted user into Kuzzle. - * - * @param options Request optional arguments - * @param listener Callback listener - * @return this - * @throws JSONException - */ - public User saveRestricted(final Options options, final ResponseListener listener) throws JSONException { - JSONObject data = this.serialize(); - - if (listener != null) { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createRestrictedUser"), data, options, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject response) { - listener.onSuccess(User.this); - } - - @Override - public void onError(JSONObject error) { - listener.onError(error); - } - }); - } - else { - this.kuzzle.query(this.kuzzleSecurity.buildQueryArgs("createRestrictedUser"), data, options); - } - - return this; - } - - /** - * {@link #saveRestricted(Options, ResponseListener)} - */ - public User saveRestricted(final ResponseListener listener) throws JSONException { - return saveRestricted(null, listener); - } - - /** - * {@link #saveRestricted(Options, ResponseListener)} - */ - public User saveRestricted(final Options options) throws JSONException { - return saveRestricted(options, null); - } - - /** - * {@link #saveRestricted(Options, ResponseListener)} - */ - public User saveRestricted() throws JSONException { - return saveRestricted(null, null); - } - - /** - * Return a JSONObject representing a serialized version of this object - * - * @return serialized version of this object - * @throws JSONException - */ - public JSONObject serialize() throws JSONException { - JSONObject - data = new JSONObject().put("_id", this.id), - content = new JSONObject(this.content.toString()); - - if (this.profileIds.size() > 0) { - content.put("profileIds", new JSONArray(this.profileIds)); - } - - data.put("body", content); - - return data; - } - - /** - * Return a JSONObject representing a serialized version of this object - * - * @return serialized version of this object - * @throws JSONException - */ - public JSONObject creationSerialize() throws JSONException { - JSONObject - data = new JSONObject().put("_id", this.id), - body = new JSONObject(), - content = new JSONObject(this.content.toString()), - credentials = new JSONObject(this.credentials.toString()); - - if (this.profileIds.size() > 0) { - content.put("profileIds", new JSONArray(this.profileIds)); - } - - body.put("content", content); - body.put("credentials", credentials); - data.put("body", body); - - return data; - } - - /** - * @return the associated profile identifiers - */ - public String[] getProfileIds() { - return this.profileIds.toArray(new String[0]); - } - - /** - * {@link #getProfiles(Options, ResponseListener)} - */ - public void getProfiles(final ResponseListener listener) throws JSONException { - getProfiles(null, listener); - } - - /** - * Gets the profile objects from the associated profile identifiers - * - * @param options Request optional arguments - * @param listener Response callback listener - * @throws JSONException - */ - public void getProfiles(final Options options, final ResponseListener listener) throws JSONException { - if (listener == null) { - throw new IllegalArgumentException("User.getProfiles: a valid ResponseListener object is required"); - } - - final Profile[] profiles = new Profile[this.profileIds.size()]; - - if (this.profileIds.size() == 0) { - listener.onSuccess(profiles); - return; - } - - // using an array to allow these variables to be final - // while keeping the possibility to change their value - final int[] fetched = {0}; - final boolean[] errored = {false}; - - for (int i = 0; i < this.profileIds.size(); i++) { - this.kuzzleSecurity.fetchProfile(this.profileIds.get(i), options, new ResponseListener() { - @Override - public void onSuccess(Profile response) { - profiles[fetched[0]] = response; - fetched[0]++; - - if (fetched[0] == User.this.profileIds.size()) { - listener.onSuccess(profiles); - } - } - - @Override - public void onError(JSONObject error) { - // prevents triggering the listener multiple times - if (errored[0]) { - return; - } - - errored[0] = true; - listener.onError(error); - } - }); - } - } - - /** - * User credentials setter - * @param credentials New credentials value - * @return this - */ - public User setCredentials(JSONObject credentials) { - this.credentials = credentials; - - return this; - } -} diff --git a/src/main/java/io/kuzzle/sdk/state/KuzzleQueue.java b/src/main/java/io/kuzzle/sdk/state/KuzzleQueue.java deleted file mode 100644 index f0b7c499..00000000 --- a/src/main/java/io/kuzzle/sdk/state/KuzzleQueue.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.kuzzle.sdk.state; - -import java.util.ArrayDeque; -import java.util.Iterator; -import java.util.Queue; - -/** - * The type KuzzleQueue. - * - * @param the type parameter - */ -public class KuzzleQueue implements Iterable { - - private Queue _queue = new ArrayDeque<>(); - - /** - * Add to queue. - * - * @param object Item to queue - */ - public synchronized void addToQueue(T object) { - _queue.add(object); - } - - /** - * Dequeue t. - * - * @return Dequeued item - */ - public synchronized T dequeue() { - return _queue.poll(); - } - - private States _currentState = States.DISCONNECTED; - - /** - * @param states New connection state value - */ - public void setState(States states) { - _currentState = states; - } - - /** - * @return Connection state value - */ - public States state() { - return _currentState; - } - - /** - * @return queue content - */ - public Queue getQueue() { - return _queue; - } - - @Override - public Iterator iterator() { - return _queue.iterator(); - } -} diff --git a/src/main/java/io/kuzzle/sdk/state/States.java b/src/main/java/io/kuzzle/sdk/state/States.java deleted file mode 100644 index 5c152558..00000000 --- a/src/main/java/io/kuzzle/sdk/state/States.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.kuzzle.sdk.state; - -/** - * The enum States. - */ -public enum States { - CONNECTING, - DISCONNECTED, - CONNECTED, - INITIALIZING, - READY, - LOGGED_OUT, - ERROR, - OFFLINE -} diff --git a/src/main/java/io/kuzzle/sdk/util/Event.java b/src/main/java/io/kuzzle/sdk/util/Event.java deleted file mode 100644 index 4854195b..00000000 --- a/src/main/java/io/kuzzle/sdk/util/Event.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.kuzzle.sdk.util; - -import io.kuzzle.sdk.listeners.EventListener; - -public abstract class Event implements EventListener { - private io.kuzzle.sdk.enums.Event type; - - /** - * Instantiates a new Event. - * - * @param type Event type - */ - public Event(io.kuzzle.sdk.enums.Event type) { - this.type = type; - } - - public abstract void trigger(Object... args); - - /** - * @return Event type value - */ - public io.kuzzle.sdk.enums.Event getType() { - return this.type; - } -} diff --git a/src/main/java/io/kuzzle/sdk/util/EventList.java b/src/main/java/io/kuzzle/sdk/util/EventList.java deleted file mode 100644 index 8b7ec217..00000000 --- a/src/main/java/io/kuzzle/sdk/util/EventList.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.util; - -import java.util.HashMap; -import io.kuzzle.sdk.listeners.EventListener; - -public class EventList extends HashMap { - public long lastEmitted = 0; -} diff --git a/src/main/java/io/kuzzle/sdk/util/KuzzleJSONObject.java b/src/main/java/io/kuzzle/sdk/util/KuzzleJSONObject.java deleted file mode 100644 index 32e5d87b..00000000 --- a/src/main/java/io/kuzzle/sdk/util/KuzzleJSONObject.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.kuzzle.sdk.util; - -import org.json.JSONException; -import org.json.JSONObject; - -public class KuzzleJSONObject extends JSONObject { - - @Override - public KuzzleJSONObject put(final String name, final Object value) { - try { - super.put(name, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public KuzzleJSONObject put(final String name, final long value) { - try { - super.put(name, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public KuzzleJSONObject put(final String name, final int value) { - try { - super.put(name, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public KuzzleJSONObject put(final String name, final double value) { - try { - super.put(name, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public KuzzleJSONObject put(final String name, final boolean value) { - try { - super.put(name, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } - -} diff --git a/src/main/java/io/kuzzle/sdk/util/OfflineQueueLoader.java b/src/main/java/io/kuzzle/sdk/util/OfflineQueueLoader.java deleted file mode 100644 index f2267740..00000000 --- a/src/main/java/io/kuzzle/sdk/util/OfflineQueueLoader.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.kuzzle.sdk.util; - -import io.kuzzle.sdk.state.KuzzleQueue; - -public interface OfflineQueueLoader { - KuzzleQueue load(); -} diff --git a/src/main/java/io/kuzzle/sdk/util/QueryObject.java b/src/main/java/io/kuzzle/sdk/util/QueryObject.java deleted file mode 100644 index 1abc119f..00000000 --- a/src/main/java/io/kuzzle/sdk/util/QueryObject.java +++ /dev/null @@ -1,86 +0,0 @@ -package io.kuzzle.sdk.util; - -import org.json.JSONObject; - -import java.util.Date; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -public class QueryObject { - private JSONObject query; - private String action; - private Options options; - private OnQueryDoneListener cb; - private Date timestamp; - - /** - * @return Callback to invoke with the query result - */ - public OnQueryDoneListener getCb() { - return cb; - } - - /** - * @param cb Callback to invoke with the query result - */ - public void setCb(OnQueryDoneListener cb) { - this.cb = cb; - } - - /** - * @return Controller action name to execute - */ - public String getAction() { - return action; - } - - /** - * @param action Controller action name to execute - */ - public void setAction(String action) { - this.action = action; - } - - /** - * @return Query options - */ - public Options getOptions() { - return options; - } - - /** - * @param options Query options - */ - public void setOptions(Options options) { - this.options = options; - } - - /** - * @return Query timestamp (Epoch time) - */ - public Date getTimestamp() { - return timestamp; - } - - /** - * @param timestamp Query timestamp (Epoch time) - */ - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - - /** - * @return Query content - */ - public JSONObject getQuery() { - return query; - } - - /** - * @param query Query content - */ - public void setQuery(JSONObject query) { - this.query = query; - } -} diff --git a/src/main/java/io/kuzzle/sdk/util/QueueFilter.java b/src/main/java/io/kuzzle/sdk/util/QueueFilter.java deleted file mode 100644 index 8d7ad00b..00000000 --- a/src/main/java/io/kuzzle/sdk/util/QueueFilter.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.kuzzle.sdk.util; - -import org.json.JSONObject; - -public interface QueueFilter { - boolean filter(JSONObject object); -} diff --git a/src/main/java/io/kuzzle/sdk/util/Scroll.java b/src/main/java/io/kuzzle/sdk/util/Scroll.java deleted file mode 100644 index 36f217b5..00000000 --- a/src/main/java/io/kuzzle/sdk/util/Scroll.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.kuzzle.sdk.util; - - -public class Scroll { - private String scrollId; - - public void setScrollId(String scrollId) { - this.scrollId = scrollId; - } - - public boolean hasScrollId() { return !(scrollId == null); } - - public String getScrollId() { return scrollId; } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/checkTokenTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/checkTokenTest.java deleted file mode 100644 index f51582fc..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/checkTokenTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Date; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class checkTokenTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testCheckTokenWithIllegalListener() { - kuzzle.checkToken("token", null); - } - - @Test(expected = IllegalArgumentException.class) - public void testCheckTokenWithIllegalToken() { - kuzzle.checkToken(null, mock(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testCheckTokenWithEmptyToken() { - kuzzle.checkToken("", null); - } - - @Test(expected = RuntimeException.class) - public void testCheckTokenException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("valid", true).put("expiresAt", new Date().getTime()))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.checkToken("token", listener); - } - - @Test(expected = RuntimeException.class) - public void testCheckTokenQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.checkToken("token", listener); - } - - @Test - public void testCheckTokenValid() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("valid", true).put("expiresAt", new Date().getTime()))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.checkToken("token-42", mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "checkToken"); - } - - @Test - public void testCheckTokenInvalid() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("valid", false).put("state", "error"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.checkToken("token-42", mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "checkToken"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/connectionManagementTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/connectionManagementTest.java deleted file mode 100644 index c46d6b37..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/connectionManagementTest.java +++ /dev/null @@ -1,264 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Date; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.TokenValidity; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.QueryObject; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class connectionManagementTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - kuzzle = new KuzzleExtend("localhost", options, listener); - kuzzle.setSocket(s); - } - - @Test - public void testMaxTTLWithReconnectListener() throws JSONException, URISyntaxException { - Options options = new Options(); - options.setQueueTTL(1); - options.setReplayInterval(1); - options.setAutoReplay(true); - options.setConnect(Mode.MANUAL); - options.setOfflineMode(Mode.AUTO); - options.setAutoReconnect(true); - - QueryObject o = new QueryObject(); - o.setTimestamp(new Date()); - o.setAction("test"); - JSONObject query = new JSONObject("{\"controller\":\"test3\",\"volatile\":{},\"requestId\":\"a476ae61-497e-4338-b4dd-751ac22c6b61\",\"action\":\"test3\",\"collection\":\"test3\"}"); - o.setQuery(query); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - final EventListener listener = mock(EventListener.class); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - listener.trigger(); - return s; - } - }).when(s).connect(); - - kuzzle.setOfflineQueue(o); - - kuzzle.addListener(Event.reconnected, listener); - kuzzle.connect(); - verify(listener, times(1)).trigger(); - } - - @Test - public void testRenewSubscriptionsAfterReconnection() throws URISyntaxException, JSONException, InterruptedException { - Options options = new Options(); - options.setAutoReconnect(true); - options.setQueueTTL(1); - options.setAutoReplay(true); - options.setConnect(Mode.MANUAL); - options.setAutoReconnect(true); - options.setOfflineMode(Mode.AUTO); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - extended.setState(States.INITIALIZING); - final Kuzzle kuzzleSpy = spy(extended); - - Room - room1 = new Room(new Collection(kuzzleSpy, "test", "index")), - room2 = new Room(new Collection(kuzzleSpy, "test2", "index")); - - room1 = spy(room1); - room2 = spy(room2); - - room1.renew(listener); - room2.renew(listener); - - Map> subscriptions = kuzzle.getSubscriptions(); - subscriptions.put("room", new ConcurrentHashMap()); - subscriptions.get("room").put("42", room1); - subscriptions.get("room").put("43", room2); - - Thread.sleep(2); - kuzzle.renewSubscriptions(); - verify(room1, atLeastOnce()).renew(any(ResponseListener.class)); - verify(room2, atLeastOnce()).renew(any(ResponseListener.class)); - } - - @Test - public void testAutoReconnect() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setAutoReconnect(false); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - kuzzle.disconnect(); - return s; - } - }).when(s).connect(); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - kuzzle = spy(kuzzle); - - kuzzle.connect(); - - // since "connect" is called 2 times with a socket set, disconnect - // is called each time - verify(kuzzle, times(2)).disconnect(); - } - - @Test - public void testConnectNotValid() throws URISyntaxException { - listener = spy(listener); - kuzzle.setState(States.LOGGED_OUT); - kuzzle.setListener(listener); - kuzzle = spy(kuzzle); - kuzzle.connect(); - verify(listener, atLeastOnce()).onSuccess(any(JSONObject.class)); - } - - @Test - public void testOnConnectError() throws URISyntaxException { - listener = spy(listener); - kuzzle.setListener(listener); - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - listener.onError(new JSONObject()); - return null; - } - }).when(s).connect(); - kuzzle.connect(); - verify(listener, times(1)).onError(any(JSONObject.class)); - } - - @Test - public void testConnectEventConnect() throws URISyntaxException { - listener = spy(listener); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - listener.onSuccess(new JSONObject()); - return null; - } - }).when(s).connect(); - kuzzle.connect(); - verify(listener).onSuccess(any(Void.class)); - } - - @Test - public void testDisconnect() { - kuzzle.setState(States.CONNECTED); - assertNotNull(kuzzle.getSocket()); - kuzzle.disconnect(); - assertNull(kuzzle.getSocket()); - } - - @Test(expected = RuntimeException.class) - public void testIsValid() throws Exception { - kuzzle.disconnect(); - kuzzle.isValid(); - } - - @Test - public void testJWTTokenAfterReconnect() throws URISyntaxException { - kuzzle = spy(kuzzle); - kuzzle.setJwtToken("foo"); - TokenValidity tokenValidity = spy(new TokenValidity()); - doReturn(false).when(tokenValidity).isValid(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - kuzzle.setJwtToken((String)null); - ((ResponseListener) invocation.getArguments()[1]).onSuccess(mock(TokenValidity.class)); - return null; - } - }).when(kuzzle).checkToken(eq("foo"), any(ResponseListener.class)); - kuzzle.checkToken("foo", mock(ResponseListener.class)); - assertNull(kuzzle.getJwtToken()); - doReturn(true).when(tokenValidity).isValid(); - kuzzle.setJwtToken("foo"); - kuzzle.connect(); - assertEquals("foo", kuzzle.getJwtToken()); - } - - @Test - public void testJWTTokenErrorAfterReconnect() throws URISyntaxException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - kuzzle.setJwtToken((String)null); - return s; - } - }).when(s).connect(); - kuzzle = spy(kuzzle); - kuzzle.setJwtToken("foo"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((ResponseListener) invocation.getArguments()[1]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).checkToken(eq("foo"), any(ResponseListener.class)); - kuzzle.connect(); - assertNull(kuzzle.getJwtToken()); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/constructorTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/constructorTest.java deleted file mode 100644 index 3fd74802..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/constructorTest.java +++ /dev/null @@ -1,290 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.QueryObject; -import io.kuzzle.sdk.util.QueueFilter; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.QueryArgsHelper; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.*; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.hamcrest.core.IsInstanceOf.instanceOf; - -public class constructorTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setPort(12345); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testBadUriConnection() throws URISyntaxException { - new Kuzzle(null); - } - - @Test - public void checkSignaturesVariants() throws URISyntaxException { - Kuzzle k = new Kuzzle("localhost"); - assertNotNull(k); - k = new Kuzzle("localhost", new Options()); - assertNotNull(k); - k = new Kuzzle("localhost", listener); - assertNotNull(k); - } - - @Test - public void testKuzzleConstructor() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - assertEquals(kuzzle.getDefaultIndex(), "testIndex"); - assertNotNull(kuzzle); - verify(kuzzle, never()).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test - public void testSetHeadersSignaturesVariants() throws JSONException { - kuzzle = spy(kuzzle); - kuzzle.setHeaders(new JSONObject()); - verify(kuzzle).setHeaders(any(JSONObject.class), eq(false)); - } - - @Test(expected = RuntimeException.class) - public void testSetHeaders() throws JSONException { - kuzzle.setHeaders(null, true); - kuzzle.setHeaders(new JSONObject()); - assertNotNull(kuzzle.getHeaders()); - JSONObject content = new JSONObject(); - content.put("foo", "bar"); - kuzzle.setHeaders(content); - assertEquals(kuzzle.getHeaders().getString("foo"), "bar"); - content.put("foo", "baz"); - kuzzle.setHeaders(content, true); - assertEquals(kuzzle.getHeaders().getString("foo"), "baz"); - JSONObject fake = spy(new JSONObject()); - doThrow(JSONException.class).when(fake).keys(); - kuzzle.setHeaders(fake, false); - } - - @Test(expected = RuntimeException.class) - public void testAddHeaders() throws JSONException { - JSONObject query = new JSONObject(); - JSONObject headers = new JSONObject(); - headers.put("testPurpose", "test"); - kuzzle.addHeaders(query, headers); - assertEquals(query.get("testPurpose"), "test"); - JSONObject fake = mock(JSONObject.class); - doThrow(JSONException.class).when(fake).keys(); - kuzzle.addHeaders(new JSONObject(), fake); - } - - @Test - public void testVolatileOptions() throws URISyntaxException, JSONException { - Options options = new Options(); - options.setQueuable(false); - options.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - extended.setState(States.CONNECTED); - - - JSONObject meta = new JSONObject(); - meta.put("foo", "bar"); - options.setVolatile(meta); - - JSONObject jsonObj = new JSONObject(); - jsonObj.put("requestId", "42"); - - extended.query(QueryArgsHelper.makeQueryArgs("controller", "action"), jsonObj, options, null); - verify(s).send(eq(jsonObj.toString())); - assertEquals(jsonObj.getJSONObject("volatile").getString("foo"), "bar"); - } - - @Test - public void testVolatileInKuzzle() throws JSONException, URISyntaxException { - JSONObject jsonObj = new JSONObject(); - jsonObj.put("requestId", "42"); - JSONObject meta = new JSONObject(); - meta.put("foo", "bar"); - Options options = new Options(); - options.setVolatile(meta); - options.setQueuable(false); - options.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - extended.setState(States.CONNECTED); - extended.query(QueryArgsHelper.makeQueryArgs("controller", "action"), jsonObj, options); - verify(s).send(eq(jsonObj.toString())); - assertEquals(jsonObj.getJSONObject("volatile").getString("foo"), "bar"); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetDefaultIndexIllegalIndex() { - kuzzle.setDefaultIndex(null); - } - - @Test - public void exposeDefaultIndexGetterSetter() { - assertEquals("testIndex", kuzzle.getDefaultIndex()); - assertThat(kuzzle.setDefaultIndex("foobar"), instanceOf(KuzzleExtend.class)); - assertEquals("foobar", kuzzle.getDefaultIndex()); - } - - @Test - public void exposeJwtTokenGetter() { - assertThat(kuzzle.setJwtToken("foobar"), instanceOf(KuzzleExtend.class)); - assertEquals("foobar", kuzzle.getJwtToken()); - } - - @Test - public void exposeAutoQueueGetterSetter() { - assertThat(kuzzle.setAutoQueue(true), instanceOf(KuzzleExtend.class)); - assertEquals(true, kuzzle.isAutoQueue()); - } - - @Test - public void exposeAutoReconnectGetter() { - assertThat(kuzzle.isAutoReconnect(), instanceOf(boolean.class)); - } - - @Test - public void exposeAutoResubscribeGetterSetter() { - assertThat(kuzzle.setAutoResubscribe(true), instanceOf(KuzzleExtend.class)); - assertEquals(true, kuzzle.isAutoResubscribe()); - } - - @Test - public void exposeAutoReplayGetterSetter() { - assertThat(kuzzle.setAutoReplay(true), instanceOf(KuzzleExtend.class)); - assertEquals(true, kuzzle.isAutoReplay()); - } - - @Test - public void exposeOfflineQueueGetterSetter() { - QueryObject query = new QueryObject(); - assertThat(kuzzle.setOfflineQueue(query), instanceOf(KuzzleExtend.class)); - assertEquals(kuzzle.getOfflineQueue().peek(), query); - } - - @Test - public void exposeQueueFilterGetterSetter() { - QueueFilter qf = new QueueFilter() { - @Override - public boolean filter(JSONObject object) { - return false; - } - }; - - assertThat(kuzzle.setQueueFilter(qf), instanceOf(KuzzleExtend.class)); - assertEquals(qf, kuzzle.getQueueFilter()); - } - - @Test - public void exposeQueueMaxSizeGetterSetter() { - assertThat(kuzzle.setQueueMaxSize(123), instanceOf(KuzzleExtend.class)); - assertEquals(123, kuzzle.getQueueMaxSize()); - } - - @Test - public void ensureQueueMaxSizeIsNeverBelowZero() { - kuzzle.setQueueMaxSize(-4623); - assertEquals(0, kuzzle.getQueueMaxSize()); - } - - @Test - public void exposeQueueTTLGetterSetter() { - assertThat(kuzzle.setQueueTTL(123), instanceOf(KuzzleExtend.class)); - assertEquals(123, kuzzle.getQueueTTL()); - } - - @Test - public void ensureQueueTTLIsNeverBelowZero() { - kuzzle.setQueueTTL(-12); - assertEquals(0, kuzzle.getQueueTTL()); - } - - @Test - public void exposeVolatileGetterSetter() { - JSONObject _volatile = new JSONObject(); - assertThat(kuzzle.setVolatile(_volatile), instanceOf(KuzzleExtend.class)); - assertEquals(_volatile, kuzzle.getVolatile()); - } - - @Test - public void exposeReplayIntervalGetterSetter() { - assertThat(kuzzle.setReplayInterval(123), instanceOf(KuzzleExtend.class)); - assertEquals(123, kuzzle.getReplayInterval()); - } - - @Test - public void ensureReplayIntervalIsNeverBelowZero() { - kuzzle.setReplayInterval(-123); - assertEquals(0, kuzzle.getReplayInterval()); - } - - @Test - public void exposeReconnectionDelayGetter() { - assertThat(kuzzle.getReconnectionDelay(), instanceOf(long.class)); - } - - @Test - public void testGetPort() { - assertEquals(kuzzle.getPort(), 12345); - } - - @Test - public void testSetPort() { - kuzzle = spy(kuzzle); - kuzzle.setPort(1234); - assertEquals(kuzzle.getPort(), 1234); - } - - @Test - public void testGetHost() { - assertEquals("localhost", kuzzle.getHost()); - } - - @Test public void testSetHost() { - kuzzle = spy(kuzzle); - kuzzle.setHost("foobar"); - assertEquals("foobar", kuzzle.getHost()); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/createIndexTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/createIndexTest.java deleted file mode 100644 index 06707f78..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/createIndexTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Date; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class createIndexTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - @Test(expected = IllegalArgumentException.class) - public void testCreateIndexIllegalIndex() { - kuzzle.checkToken(null, mock(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testCreateIndexException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.createIndex("index", listener); - } - - @Test(expected = RuntimeException.class) - public void testCreateIndexQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.createIndex("index", listener); - } - - @Test - public void testCreateIndex() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("acknowledged", true))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.createIndex("index", mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "index"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "create"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/createMyCredentialsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/createMyCredentialsTest.java deleted file mode 100644 index 600b6f08..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/createMyCredentialsTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class createMyCredentialsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - private JSONObject credentials; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - try { - credentials = new JSONObject() - .put("foo", "bar"); - } catch (JSONException err) { - throw new RuntimeException(err); - } - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testCreateMyCredentialsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.createMyCredentials("strategy", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testCreateMyCredentialsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.createMyCredentials("strategy", credentials, null, listener); - } - - @Test - public void testCreateMyCredentials() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzle.createMyCredentials("strategy", credentials) - .createMyCredentials("strategy", credentials, mock(Options.class)) - .createMyCredentials("strategy", credentials, mock(ResponseListener.class)) - .createMyCredentials("strategy", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "createMyCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/deleteMyCredentialsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/deleteMyCredentialsTest.java deleted file mode 100644 index 47c23bcc..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/deleteMyCredentialsTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class deleteMyCredentialsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testDeleteMyCredentialsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.deleteMyCredentials("strategy", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testDeleteMyCredentialsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.deleteMyCredentials("strategy", null, listener); - } - - @Test - public void testDeleteMyCredentials() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.deleteMyCredentials("strategy") - .deleteMyCredentials("strategy", mock(ResponseListener.class)) - .deleteMyCredentials("strategy", mock(Options.class)) - .deleteMyCredentials("strategy", mock(Options.class), mock(ResponseListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "deleteMyCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/eventSystemTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/eventSystemTest.java deleted file mode 100644 index 6e846c58..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/eventSystemTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.util.EventList; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; - -public class eventSystemTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testAddListener() { - assertEquals(kuzzle.getEventListeners(Event.connected), null); - kuzzle.addListener(Event.connected, mock(EventListener.class)); - assertThat(kuzzle.getEventListeners(Event.connected), instanceOf(EventList.class)); - } - - @Test(expected = NullPointerException.class) - public void testRemoveAllListeners() { - kuzzle.addListener(Event.connected, mock(EventListener.class)); - kuzzle.addListener(Event.connected, mock(EventListener.class)); - kuzzle.addListener(Event.disconnected, mock(EventListener.class)); - kuzzle.addListener(Event.disconnected, mock(EventListener.class)); - assertEquals(kuzzle.getEventListeners(Event.connected).size(), 2); - assertEquals(kuzzle.getEventListeners(Event.disconnected).size(), 2); - kuzzle.removeAllListeners(); - assertEquals(kuzzle.getEventListeners(Event.connected).size(), 0); - assertEquals(kuzzle.getEventListeners(Event.disconnected).size(), 0); - } - - @Test - public void testRemoveAllListenersType() { - kuzzle.addListener(Event.connected, mock(EventListener.class)); - kuzzle.addListener(Event.connected, mock(EventListener.class)); - kuzzle.addListener(Event.disconnected, mock(EventListener.class)); - kuzzle.addListener(Event.disconnected, mock(EventListener.class)); - assertEquals(kuzzle.getEventListeners(Event.connected).size(), 2); - assertEquals(kuzzle.getEventListeners(Event.disconnected).size(), 2); - kuzzle.removeAllListeners(Event.connected); - assertEquals(kuzzle.getEventListeners(Event.connected).size(), 0); - assertEquals(kuzzle.getEventListeners(Event.disconnected).size(), 2); - } - - @Test - public void testRemoveListener() { - EventListener listener1 = mock(EventListener.class); - EventListener listener2 = mock(EventListener.class); - EventListener listener3 = mock(EventListener.class); - EventListener listener4 = mock(EventListener.class); - kuzzle.addListener(Event.disconnected, listener1); - kuzzle.addListener(Event.connected, listener2); - kuzzle.addListener(Event.disconnected, listener3); - kuzzle.addListener(Event.connected, listener4); - assertEquals(kuzzle.getEventListeners(Event.disconnected).get(listener1).getType(), Event.disconnected); - assertEquals(kuzzle.getEventListeners(Event.connected).get(listener2).getType(), Event.connected); - assertEquals(kuzzle.getEventListeners(Event.disconnected).get(listener3).getType(), Event.disconnected); - assertEquals(kuzzle.getEventListeners(Event.connected).get(listener4).getType(), Event.connected); - kuzzle.removeListener(Event.connected, listener2); - assertEquals(kuzzle.getEventListeners(Event.connected).size(), 1); - assertEquals(kuzzle.getEventListeners(Event.disconnected).size(), 2); - assertEquals(kuzzle.getEventListeners(Event.disconnected).get(listener1).getType(), Event.disconnected); - assertEquals(kuzzle.getEventListeners(Event.disconnected).get(listener2), null); - assertEquals(kuzzle.getEventListeners(Event.disconnected).get(listener3).getType(), Event.disconnected); - assertEquals(kuzzle.getEventListeners(Event.connected).get(listener4).getType(), Event.connected); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/factoriesTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/factoriesTest.java deleted file mode 100644 index d0424e4e..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/factoriesTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -public class factoriesTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testDataCollectionFactory() { - assertEquals(kuzzle.collection("test").getCollection(), "test"); - assertEquals(kuzzle.collection("test2").getCollection(), "test2"); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalDefaultIndex() { - kuzzle.setSuperDefaultIndex(null); - kuzzle.collection("foo"); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalIndex() { - kuzzle.setSuperDefaultIndex(null); - kuzzle.collection("collection", null); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAllStatisticsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAllStatisticsTest.java deleted file mode 100644 index dda13a4a..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAllStatisticsTest.java +++ /dev/null @@ -1,187 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Iterator; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.QueryArgsHelper; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getAllStatisticsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - kuzzle.setState(States.CONNECTED); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testGetAllStatisticsNoListener() { - kuzzle.getAllStatistics(null); - } - - @Test - public void testGetAllStatisticsNoOptions() { - kuzzle = spy(kuzzle); - kuzzle.getAllStatistics(listener); - verify(kuzzle).getAllStatistics(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testGetAllStatisticsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("hits", mock(JSONObject.class)))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAllStatistics(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetAllStatisticsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAllStatistics(listener); - } - - @Test - public void testGetAllStatsSuccess() throws JSONException { - kuzzle = spy(kuzzle); - final JSONObject response = new JSONObject("{\n" + - " \"total\": 25,\n" + - " \"hits\": [\n" + - " {\n" + - " \"completedRequests\": {\n" + - " \"websocket\": 148,\n" + - " \"rest\": 24,\n" + - " \"mq\": 78\n" + - " },\n" + - " \"failedRequests\": {\n" + - " \"websocket\": 3\n" + - " },\n" + - " \"ongoingRequests\": {\n" + - " \"mq\": 8,\n" + - " \"rest\": 2\n" + - " },\n" + - " \"connections\": {\n" + - " \"websocket\": 13\n" + - " },\n" + - " \"timestamp\": \"2016-01-13T13:46:19.917Z\"\n" + - " }\n" + - " ]\n" + - " }\n"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", response)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAllStatistics(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] result) { - try { - for (int i = 0; i < result.length; i++) { - for (Iterator ite = result[i].keys(); ite.hasNext(); ) { - String key = (String) ite.next(); - assertEquals(result[i].get(key), response.getJSONArray("hits").getJSONObject(i).get(key)); - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(JSONObject error) { - - } - }); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getAllStats"); - } - - @Test - public void testGetAllStatsError() throws JSONException { - kuzzle = spy(kuzzle); - - final JSONObject responseError = new JSONObject(); - responseError.put("error", "rorre"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(responseError); - return null; - } - }).when(kuzzle).query(eq(QueryArgsHelper.makeQueryArgs("server", "getAllStats")), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAllStatistics(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] object) { - } - - @Override - public void onError(JSONObject error) { - try { - System.out.println(error.toString()); - assertEquals(error.get("error"), "rorre"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getAllStats"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAutoRefreshTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAutoRefreshTest.java deleted file mode 100644 index 7a90bf73..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getAutoRefreshTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import java.net.URISyntaxException; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getAutoRefreshTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - - @Before - public void setup() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = mock(ResponseListener.class); - } - - @Test - public void testSignatureVariants() { - Options options = mock(Options.class); - - kuzzle = spy(kuzzle); - - kuzzle.getAutoRefresh(listener); - kuzzle.getAutoRefresh(options, listener); - kuzzle.getAutoRefresh("foo", listener); - - verify(kuzzle, times(3)).getAutoRefresh(any(String.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetAutoRefreshWithIllegalListener() { - kuzzle.getAutoRefresh("index", null, null); - } - - @Test(expected = RuntimeException.class) - public void testGetAutoRefreshException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAutoRefresh(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetAutoRefreshQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getAutoRefresh(listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetAutoRefreshIllegalDefaultIndex() { - kuzzle = spy(kuzzle); - kuzzle.setSuperDefaultIndex(null); - kuzzle.getAutoRefresh(null, mock(Options.class), listener); - } - - @Test - public void testGetAutoRefresh() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.getAutoRefresh(listener); - kuzzle.getAutoRefresh(mock(Options.class), listener); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "index"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getAutoRefresh"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).index, kuzzle.getDefaultIndex()); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getLastStatisticsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getLastStatisticsTest.java deleted file mode 100644 index acf26fee..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getLastStatisticsTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getLastStatisticsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - - @Test(expected = RuntimeException.class) - public void testGetLastStatisticsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetLastStatisticsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(listener); - } - - @Test - public void testGetLastStatistic() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject("{ result: {\n" + - " completedRequests: {\n" + - " websocket: 148,\n" + - " rest: 24,\n" + - " mq: 78\n" + - " },\n" + - " failedRequests: {\n" + - " websocket: 3\n" + - " },\n" + - " ongoingRequests: {\n" + - " mq: 8,\n" + - " rest: 2\n" + - " },\n" + - " connections: {\n" + - " websocket: 13\n" + - " },\n" + - " \"timestamp\": \"2016-01-13T13:46:19.917Z\"\n" + - " }" + - "}")); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getLastStats"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyCredentialsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyCredentialsTest.java deleted file mode 100644 index 7075d906..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyCredentialsTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class getMyCredentialsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testGetMyCredentialsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getMyCredentials("strategy", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testGetMyCredentialsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getMyCredentials("strategy", null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzle.getMyCredentials(null, null); - } - - @Test - public void testGetMyCredentials() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.getMyCredentials("strategy", mock(ResponseListener.class)); - kuzzle.getMyCredentials("strategy", mock(Options.class), mock(ResponseListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getMyCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyRightsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyRightsTest.java deleted file mode 100644 index 01d4f90e..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getMyRightsTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class getMyRightsTest { - - private Kuzzle kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - kuzzle = spy(new KuzzleExtend("localhost", mock(Options.class), mock(ResponseListener.class))); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalCallback() { - kuzzle.getMyRights(null); - } - - @Test(expected = RuntimeException.class) - public void testQueryException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getMyRights(listener); - } - - @Test(expected = RuntimeException.class) - public void testException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getMyRights(listener); - } - - @Test - public void testGetMyRights() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", new JSONObject() - .put("hits", new JSONArray())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getMyRights(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getMyRights"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getServerInfoTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getServerInfoTest.java deleted file mode 100644 index fc4abe4f..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getServerInfoTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getServerInfoTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testGetServerInfoIllegalListener() { - kuzzle.getServerInfo(null); - } - - @Test - public void testGetServerInfoNoOptions() { - kuzzle = spy(kuzzle); - kuzzle.getServerInfo(mock(ResponseListener.class)); - verify(kuzzle).getServerInfo(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testGetServerInfoException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getServerInfo(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetServerInfoQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getServerInfo(listener); - } - - @Test - public void testGetServerInfo() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("serverInfo", mock(JSONObject.class)))); - ((OnQueryDoneListener)invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getServerInfo(listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "info"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getStatisticsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/getStatisticsTest.java deleted file mode 100644 index b7a5876b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/getStatisticsTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class getStatisticsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void checkAllSignaturesVariants() { - kuzzle = spy(kuzzle); - listener = spy(listener); - kuzzle.getStatistics(listener); - kuzzle.getStatistics(System.currentTimeMillis(), listener); - verify(kuzzle).getStatistics(any(Options.class), any(ResponseListener.class)); - verify(kuzzle).getStatistics(any(long.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testGetStatisticsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("hits", mock(JSONArray.class)))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(System.currentTimeMillis(), listener); - } - - @Test(expected = RuntimeException.class) - public void testGetStatisticsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(System.currentTimeMillis(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetStatsIllegalListener() { - kuzzle.getStatistics(System.currentTimeMillis(), null); - } - - @Test - public void testGetStatistics() throws JSONException { - kuzzle = spy(kuzzle); - final JSONObject response = new JSONObject("{ result: {\n" + - " total: 25,\n" + - " hits: [\n" + - " {\n" + - " completedRequests: {\n" + - " websocket: 148,\n" + - " rest: 24,\n" + - " mq: 78\n" + - " },\n" + - " failedRequests: {\n" + - " websocket: 3\n" + - " },\n" + - " ongoingRequests: {\n" + - " mq: 8,\n" + - " rest: 2\n" + - " },\n" + - " connections: {\n" + - " websocket: 13\n" + - " },\n" + - " \"timestamp\": \"2016-01-13T13:46:19.917Z\"\n" + - " }\n" + - " ]\n" + - " }" + - "}"); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.getStatistics(System.currentTimeMillis(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getStats"); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetStatisticsWithoutListener() { - kuzzle.getStatistics(null); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/listCollectionsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/listCollectionsTest.java deleted file mode 100644 index 50f2f395..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/listCollectionsTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class listCollectionsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testAllSignatureVariants() { - listener = spy(listener); - kuzzle = spy(kuzzle); - kuzzle.listCollections(listener); - kuzzle.listCollections("foo", listener); - kuzzle.listCollections(new Options(), listener); - verify(kuzzle, times(3)).listCollections(any(String.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testListCollectionsWithIllegalListener() { - kuzzle.listCollections("index", null); - } - - @Test(expected = RuntimeException.class) - public void testListCollectionException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("collections", mock(JSONArray.class)))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.listCollections(listener); - } - - @Test(expected = RuntimeException.class) - public void testListCollectionQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.listCollections(listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListCollectionsIllegalDefaultIndex() { - kuzzle = spy(kuzzle); - kuzzle.setSuperDefaultIndex(null); - kuzzle.listCollections(null, mock(Options.class), listener); - } - - @Test - public void testListCollections() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("collections", mock(JSONArray.class)))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.listCollections(listener); - kuzzle.listCollections(mock(Options.class), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "list"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/listIndexesTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/listIndexesTest.java deleted file mode 100644 index 99e30e7f..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/listIndexesTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class listIndexesTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testAllSignaturesVariant() { - kuzzle = spy(kuzzle); - kuzzle.listIndexes(spy(listener)); - verify(kuzzle).listIndexes(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testListIndexesWithIllegalListener() { - kuzzle.listIndexes(null); - } - - @Test(expected = RuntimeException.class) - public void testListIndexesException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("indexes", new JSONArray().put("foo")))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.listIndexes(listener); - } - - @Test(expected = RuntimeException.class) - public void testListIndexesQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.listIndexes(listener); - } - - @Test - public void testListIndexes() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("indexes", new JSONArray().put("foo")))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.listIndexes(listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "index"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "list"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/loginTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/loginTest.java deleted file mode 100644 index 57c6db59..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/loginTest.java +++ /dev/null @@ -1,159 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class loginTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void checkAllSignaturesVariants() { - JSONObject stubCredentials = new JSONObject(); - kuzzle = spy(kuzzle); - listener = spy(listener); - kuzzle.login("foo", stubCredentials); - kuzzle.login("foo", stubCredentials, 42); - kuzzle.login("foo", stubCredentials, listener); - kuzzle.login("foo"); - kuzzle.login("foo", 42); - kuzzle.login("foo", 42, listener); - kuzzle.login("foo", listener); - verify(kuzzle, times(7)).login(any(String.class), any(JSONObject.class), any(int.class), any(ResponseListener.class)); - } - - @Test - public void testLogin() throws JSONException { - kuzzle = spy(kuzzle); - - ResponseListener listenerSpy = spy(listener); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_type", "type"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.login("local", new JSONObject().put("username", "username").put("password", "password")); - kuzzle.login("local", new JSONObject().put("username", "username").put("password", "password"), 42); - kuzzle.login("local", new JSONObject().put("username", "username").put("password", "password"), 42, listenerSpy); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "login"); - } - - @Test(expected = IllegalArgumentException.class) - public void testNoStrategy() { - kuzzle.login(null, new JSONObject()); - } - - @Test - public void testLoginAttemptEvent() throws JSONException { - kuzzle = spy(kuzzle); - kuzzle.addListener(Event.loginAttempt, mock(EventListener.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("jwt", "token"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.login("local", new JSONObject()); - verify(kuzzle, times(2)).emitEvent(any(Event.class), any(Object.class)); - } - - @Test(expected = RuntimeException.class) - public void testLoginQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.login("local", new JSONObject()); - } - - @Test(expected = RuntimeException.class) - public void testLoginOnSuccessException() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("jwt", "token"))); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(kuzzle).setJwtToken(any(String.class)); - kuzzle.login("local", new JSONObject()); - } - - @Test(expected = RuntimeException.class) - public void testLoginOnErrorException() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(kuzzle).emitEvent(any(Event.class), any(Object.class)); - kuzzle.login("local", new JSONObject()); - } - - @Test(expected = RuntimeException.class) - public void testSetJwtTokenException() { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).emitEvent(any(Event.class), any(Object.class)); - kuzzle.setJwtToken("foo"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/logoutTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/logoutTest.java deleted file mode 100644 index 7e87afc2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/logoutTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class logoutTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void checkAllSignaturesVariants() { - kuzzle = spy(kuzzle); - kuzzle.logout(); - verify(kuzzle).logout(any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testLogoutException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("hits", new JSONArray().put("foo")))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.logout(listener); - } - - @Test(expected = RuntimeException.class) - public void testLogoutQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.logout(listener); - } - - @Test - public void testLogout() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - - final JSONObject response = new JSONObject("{\"result\": {\"jwt\": \"jwtToken\"}}"); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.login("local", new JSONObject().put("username", "username").put("password", "password")); - kuzzle.logout(); - kuzzle.logout(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "logout"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/nowTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/nowTest.java deleted file mode 100644 index 7abdb61f..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/nowTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class nowTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void checkAllSignaturesVariants() { - listener = spy(listener); - kuzzle = spy(kuzzle); - kuzzle.now(listener); - verify(kuzzle).now(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testNowIllegalListener() { - kuzzle = spy(kuzzle); - kuzzle.now(null); - } - - @Test(expected = RuntimeException.class) - public void testNowException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("now", mock(JSONObject.class)))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.now(listener); - } - - @Test(expected = RuntimeException.class) - public void testNowQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.now(listener); - } - - @Test - public void testNow() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("now", 42424242))); - ((OnQueryDoneListener)invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.now(listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "server"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "now"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/offlineQueueLoaderTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/offlineQueueLoaderTest.java deleted file mode 100644 index d881e2e6..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/offlineQueueLoaderTest.java +++ /dev/null @@ -1,230 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.KuzzleQueue; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.OfflineQueueLoader; -import io.kuzzle.sdk.util.QueryObject; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class offlineQueueLoaderTest { - - private KuzzleExtend kuzzleExtend; - private WebSocketClient s; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - s = mock(WebSocketClient.class); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - kuzzleExtend = extended; - } - - - @Test - public void testOfflineQueueLoader() throws JSONException, URISyntaxException, InterruptedException { - kuzzleExtend = spy(kuzzleExtend); - kuzzleExtend.setAutoReplay(true); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.setState(States.READY); - kuzzleExtend.setAutoReplay(false); - OfflineQueueLoader offlineQueueLoader = new OfflineQueueLoader() { - @Override - public KuzzleQueue load() { - KuzzleQueue queue = new KuzzleQueue(); - QueryObject query = new QueryObject(); - try { - query.setQuery(new JSONObject().put("action", "foo").put("requestId", "42").put("controller", "ctrl")); - } catch (JSONException e) { - e.printStackTrace(); - } - queue.addToQueue(query); - return queue; - } - }; - kuzzleExtend.setOfflineQueueLoader(offlineQueueLoader); - - kuzzleExtend.replayQueue(); - ArgumentCaptor argument = ArgumentCaptor.forClass(JSONObject.class); - Thread.sleep(1000); - verify(kuzzleExtend, times(2)).emitRequest((JSONObject) argument.capture(), any(OnQueryDoneListener.class)); - assertEquals(((JSONObject) argument.getAllValues().get(0)).getString("action"), "bar"); - assertEquals(((JSONObject) argument.getAllValues().get(1)).getString("action"), "foo"); - } - - @Test(expected = IllegalArgumentException.class) - public void testOfflineQueueLoaderIllegalRequestId() throws JSONException, URISyntaxException { - - kuzzleExtend = spy(kuzzleExtend); - kuzzleExtend.setAutoReplay(true); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.setState(States.READY); - kuzzleExtend.setAutoReplay(false); - OfflineQueueLoader offlineQueueLoader = new OfflineQueueLoader() { - @Override - public KuzzleQueue load() { - KuzzleQueue queue = new KuzzleQueue(); - QueryObject query = new QueryObject(); - try { - query.setQuery(new JSONObject().put("action", "foo").put("controller", "ctrl")); - } catch (JSONException e) { - e.printStackTrace(); - } - queue.addToQueue(query); - return queue; - } - }; - kuzzleExtend.setOfflineQueueLoader(offlineQueueLoader); - - kuzzleExtend.replayQueue(); - } - - @Test(expected = IllegalArgumentException.class) - public void testOfflineQueueLoaderIllegalController() throws JSONException, URISyntaxException { - kuzzleExtend = spy(kuzzleExtend); - kuzzleExtend.setAutoReplay(true); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.setState(States.READY); - kuzzleExtend.setAutoReplay(false); - OfflineQueueLoader offlineQueueLoader = new OfflineQueueLoader() { - @Override - public KuzzleQueue load() { - KuzzleQueue queue = new KuzzleQueue(); - QueryObject query = new QueryObject(); - try { - query.setQuery(new JSONObject().put("action", "foo").put("requestId", "42")); - } catch (JSONException e) { - e.printStackTrace(); - } - queue.addToQueue(query); - return queue; - } - }; - kuzzleExtend.setOfflineQueueLoader(offlineQueueLoader); - - - kuzzleExtend.replayQueue(); - } - - @Test(expected = IllegalArgumentException.class) - public void testOfflineQueueLoaderIllegalAction() throws JSONException, URISyntaxException { - kuzzleExtend = spy(kuzzleExtend); - kuzzleExtend.setAutoReplay(true); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.setState(States.READY); - kuzzleExtend.setAutoReplay(false); - OfflineQueueLoader offlineQueueLoader = new OfflineQueueLoader() { - @Override - public KuzzleQueue load() { - KuzzleQueue queue = new KuzzleQueue(); - QueryObject query = new QueryObject(); - try { - query.setQuery(new JSONObject().put("requestId", "42").put("controller", "ctrl")); - } catch (JSONException e) { - e.printStackTrace(); - } - queue.addToQueue(query); - return queue; - } - }; - kuzzleExtend.setOfflineQueueLoader(offlineQueueLoader); - - kuzzleExtend.replayQueue(); - } - - @Test - public void testOfflineQueueDuplicateRequestId() throws JSONException, URISyntaxException, InterruptedException { - kuzzleExtend = spy(kuzzleExtend); - kuzzleExtend.setAutoReplay(true); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject().put("requestId", "42"), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.setState(States.READY); - kuzzleExtend.setAutoReplay(false); - OfflineQueueLoader offlineQueueLoader = new OfflineQueueLoader() { - @Override - public KuzzleQueue load() { - KuzzleQueue queue = new KuzzleQueue(); - QueryObject query = new QueryObject(); - try { - query.setQuery(new JSONObject().put("action", "foo").put("requestId", "42").put("controller", "ctrl")); - } catch (JSONException e) { - e.printStackTrace(); - } - queue.addToQueue(query); - return queue; - } - }; - kuzzleExtend.setOfflineQueueLoader(offlineQueueLoader); - - kuzzleExtend.replayQueue(); - ArgumentCaptor argument = ArgumentCaptor.forClass(JSONObject.class); - Thread.sleep(1000); - verify(kuzzleExtend, times(1)).emitRequest((JSONObject) argument.capture(), any(OnQueryDoneListener.class)); - assertEquals(((JSONObject) argument.getAllValues().get(0)).getString("action"), "bar"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/queryTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/queryTest.java deleted file mode 100644 index 1b66c934..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/queryTest.java +++ /dev/null @@ -1,284 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.QueueFilter; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static junit.framework.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class queryTest { - private KuzzleExtend kuzzle; - private WebSocketClient socket = mock(WebSocketClient.class); - private Kuzzle.QueryArgs args; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setState(States.CONNECTED); - kuzzle.setSocket(socket); - - args = new Kuzzle.QueryArgs(); - args.controller = "foo"; - args.action = "bar"; - } - - @Test - public void checkAllSignaturesVariants() throws JSONException { - JSONObject query = new JSONObject(); - OnQueryDoneListener queryListener = mock(OnQueryDoneListener.class); - kuzzle = spy(kuzzle); - kuzzle.query(args, query); - kuzzle.query(args, query, new Options()); - kuzzle.query(args, query, queryListener); - verify(kuzzle, times(3)).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test(expected = IllegalStateException.class) - public void shouldThrowIfDisconnected() throws JSONException { - kuzzle.setState(States.DISCONNECTED); - kuzzle.query(args, new JSONObject()); - } - - @Test - public void shouldEmitTheRightRequest() throws JSONException { - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject request = new JSONObject(argument.getValue()); - assertEquals(request.getString("controller"), args.controller); - assertEquals(request.getString("action"), args.action); - assertEquals(request.getJSONObject("volatile").length(), 1); - assertEquals(request.has("index"), false); - assertEquals(request.has("collection"), false); - assertEquals(request.has("headers"), false); - assertNotNull(request.getString("requestId")); - } - - @Test - public void shouldAddIndexIfNeeded() throws JSONException { - args.index = "index"; - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject request = new JSONObject(argument.getValue()); - assertEquals(request.getString("controller"), args.controller); - assertEquals(request.getString("action"), args.action); - assertEquals(request.getString("index"), args.index); - assertEquals(request.has("collection"), false); - assertEquals(request.has("headers"), false); - assertEquals(request.getJSONObject("volatile").length(), 1); - assertNotNull(request.getString("requestId")); - } - - @Test - public void shouldAddCollectionIfNeeded() throws JSONException { - args.collection = "collection"; - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject request = new JSONObject(argument.getValue()); - assertEquals(request.getString("controller"), args.controller); - assertEquals(request.getString("action"), args.action); - assertEquals(request.getString("collection"), args.collection); - assertEquals(request.has("index"), false); - assertEquals(request.has("headers"), false); - assertEquals(request.getJSONObject("volatile").length(), 1); - assertNotNull(request.getString("requestId")); - } - - @Test - public void shouldAddJwtTokenIfNeeded() throws JSONException { - kuzzle.setJwtToken("token"); - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject request = new JSONObject(argument.getValue()); - assertEquals(request.getString("controller"), args.controller); - assertEquals(request.getString("action"), args.action); - assertEquals(request.getJSONObject("volatile").length(), 1); - assertEquals(request.has("index"), false); - assertEquals(request.has("collection"), false); - assertNotNull(request.getString("requestId")); - assertEquals(request.getString("jwt"), "token"); - } - - @Test - public void shouldNotAddJwtTokenIfCheckingToken() throws JSONException { - kuzzle.setJwtToken("token"); - args.controller = "auth"; - args.action = "checkToken"; - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject request = new JSONObject(argument.getValue()); - assertEquals(request.getString("controller"), args.controller); - assertEquals(request.getString("action"), args.action); - assertEquals(request.getJSONObject("volatile").length(), 1); - assertEquals(request.has("index"), false); - assertEquals(request.has("collection"), false); - assertEquals(request.has("headers"), false); - assertNotNull(request.getString("requestId")); - } - - @Test - public void shouldAddVolatile() throws JSONException { - JSONObject - kuzzleVolatile = new JSONObject().put("foo", "foo").put("bar", "bar"), - optionsVolatile = new JSONObject().put("qux", "qux").put("foo", "bar"); - Options opts = new Options().setVolatile(optionsVolatile); - - kuzzle.setVolatile(kuzzleVolatile); - kuzzle.query(args, new JSONObject(), opts); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject _volatile = new JSONObject(argument.getValue()).getJSONObject("volatile"); - assertEquals(_volatile.length(), 4); - assertEquals(_volatile.getString("sdkVersion"), kuzzle.getSdkVersion()); - assertEquals(_volatile.getString("foo"), "bar"); // options take precedence over kuzzle volatile data - assertEquals(_volatile.getString("bar"), "bar"); - assertEquals(_volatile.getString("qux"), "qux"); - } - - @Test - public void shouldSendSdkVersionInVolatile() throws JSONException { - kuzzle.query(args, new JSONObject(), new Options()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - JSONObject _volatile = new JSONObject(argument.getValue()).getJSONObject("volatile"); - assertEquals(_volatile.length(), 1); - assertEquals(_volatile.getString("sdkVersion"), kuzzle.getSdkVersion()); - } - - @Test - public void shouldAddRefresh() throws JSONException { - String optionsRefresh = "foo"; - Options opts = new Options().setRefresh(optionsRefresh); - - kuzzle.query(args, new JSONObject(), opts); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - String refresh = new JSONObject(argument.getValue()).getString("refresh"); - assertEquals(refresh, optionsRefresh); - } - - @Test - public void shouldAddHeaders() throws JSONException { - JSONObject headers = new JSONObject().put("foo", "bar"); - - kuzzle.setHeaders(headers); - - kuzzle.query(args, new JSONObject()); - - ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); - verify(socket).send(argument.capture()); - - assertEquals(new JSONObject(argument.getValue()).getString("foo"), "bar"); - } - - @Test - public void shouldEmitRequestIfConnected() throws JSONException { - Options opts = new Options().setQueuable(false); - kuzzle.setState(States.CONNECTED); - KuzzleExtend kuzzleSpy = spy(kuzzle); - kuzzleSpy.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - verify(kuzzleSpy).emitRequest(any(JSONObject.class), any(OnQueryDoneListener.class)); - assertEquals(kuzzleSpy.getOfflineQueue().size(), 0); - } - - @Test - public void shouldQueueRequestsIfNotConnected() throws JSONException { - Options opts = new Options().setQueuable(true); - kuzzle.setState(States.OFFLINE); - kuzzle.startQueuing(); - - KuzzleExtend kuzzleSpy = spy(kuzzle); - kuzzleSpy.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - verify(kuzzleSpy, never()).emitRequest(any(JSONObject.class), any(OnQueryDoneListener.class)); - assertEquals(kuzzleSpy.getOfflineQueue().size(), 1); - } - - @Test - public void shouldFilterRequestBeforeQueuingIt() throws JSONException { - Options opts = new Options().setQueuable(true); - QueueFilter filter = spy(new QueueFilter() { - @Override - public boolean filter(JSONObject object) { - return false; - } - }); - - kuzzle.setQueueFilter(filter); - kuzzle.setState(States.OFFLINE); - kuzzle.startQueuing(); - - KuzzleExtend kuzzleSpy = spy(kuzzle); - kuzzleSpy.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - verify(kuzzleSpy, never()).emitRequest(any(JSONObject.class), any(OnQueryDoneListener.class)); - verify(filter).filter(any(JSONObject.class)); - assertEquals(kuzzleSpy.getOfflineQueue().size(), 0); - } - - @Test - public void shouldDiscardQueuableRequestWhenNotConnected() throws JSONException { - Options opts = new Options().setQueuable(false); - kuzzle.setState(States.OFFLINE); - OnQueryDoneListener listener = mock(OnQueryDoneListener.class); - - KuzzleExtend kuzzleSpy = spy(kuzzle); - kuzzleSpy.query(args, new JSONObject(), opts, listener); - verify(kuzzleSpy, never()).emitRequest(any(JSONObject.class), any(OnQueryDoneListener.class)); - verify(listener).onError(any(JSONObject.class)); - } - - @Test - public void shouldDiscardNonQueuedRequestWhenNotConnected() throws JSONException { - Options opts = new Options().setQueuable(false); - kuzzle.setState(States.OFFLINE); - kuzzle.stopQueuing(); - OnQueryDoneListener listener = mock(OnQueryDoneListener.class); - - KuzzleExtend kuzzleSpy = spy(kuzzle); - kuzzleSpy.query(args, new JSONObject(), opts, listener); - verify(kuzzleSpy, never()).emitRequest(any(JSONObject.class), any(OnQueryDoneListener.class)); - verify(listener).onError(any(JSONObject.class)); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/queueManagementTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/queueManagementTest.java deleted file mode 100644 index 1115cb42..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/queueManagementTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Date; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.QueryObject; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.QueryArgsHelper; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -public class queueManagementTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testFlushQueue() throws URISyntaxException, JSONException { - Options options = new Options(); - options.setQueueTTL(1); - options.setAutoReplay(true); - options.setConnect(Mode.MANUAL); - options.setAutoReconnect(true); - options.setOfflineMode(Mode.AUTO); - - kuzzle = new KuzzleExtend("localhost", options, null); - QueryObject o = new QueryObject(); - o.setTimestamp(new Date()); - o.setAction("test"); - o.setQuery(new JSONObject("{\"controller\":\"test\",\"volatile\":{},\"requestId\":\"a476ae61-497e-4338-b4dd-751ac22c6b61\",\"action\":\"test\",\"collection\":\"test\"}")); - kuzzle.getOfflineQueue().add(o); - o.setQuery(new JSONObject("{\"controller\":\"test2\",\"volatile\":{},\"requestId\":\"a476ae61-497e-4338-b4dd-751ac22c6b61\",\"action\":\"test2\",\"collection\":\"test2\"}")); - kuzzle.getOfflineQueue().add(o); - assertEquals(kuzzle.getOfflineQueue().size(), 2); - kuzzle.flushQueue(); - assertEquals(kuzzle.getOfflineQueue().size(), 0); - } - - @Test - public void testManualQueuing() throws URISyntaxException, JSONException { - Options options = new Options(); - options.setAutoReconnect(true); - options.setAutoQueue(false); - options.setDefaultIndex("testIndex"); - options.setQueueTTL(10000); - options.setReplayInterval(1); - options.setConnect(Mode.MANUAL); - options.setQueuable(false); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - extended.setState(States.CONNECTED); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - s.onCloseReceived(); - return s; - } - }).when(s).close(); - extended.connect(); - extended.startQueuing(); - JSONObject query = new JSONObject(); - query.put("requestId", "42"); - extended.query(QueryArgsHelper.makeQueryArgs("test", "test"), query, null, null); - assertEquals(extended.getOfflineQueue().size(), 1); - extended.flushQueue(); - extended.stopQueuing(); - assertEquals(extended.getOfflineQueue().size(), 0); - extended.query(QueryArgsHelper.makeQueryArgs("test", "test"), query, options, null); - assertEquals(extended.getOfflineQueue().size(), 0); - } - - @Test - public void testQueuable() throws URISyntaxException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - s.onCloseReceived(); - return s; - } - }).when(s).close(); - Options options = new Options(); - options.setAutoReconnect(false); - options.setDefaultIndex("testIndex"); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.connect(); - kuzzle.listCollections(mock(ResponseListener.class)); - assertEquals(kuzzle.getOfflineQueue().size(), 1); - kuzzle.flushQueue(); - options.setQueuable(false); - kuzzle.listCollections(options, mock(ResponseListener.class)); - assertEquals(kuzzle.getOfflineQueue().size(), 0); - } - - @Test - public void testQueueMaxSize() throws URISyntaxException, JSONException { - Options options = new Options(); - options.setAutoReconnect(true); - options.setAutoQueue(true); - options.setQueueTTL(1000); - options.setQueueMaxSize(1); - options.setAutoReplay(true); - options.setConnect(Mode.MANUAL); - options.setOfflineMode(Mode.AUTO); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - s.onCloseReceived(); - return s; - } - }).when(s).close(); - kuzzle.connect(); - kuzzle.query(QueryArgsHelper.makeQueryArgs("test", "test"), new JSONObject(), mock(OnQueryDoneListener.class)); - kuzzle.query(QueryArgsHelper.makeQueryArgs("test2", "test2"), new JSONObject()); - kuzzle.query(QueryArgsHelper.makeQueryArgs("test3", "test3"), new JSONObject()); - assertEquals(kuzzle.getOfflineQueue().size(), 1); - assertEquals(kuzzle.getOfflineQueue().peek().getQuery().getString("controller"), "test3"); - verify(s, never()).send(any(String.class)); - } - - - @Test - public void testDequeue() throws URISyntaxException, JSONException { - Options options = new Options(); - options.setAutoReconnect(true); - options.setQueueTTL(10000); - options.setAutoReplay(true); - options.setReplayInterval(1); - options.setConnect(Mode.MANUAL); - options.setOfflineMode(Mode.AUTO); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - s.onCloseReceived(); - return s; - } - }).when(s).close(); - kuzzle.connect(); - - QueryObject o = new QueryObject(); - o.setTimestamp(new Date()); - o.setAction("test"); - - JSONObject query = new JSONObject("{\"controller\":\"test3\",\"volatile\":{},\"requestId\":\"a476ae61-497e-4338-b4dd-751ac22c6b61\",\"action\":\"test3\",\"collection\":\"test3\"}"); - o.setQuery(query); - kuzzle.getOfflineQueue().add(o); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - s.onOpen(); - return s; - } - }).when(s).connect(); - kuzzle.connect(); - kuzzle.setAutoReplay(false); - kuzzle.replayQueue(); - verify(s, atLeastOnce()).send(eq(query.toString())); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/refreshIndexTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/refreshIndexTest.java deleted file mode 100644 index 1b0ba1f9..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/refreshIndexTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import java.net.URISyntaxException; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - - -public class refreshIndexTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setup() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = mock(ResponseListener.class); - } - - @Test - public void testAllSignatureVariants() { - Options options = mock(Options.class); - - kuzzle = spy(kuzzle); - - kuzzle.refreshIndex(); - kuzzle.refreshIndex(options); - kuzzle.refreshIndex(options, listener); - kuzzle.refreshIndex(listener); - kuzzle.refreshIndex("foo"); - kuzzle.refreshIndex("foo", options); - kuzzle.refreshIndex("foo", listener); - - verify(kuzzle, times(7)).refreshIndex(any(String.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testRefreshIndexException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_shards", new JSONObject()))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.refreshIndex(listener); - } - - @Test(expected = RuntimeException.class) - public void testRefreshIndexQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.refreshIndex(listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testRefreshIndexIllegalDefaultIndex() { - kuzzle = spy(kuzzle); - kuzzle.setSuperDefaultIndex(null); - kuzzle.refreshIndex(null, mock(Options.class), listener); - } - - @Test - public void testRefreshIndex() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_shards", new JSONObject()))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.refreshIndex(); - kuzzle.refreshIndex(listener); - kuzzle.refreshIndex(mock(Options.class), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "index"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "refresh"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).index, kuzzle.getDefaultIndex()); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/setAutoRefreshTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/setAutoRefreshTest.java deleted file mode 100644 index 18ca029a..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/setAutoRefreshTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class setAutoRefreshTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - - @Before - public void setup() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = mock(ResponseListener.class); - } - - @Test - public void testSignatureVariants() { - Options options = mock(Options.class); - - kuzzle = spy(kuzzle); - - kuzzle.setAutoRefresh(true); - kuzzle.setAutoRefresh(true, options); - kuzzle.setAutoRefresh(true, options, listener); - kuzzle.setAutoRefresh("foo", true); - kuzzle.setAutoRefresh("foo", true, options); - kuzzle.setAutoRefresh("foo", true, listener); - - verify(kuzzle, times(6)).setAutoRefresh(any(String.class), any(Boolean.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testSetAutoRefreshException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONArray.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.setAutoRefresh(true, listener); - } - - @Test(expected = RuntimeException.class) - public void testSetAutoRefreshQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.setAutoRefresh(true, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetAutoRefreshIllegalDefaultIndex() { - kuzzle = spy(kuzzle); - kuzzle.setSuperDefaultIndex(null); - kuzzle.setAutoRefresh(null, true, mock(Options.class), listener); - } - - @Test - public void testGetAutoRefresh() throws URISyntaxException, JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.setAutoRefresh(true); - kuzzle.setAutoRefresh(true, listener); - kuzzle.setAutoRefresh(true, mock(Options.class), listener); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - ArgumentCaptor request = ArgumentCaptor.forClass(JSONObject.class); - verify(kuzzle, times(3)).query((Kuzzle.QueryArgs) argument.capture(), (JSONObject) request.capture(), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "index"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "setAutoRefresh"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).index, kuzzle.getDefaultIndex()); - assertEquals(((JSONObject) request.getValue()).getJSONObject("body").getBoolean("autoRefresh"), true); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/setJwtTokenTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/setJwtTokenTest.java deleted file mode 100644 index 35d0d5b1..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/setJwtTokenTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.TestCase.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class setJwtTokenTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(s); - - kuzzle = spy(kuzzle); - doNothing().when(kuzzle).renewSubscriptions(); - doNothing().when(kuzzle).emitEvent(any(Event.class), any(JSONObject.class)); - } - - @Test - public void shouldHandleStringToken() throws JSONException { - kuzzle.setJwtToken("foobar"); - assertEquals("foobar", kuzzle.getJwtToken()); - - ArgumentCaptor loginResult = ArgumentCaptor.forClass(JSONObject.class); - verify(kuzzle).emitEvent(eq(Event.loginAttempt), (JSONObject)loginResult.capture()); - assertTrue(((JSONObject) loginResult.getValue()).getBoolean("success")); - - verify(kuzzle).renewSubscriptions(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowWithNullKuzzleResponse() throws JSONException { - kuzzle.setJwtToken((JSONObject) null); - } - - @Test - public void shouldHandleValidKuzzleResponse() throws JSONException { - JSONObject validResponse = new JSONObject() - .put("result", new JSONObject() - .put("jwt", "foobar") - ); - - kuzzle.setJwtToken(validResponse); - assertEquals("foobar", kuzzle.getJwtToken()); - - ArgumentCaptor loginResult = ArgumentCaptor.forClass(JSONObject.class); - verify(kuzzle).emitEvent(eq(Event.loginAttempt), (JSONObject)loginResult.capture()); - assertTrue(((JSONObject) loginResult.getValue()).getBoolean("success")); - - verify(kuzzle).renewSubscriptions(); - } - - @Test - public void shouldHandleInvalidResponse() throws JSONException { - kuzzle.setJwtToken(new JSONObject()); - assertNull(kuzzle.getJwtToken()); - - ArgumentCaptor loginResult = ArgumentCaptor.forClass(JSONObject.class); - verify(kuzzle).emitEvent(eq(Event.loginAttempt), (JSONObject)loginResult.capture()); - assertFalse(((JSONObject) loginResult.getValue()).getBoolean("success")); - - verify(kuzzle, never()).renewSubscriptions(); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/subscriptionsManagementTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/subscriptionsManagementTest.java deleted file mode 100644 index 27a1b127..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/subscriptionsManagementTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.lang.reflect.InvocationTargetException; -import java.net.URISyntaxException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -public class subscriptionsManagementTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testDeleteSubscription() throws JSONException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Map> subscriptions = kuzzle.getSubscriptions(); - - subscriptions.put("foo", new ConcurrentHashMap()); - subscriptions.get("foo").put("bar", mock(Room.class)); - subscriptions.get("foo").put("baz", mock(Room.class)); - subscriptions.get("foo").put("qux", mock(Room.class)); - - kuzzle.deleteSubscription("foobar", "whatever"); - - // there is always a "pending" room ID used to store pending subscriptions - assertEquals(subscriptions.keySet().size(), 2); - assertEquals(subscriptions.get("pending").size(), 0); - assertEquals(subscriptions.get("foo").size(), 3); - - kuzzle.deleteSubscription("foo", "baz"); - - assertEquals(subscriptions.keySet().size(), 2); - assertEquals(subscriptions.get("pending").size(), 0); - assertEquals(subscriptions.get("foo").size(), 2); - - kuzzle.deleteSubscription("foo", "qux"); - - assertEquals(subscriptions.keySet().size(), 2); - assertEquals(subscriptions.get("pending").size(), 0); - assertEquals(subscriptions.get("foo").size(), 1); - - kuzzle.deleteSubscription("foo", "bar"); - - assertEquals(subscriptions.keySet().size(), 1); - assertEquals(subscriptions.get("pending").size(), 0); - assertEquals(subscriptions.containsKey("foo"), false); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/unsetJwtTokenTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/unsetJwtTokenTest.java deleted file mode 100644 index b861f2c2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/unsetJwtTokenTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; -import java.util.concurrent.ConcurrentHashMap; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleDataCollectionExtend; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class unsetJwtTokenTest { - private KuzzleExtend kuzzle; - private WebSocketClient s; - private ConcurrentHashMap chp = new ConcurrentHashMap<>(); - private Room room; - - @Before - public void setUp() throws URISyntaxException { - kuzzle = new KuzzleExtend("host", mock(Options.class), mock(ResponseListener.class)); - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - s = mock(WebSocketClient.class); - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.getSubscriptions().put("1", chp); - kuzzle.setSocket(s); - - kuzzle = spy(kuzzle); - doNothing().when(kuzzle).emitEvent(any(Event.class), any(JSONObject.class)); - room = spy(new RoomExtend(new KuzzleDataCollectionExtend(kuzzle, "index", "collection"))); - chp.put("2", room); - } - - @Test - public void shouldUnsetTokenAndUnsubscribeAllRoom() { - kuzzle.setJwtTokenWithoutSubscribe("42"); - kuzzle.unsetJwtToken(); - assertEquals(null, kuzzle.getJwtToken()); - verify(room).unsubscribe(); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateMyCredentialsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateMyCredentialsTest.java deleted file mode 100644 index 9fed407c..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateMyCredentialsTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class updateMyCredentialsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - private JSONObject credentials; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - try { - credentials = new JSONObject() - .put("foo", "bar"); - } catch (JSONException err) { - throw new RuntimeException(err); - } - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testUpdateMyCredentialsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.updateMyCredentials("strategy", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testUpdateMyCredentialsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.updateMyCredentials("strategy", credentials, null, listener); - } - - @Test - public void testUpdateMyCredentials() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzle.updateMyCredentials("strategy", credentials) - .updateMyCredentials("strategy", credentials, mock(Options.class)) - .updateMyCredentials("strategy", credentials, mock(ResponseListener.class)) - .updateMyCredentials("strategy", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateMyCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateSelfTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateSelfTest.java deleted file mode 100644 index f5acfe31..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/updateSelfTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class updateSelfTest { - - Kuzzle kuzzle; - ArgumentCaptor argument; - ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - kuzzle = spy(new Kuzzle("localhost")); - argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - listener = spy(new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); - } - - @Test(expected = RuntimeException.class) - public void testUpdateSelfException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.updateSelf(mock(JSONObject.class)); - } - - @Test - public void testUpdateSelf() throws JSONException { - JSONObject content = new JSONObject(); - content.put("foo", "bar"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.updateSelf(content, listener); - kuzzle.updateSelf(content, mock(Options.class)); - kuzzle.updateSelf(content, mock(Options.class), listener); - kuzzle.updateSelf(content); - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(listener, times(2)).onSuccess(any(JSONObject.class)); - verify(listener, times(2)).onError(any(JSONObject.class)); - assertEquals("auth", ((Kuzzle.QueryArgs)argument.getValue()).controller); - assertEquals("updateSelf", ((Kuzzle.QueryArgs)argument.getValue()).action); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/validateMyCredentialsTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/validateMyCredentialsTest.java deleted file mode 100644 index 9f6178e3..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/validateMyCredentialsTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class validateMyCredentialsTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - private JSONObject credentials; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - - try { - credentials = new JSONObject() - .put("foo", "bar"); - } catch (JSONException err) { - throw new RuntimeException(err); - } - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testValidateMyCredentialsException() throws JSONException { - listener = spy(listener); - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.validateMyCredentials("strategy", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testValidateMyCredentialsQueryException() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.validateMyCredentials("strategy", credentials, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzle.validateMyCredentials(null, null, null); - } - - @Test - public void testValidateMyCredentials() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzle.validateMyCredentials("strategy", credentials, mock(ResponseListener.class)); - kuzzle.validateMyCredentials("strategy", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "validateMyCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/Kuzzle/whoAmiTest.java b/test/main/java/io/kuzzle/sdk/core/Kuzzle/whoAmiTest.java deleted file mode 100644 index f7867539..00000000 --- a/test/main/java/io/kuzzle/sdk/core/Kuzzle/whoAmiTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package main.java.io.kuzzle.sdk.core.Kuzzle; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class whoAmiTest { - private KuzzleExtend kuzzle; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - options.setDefaultIndex("testIndex"); - - kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setSocket(mock(WebSocketClient.class)); - - listener = new ResponseListener() { - @Override - public void onSuccess(Object object) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test - public void testWhoAmIValid() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject() - .put("result", new JSONObject() - .put("_id", "test") - .put("_source", new JSONObject() - .put("profile", new JSONObject() - .put("_id", "admin") - .put("roles", "") - ) - ) - .put("_meta", new JSONObject()) - ) - ); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzle.whoAmI(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "auth"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getCurrentUser"); - } - - @Test(expected = RuntimeException.class) - public void testWhoAmIInvalid() throws JSONException { - kuzzle = spy(kuzzle); - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.whoAmI(mock(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testWhoAmINoListener() throws JSONException { - kuzzle.whoAmI(null); - } - - @Test(expected = RuntimeException.class) - public void testWhoAmIInvalidResponse() throws JSONException { - kuzzle = spy(kuzzle); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener)invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzle.whoAmI(mock(ResponseListener.class)); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/constructorTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/constructorTest.java deleted file mode 100644 index 7d14acec..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/constructorTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class constructorTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.setHeaders(new JSONObject()); - verify(collection).setHeaders(any(JSONObject.class), eq(false)); - } - - @Test(expected = RuntimeException.class) - public void testSetHeaders() throws JSONException { - when(kuzzle.getHeaders()).thenCallRealMethod(); - when(kuzzle.setHeaders(any(JSONObject.class), anyBoolean())).thenCallRealMethod(); - JSONObject content = new JSONObject(); - content.put("foo", "bar"); - collection.setHeaders(content); - assertEquals(collection.getHeaders().getString("foo"), "bar"); - content.put("foo", "baz"); - collection.setHeaders(content, true); - assertEquals(collection.getHeaders().getString("foo"), "baz"); - content.put("bar", "foo"); - collection.setHeaders(content, false); - assertEquals(collection.getHeaders().getString("foo"), "baz"); - assertEquals(collection.getHeaders().getString("bar"), "foo"); - collection.setHeaders(null, false); - assertEquals(collection.getHeaders().getString("foo"), "baz"); - assertEquals(collection.getHeaders().getString("bar"), "foo"); - collection.setHeaders(null, true); - assertEquals(collection.getHeaders().length(), 0); - JSONObject fake = spy(new JSONObject()); - doThrow(JSONException.class).when(fake).keys(); - collection.setHeaders(fake, false); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowIfNoKuzzleInstanceProvided() { - new Collection(null, "foo", "bar"); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowIfNoIndexProvided() { - new Collection(mock(Kuzzle.class), "foo", null); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowIfNoCollectionProvided() { - new Collection(mock(Kuzzle.class), null, "foo"); - } - - @Test(expected = RuntimeException.class) - public void testConstructorException() { - doThrow(JSONException.class).when(kuzzle).getHeaders(); - new Collection(kuzzle, "collections", "foo"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/countTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/countTest.java deleted file mode 100644 index 2ab334f6..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/countTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class countTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - JSONObject filters = mock(JSONObject.class); - collection = spy(collection); - collection.count(filters, listener); - verify(collection).count(eq(filters), eq((Options) null), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testCountIllegalListener() { - collection.count(null); - } - - @Test(expected = RuntimeException.class) - public void testCountQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.count(listener); - } - - @Test(expected = RuntimeException.class) - public void testCountException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - collection.count(listener); - } - - @Test - public void testCount() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - JSONObject filters = new JSONObject(); - collection.count(filters, listener); - collection.count(filters, new Options(), listener); - collection.count(listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "count"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createDocumentTest.java deleted file mode 100644 index f48c983c..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createDocumentTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class createDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() throws JSONException { - Document doc = mock(Document.class); - JSONObject content = new JSONObject(); - String id = "foo"; - Options opts = new Options(); - - collection = spy(collection); - - collection.createDocument(doc); - collection.createDocument(doc, opts); - collection.createDocument(doc, listener); - collection.createDocument(doc, opts, listener); - - collection.createDocument(id, content); - collection.createDocument(id, content, opts); - collection.createDocument(id, content, listener); - collection.createDocument(id, content, opts, listener); - - collection.createDocument(content); - collection.createDocument(content, opts); - collection.createDocument(content, listener); - collection.createDocument(content, opts, listener); - - verify(collection, times(12)).createDocument(any(Document.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testCreateDocumentQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.createDocument(mock(Document.class), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateDocumentIllegalIfExistValue() { - Options opts = new Options(); - - opts.setIfExist("foobar"); - } - - @Test(expected = RuntimeException.class) - public void testCreateDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.createDocument(mock(Document.class), listener); - } - - @Test - public void testCreateDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", new JSONObject() - .put("_id", "foo") - .put("_version", 1337) - .put("_source", new JSONObject()) - .put("_meta", new JSONObject())); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - collection.createDocument(doc); - collection.createDocument(doc, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "create"); - } - - @Test - public void testCreateDocumentWithOptions() throws JSONException { - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - Options options = new Options(); - options.setIfExist("replace"); - collection.createDocument(doc, options); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplace"); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateDocumentWithIllegalContent() throws JSONException { - collection.createDocument("id", null, mock(Options.class), listener); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createTest.java deleted file mode 100644 index 16c1af25..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/createTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import io.kuzzle.sdk.core.Kuzzle.QueryArgs; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class createTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - - collection.create(); - collection.create(mock(Options.class)); - collection.create(listener); - collection.create(mock(Options.class), listener); - collection.create(mock(JSONObject.class)); - collection.create(mock(JSONObject.class), mock(Options.class)); - collection.create(mock(JSONObject.class), listener); - - verify(collection, times(7)).create(any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testCreateQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.create(listener); - } - - @Test(expected = RuntimeException.class) - public void testCreateException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - return null; - } - }).when(kuzzle).query(any(QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.create(listener); - } - - @Test - public void testCreateWithoutMapping() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.create(new Options(), listener); - collection.create(listener); - collection.create(new Options()); - collection.create(); - - ArgumentCaptor argument = ArgumentCaptor.forClass(QueryArgs.class); - verify(kuzzle, times(4)).query((QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((QueryArgs) argument.getValue()).action, "create"); - } - - @Test - public void testCreateWithMapping() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - JSONObject mapping = new JSONObject().put("foo", "bar"); - - collection.create(mapping); - collection.create(mapping, new Options(), listener); - collection.create(mapping, listener); - collection.create(mapping, new Options()); - - ArgumentCaptor - capturedQargs = ArgumentCaptor.forClass(QueryArgs.class), - capturedMappings = ArgumentCaptor.forClass(JSONObject.class); - - verify(kuzzle, times(4)).query((QueryArgs)capturedQargs.capture(), (JSONObject)capturedMappings.capture(), any(Options.class), any(OnQueryDoneListener.class)); - - assertEquals(((QueryArgs) capturedQargs.getValue()).controller, "collection"); - assertEquals(((QueryArgs) capturedQargs.getValue()).action, "create"); - - String expected = (new JSONObject().put("body", mapping)).toString(); - for (Object m : capturedMappings.getAllValues()) { - assertEquals(expected, m.toString()); - } - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteDocumentTest.java deleted file mode 100644 index 734baba9..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteDocumentTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleDataCollectionExtend; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class deleteDocumentTest { - private Kuzzle kuzzle; - private KuzzleDataCollectionExtend collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new KuzzleDataCollectionExtend(kuzzle, "index", "test"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - JSONObject filters = new JSONObject(); - Options opts = mock(Options.class); - collection = spy(collection); - - collection.deleteDocument("foo"); - collection.deleteDocument("foo", opts); - collection.deleteDocument("foo", listener); - collection.deleteDocument("foo", opts, listener); - - collection.deleteDocument(filters); - collection.deleteDocument(filters, opts); - collection.deleteDocument(filters, listener); - collection.deleteDocument(filters, opts, listener); - - verify(collection, times(8)).deleteDocument(any(String.class), any(JSONObject.class), any(Options.class), any(ResponseListener.class), any(ResponseListener.class)); - } - - @Test - public void testDeleteDocumentByFilter() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("hits", new JSONArray().put("val")))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.deleteDocument(new JSONObject(), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteByQuery"); - } - - @Test(expected = IllegalArgumentException.class) - public void testDeleteDocumentIllegalId() { - collection.deleteDocument((String) null); - } - - @Test(expected = IllegalArgumentException.class) - public void testDeleteDocumentIllegalFilter() { - collection.deleteDocument((JSONObject) null); - } - - @Test(expected = RuntimeException.class) - public void testDeleteDocumentQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.deleteDocument("id", listener); - } - - @Test(expected = RuntimeException.class) - public void testDeleteDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id-42"))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.deleteDocument("id", listener); - } - - @Test - public void testDeleteDocumentById() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id-42"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.deleteDocument("42", listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "delete"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteSpecificationsTest.java deleted file mode 100644 index 8d23701d..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/deleteSpecificationsTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleDataCollectionExtend; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class deleteSpecificationsTest { - private Kuzzle kuzzle; - private KuzzleDataCollectionExtend collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new KuzzleDataCollectionExtend(kuzzle, "index", "test"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkDeleteSpecificationsSignaturesVariants() throws JSONException { - Options opts = mock(Options.class); - collection = spy(collection); - - collection.deleteSpecifications(); - collection.deleteSpecifications(opts); - collection.deleteSpecifications(listener); - collection.deleteSpecifications(opts, listener); - - verify(collection, times(4)).deleteSpecifications(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testDeleteSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.deleteSpecifications(listener); - } - - @Test(expected = RuntimeException.class) - public void testDeleteSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("acknowledged", true))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.deleteSpecifications(listener); - } - - @Test - public void testDeleteSpecifications() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("acknowledged", true))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.deleteSpecifications(listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/documentExistsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/documentExistsTest.java deleted file mode 100644 index 4f99b28f..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/documentExistsTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class documentExistsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.documentExists("foo", listener); - verify(collection).documentExists(eq("foo"), eq((Options)null), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testDocumentExistsIllegalDocumentId() { - collection.documentExists(null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testDocumentExistsIllegalListener() { - collection.documentExists("id", null); - } - - @Test(expected = RuntimeException.class) - public void testDocumentExistsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.documentExists("id", listener); - } - - @Test(expected = RuntimeException.class) - public void testDocumentExistsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.documentExists("id", listener); - } - - @Test - public void testDocumentExists() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess( - new JSONObject() - .put("result", true) - ); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.documentExists("42", mock(ResponseListener.class)); - collection.documentExists("42", new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "exists"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/factoriesTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/factoriesTest.java deleted file mode 100644 index 0554dd8f..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/factoriesTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.CollectionMapping; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class factoriesTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void testRoomFactory() { - assertThat(collection.room(mock(RoomOptions.class)), instanceOf(Room.class)); - assertThat(collection.room(), instanceOf(Room.class)); - } - - @Test - public void testDocumentFactory() throws JSONException { - assertThat(collection.document(), instanceOf(Document.class)); - assertThat(collection.document("id"), instanceOf(Document.class)); - assertThat(collection.document("id", new JSONObject()), instanceOf(Document.class)); - assertThat(collection.document(new JSONObject()), instanceOf(Document.class)); - } - - @Test - public void testDataMappingFactory() { - assertThat(collection.collectionMapping(), instanceOf(CollectionMapping.class)); - assertThat(collection.collectionMapping(new JSONObject()), instanceOf(CollectionMapping.class)); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/fetchDocument.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/fetchDocument.java deleted file mode 100644 index f810d2b2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/fetchDocument.java +++ /dev/null @@ -1,115 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class fetchDocument { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.fetchDocument("foo", listener); - verify(collection).fetchDocument(eq("foo"), eq((Options)null), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testFetchDocumentIllegalDocumentId() { - collection.fetchDocument(null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testFetchDocumentIllegalListener() { - collection.fetchDocument("id", null); - } - - @Test(expected = RuntimeException.class) - public void testFetchDocumentQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.fetchDocument("id", listener); - } - - @Test(expected = RuntimeException.class) - public void testFetchDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.fetchDocument("id", listener); - } - - @Test - public void testFetchDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess( - new JSONObject() - .put("result", new JSONObject() - .put("_id", "foo") - .put("_version", 42) - .put("_source", new JSONObject()) - ) - ); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.fetchDocument("42", mock(ResponseListener.class)); - collection.fetchDocument("42", new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "get"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getMappingTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getMappingTest.java deleted file mode 100644 index 94caa5d8..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getMappingTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class getMappingTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.getMapping(listener); - verify(collection).getMapping(eq((Options)null), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void getMappingIllegalListener() { - collection.getMapping(null); - } - - @Test - public void testGetMapping() throws JSONException { - collection.getMapping(mock(Options.class), mock(ResponseListener.class)); - collection.getMapping(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getMapping"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getSpecificationsTest.java deleted file mode 100644 index 9dc088f2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/getSpecificationsTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class getSpecificationsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkGetSpecificationsSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.getSpecifications(mock(Options.class), listener); - collection.getSpecifications(listener); - - verify(collection, times(2)).getSpecifications(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testGetSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.getSpecifications(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.getSpecifications(listener); - } - - @Test - public void testGetSpecifications() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess( - new JSONObject() - .put("result", new JSONObject() - .put("validation", new JSONObject() - .put("strict", true) - .put("fields", new JSONObject() - .put("foo", new JSONObject() - .put("mandatory", true) - .put("type", "string") - .put("defaultValue", "bar") - ) - ) - ) - ) - ); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.getSpecifications(mock(ResponseListener.class)); - collection.getSpecifications(new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateDocumentTest.java deleted file mode 100644 index a61ed498..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateDocumentTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mCreateDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private Document[] documents; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - - try { - documents = new Document[]{ - new Document(collection, "foo"), - new Document(collection, "bar") - }; - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Test - public void checkMCreateDocumentSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.mCreateDocument(documents, mock(Options.class), listener); - collection.mCreateDocument(documents, listener); - collection.mCreateDocument(documents, mock(Options.class)); - collection.mCreateDocument(documents); - - verify(collection, times(4)).mCreateDocument(any(Document[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMCreateDocumentQueryException() throws JSONException { - documents = new Document[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mCreateDocument(documents, listener); - } - - @Test(expected = RuntimeException.class) - public void testMCreateDocumentException() throws JSONException { - documents = new Document[]{}; - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.mCreateDocument(documents, listener); - } - - @Test - public void testMCreateDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mCreateDocument(documents, new Options(), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mCreate"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateOrReplaceDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateOrReplaceDocumentTest.java deleted file mode 100644 index 891f9198..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mCreateOrReplaceDocumentTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mCreateOrReplaceDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private Document[] documents; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - - try { - documents = new Document[]{ - new Document(collection, "foo"), - new Document(collection, "bar") - }; - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Test - public void checkMCreateOrReplaceDocumentSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.mCreateOrReplaceDocument(documents, mock(Options.class), listener); - collection.mCreateOrReplaceDocument(documents, listener); - collection.mCreateOrReplaceDocument(documents, mock(Options.class)); - collection.mCreateOrReplaceDocument(documents); - - verify(collection, times(4)).mCreateOrReplaceDocument(any(Document[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMCreateOrReplaceDocumentQueryException() throws JSONException { - documents = new Document[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mCreateOrReplaceDocument(documents, listener); - } - - @Test(expected = RuntimeException.class) - public void testMCreateOrReplaceDocumentException() throws JSONException { - documents = new Document[]{}; - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.mCreateOrReplaceDocument(documents, listener); - } - - @Test - public void testMCreateOrReplaceDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", mock(JSONObject.class))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mCreateOrReplaceDocument(documents, new Options(), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mCreateOrReplace"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mDeleteDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mDeleteDocumentTest.java deleted file mode 100644 index 01663bcf..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mDeleteDocumentTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleDataCollectionExtend; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mDeleteDocumentTest { - private Kuzzle kuzzle; - private KuzzleDataCollectionExtend collection; - private ResponseListener listener; - private String[] documentIds; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new KuzzleDataCollectionExtend(kuzzle, "index", "test"); - listener = mock(ResponseListener.class); - - documentIds = new String[]{"foo", "bar"}; - } - - @Test - public void checkMDeleteDocumentSignaturesVariants() throws JSONException { - Options opts = mock(Options.class); - collection = spy(collection); - - collection.mDeleteDocument(documentIds, opts, listener); - collection.mDeleteDocument(documentIds, listener); - collection.mDeleteDocument(documentIds, opts); - collection.mDeleteDocument(documentIds); - - verify(collection, times(4)).mDeleteDocument(any(String[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMDeleteDocumentIllegalArgument() throws JSONException { - documentIds = new String[]{}; - collection.mDeleteDocument(documentIds, listener); - } - - @Test(expected = RuntimeException.class) - public void testMDeleteDocumentQueryException() throws JSONException { - documentIds = new String[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mDeleteDocument(documentIds, listener); - } - - @Test(expected = RuntimeException.class) - public void testMDeleteDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONArray().put("_id").put("id-42"))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.mDeleteDocument(documentIds, listener); - } - - @Test - public void testMDeleteDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONArray().put("foo").put("bar"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mDeleteDocument(documentIds, listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mDelete"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mGetDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mGetDocumentTest.java deleted file mode 100644 index baf2c9c3..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mGetDocumentTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mGetDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private String[] documentIds; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - - documentIds = new String[]{"foo", "bar"}; - } - - @Test - public void checkMGetDocumentSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.mGetDocument(documentIds, mock(Options.class), listener); - collection.mGetDocument(documentIds, listener); - - verify(collection, times(2)).mGetDocument(any(String[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMGetDocumentIllegalArgument() throws JSONException { - documentIds = new String[]{}; - collection.mGetDocument(documentIds, listener); - } - - @Test(expected = RuntimeException.class) - public void testMGetQueryException() throws JSONException { - documentIds = new String[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mGetDocument(documentIds, listener); - } - - @Test(expected = RuntimeException.class) - public void testMGetDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.mGetDocument(documentIds, listener); - } - - @Test - public void testMGetDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess( - new JSONObject() - .put("result", new JSONObject() - .put("hits", new JSONArray() - .put(new JSONObject() - .put("_id", "foo") - .put("_version", 42) - .put("_source", new JSONObject()) - ) - .put(new JSONObject() - .put("_id", "bar") - .put("_version", 42) - .put("_source", new JSONObject()) - ) - ) - ) - ); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mGetDocument(documentIds, mock(ResponseListener.class)); - collection.mGetDocument(documentIds, new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mGet"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mReplaceDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mReplaceDocumentTest.java deleted file mode 100644 index 7d15b47b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mReplaceDocumentTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mReplaceDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private Document[] documents; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - - try { - documents = new Document[]{ - new Document(collection, "foo"), - new Document(collection, "bar") - }; - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Test - public void checkMReplaceDocumentSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.mReplaceDocument(documents, mock(Options.class), listener); - collection.mReplaceDocument(documents, listener); - collection.mReplaceDocument(documents, mock(Options.class)); - collection.mReplaceDocument(documents); - - verify(collection, times(4)).mReplaceDocument(any(Document[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMReplaceDocumentIllegalArgument() throws JSONException { - documents = new Document[]{}; - collection.mReplaceDocument(documents, listener); - } - - @Test(expected = RuntimeException.class) - public void testMReplaceDocumentQueryException() throws JSONException { - documents = new Document[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mReplaceDocument(documents, mock(Options.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testMReplaceDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id-42"))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.mReplaceDocument(documents, mock(Options.class), listener); - } - - @Test - public void testMReplaceDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", new JSONObject() - .put("_id", "42") - .put("_version", 1337) - .put("_source", new JSONObject())); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - collection.mReplaceDocument(documents, listener); - collection.mReplaceDocument(documents, mock(Options.class), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mReplace"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mUpdateDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mUpdateDocumentTest.java deleted file mode 100644 index 15c9e195..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/mUpdateDocumentTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class mUpdateDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private Document[] documents; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - - try { - documents = new Document[]{ - new Document(collection, "foo"), - new Document(collection, "bar") - }; - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Test - public void checkMUpdateDocumentSignaturesVariants() throws JSONException { - collection = spy(collection); - - collection.mUpdateDocument(documents, mock(Options.class), listener); - collection.mUpdateDocument(documents, listener); - collection.mUpdateDocument(documents, mock(Options.class)); - collection.mUpdateDocument(documents); - - verify(collection, times(4)).mUpdateDocument(any(Document[].class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMUpdateDocumentIllegalArgument() throws JSONException { - documents = new Document[]{}; - collection.mUpdateDocument(documents, listener); - } - - @Test(expected = RuntimeException.class) - public void testMUpdateDocumentQueryException() throws JSONException { - documents = new Document[]{}; - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.mUpdateDocument(documents, mock(Options.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testMUpdateDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id-42"))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.mUpdateDocument(documents, mock(Options.class), listener); - } - - @Test - public void testMUpdateDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", new JSONObject() - .put("_id", "42") - .put("_version", 1337) - .put("_source", new JSONObject())); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - collection.mUpdateDocument(documents, listener); - collection.mUpdateDocument(documents, mock(Options.class), listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "mUpdate"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/publishMessageTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/publishMessageTest.java deleted file mode 100644 index a81187a0..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/publishMessageTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - - -public class publishMessageTest { - private Kuzzle kuzzle; - private Collection collection; - - @Mock - private ResponseListener listener; - - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - - MockitoAnnotations.initMocks(this); - } - - @Test - public void checkSignaturesVariants() { - Document doc = mock(Document.class); - - when(doc.getContent()).thenReturn(new JSONObject()); - collection = spy(collection); - - collection.publishMessage(doc); - collection.publishMessage(doc, mock(Options.class)); - collection.publishMessage(doc, listener); - collection.publishMessage(doc, mock(Options.class), listener); - collection.publishMessage(mock(JSONObject.class)); - collection.publishMessage(mock(JSONObject.class), listener); - collection.publishMessage(mock(JSONObject.class), mock(Options.class)); - collection.publishMessage(mock(JSONObject.class), mock(Options.class), listener); - verify(collection, times(8)).publishMessage(any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - - @Test(expected = IllegalArgumentException.class) - public void publishWithNoDocument() { - collection.publishMessage((Document) null); - } - - @Test(expected = IllegalArgumentException.class) - public void publishWithNoContent() { - collection.publishMessage((JSONObject)null); - } - - @Test(expected = RuntimeException.class) - public void testPublishMessageException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.publishMessage(mock(Document.class), mock(Options.class)); - } - - @Test - public void testPublishMessage() throws JSONException { - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - collection.publishMessage(doc); - collection.publishMessage(doc, new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "publish"); - } - - @Test - public void testCallback() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("acknowledged", true))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - JSONObject message = new JSONObject().put("foo", "bar"); - collection.publishMessage(message, listener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "publish"); - } - - @Test(expected = RuntimeException.class) - public void testPublishMEssageException() { - doThrow(JSONException.class).when(kuzzle).addHeaders(any(JSONObject.class), any(JSONObject.class)); - collection.publishMessage(mock(JSONObject.class)); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/replaceDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/replaceDocumentTest.java deleted file mode 100644 index bb48df4c..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/replaceDocumentTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class replaceDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - JSONObject content = mock(JSONObject.class); - String id = "foo"; - collection = spy(collection); - - collection.replaceDocument(id, content); - collection.replaceDocument(id, content, mock(Options.class)); - collection.replaceDocument(id, content, listener); - - verify(collection, times(3)).replaceDocument(any(String.class), any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testReplaceDocumentIllegalDocumentId() { - collection.replaceDocument(null, null); - } - - @Test(expected = RuntimeException.class) - public void testReplaceDocumentQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.replaceDocument("id", mock(JSONObject.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testReplaceDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "id-42"))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.replaceDocument("id", mock(JSONObject.class), listener); - } - - @Test - public void testReplaceDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", new JSONObject() - .put("_id", "42") - .put("_version", 1337) - .put("_source", new JSONObject())); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - Document doc = new Document(collection); - doc.setContent("foo", "bar"); - collection.replaceDocument("42", doc.serialize(), listener); - collection.replaceDocument("42", mock(JSONObject.class), mock(Options.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollSpecificationsTest.java deleted file mode 100644 index 4ba5a5e9..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollSpecificationsTest.java +++ /dev/null @@ -1,167 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class scrollSpecificationsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private String scrollId; - private Options options; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - opts.setScroll("30s"); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "bar", "foo"); - listener = mock(ResponseListener.class); - scrollId = "1337"; - options = mock(Options.class); - } - - @Test - public void checkScrollSpecificationsSignaturesVariants() { - collection = spy(collection); - collection.scrollSpecifications(scrollId, listener); - verify(collection).scrollSpecifications(eq(scrollId), any(Options.class), eq(listener)); - - collection.scrollSpecifications(scrollId, options, listener); - verify(collection).scrollSpecifications(eq(scrollId), eq(options), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollSpecificationsIllegalListener() { - collection.scrollSpecifications(scrollId, null); - } - - @Test(expected = RuntimeException.class) - public void testScrollSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.scrollSpecifications(scrollId, listener); - } - - @Test(expected = RuntimeException.class) - public void testScrollSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - collection.scrollSpecifications(scrollId, listener); - } - - @Test - public void testScrollSpecifications() throws JSONException { - JSONObject filters = new JSONObject(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"foo#bar\",\n" + - " \"index\": \"foo\",\n" + - " \"collection\": \"bar\",\n" + - " \"_source\": {\n" + - " \"validation\": {\n" + - " \"strict\": true,\n" + - " \"fields\": {\n" + - " \"foo\": {\n" + - " \"mandatory\": true,\n" + - " \"type\": \"string\",\n" + - " \"defaultValue\": \"bar\"\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " },\n" + - " {\n" + - " \"_id\": \"bar#foo\",\n" + - " \"index\": \"bar\",\n" + - " \"collection\": \"foo\",\n" + - " \"_source\": {\n" + - " \"validation\": {\n" + - " \"strict\": false,\n" + - " \"fields\": {\n" + - " \"bar\": {\n" + - " \"mandatory\": true,\n" + - " \"type\": \"string\",\n" + - " \"defaultValue\": \"foo\"\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"total\": 2,\n" + - " \"scrollId\": \"1337\"\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.scrollSpecifications(scrollId, new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - try { - assertEquals(result.getJSONArray("hits").length(), 2); - assertEquals(result.getJSONArray("hits").getJSONObject(1).getJSONObject("_source").getJSONObject("validation").getBoolean("strict"), false); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - } - }); - collection.scrollSpecifications(scrollId, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "scrollSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollTest.java deleted file mode 100644 index 174c5177..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/scrollTest.java +++ /dev/null @@ -1,177 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.responses.SearchResult; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class scrollTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - private String scrollId; - private String scroll; - private Options options; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - scrollId = "someScrollId"; - options = mock(Options.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.scroll(scrollId, listener); - verify(collection).scroll(eq(scrollId), any(Options.class), any(JSONObject.class), eq(listener)); - - collection.scroll(scrollId, options, listener); - verify(collection).scroll(eq(scrollId), eq(options), any(JSONObject.class), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollIllegalListener() { - collection.scroll(scrollId, null); - } - - @Test(expected = RuntimeException.class) - public void testScrollQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.scroll(scrollId, listener); - } - - @Test(expected = RuntimeException.class) - public void testScrollException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - collection.scroll(scrollId, listener); - } - - @Test - public void testScroll() throws JSONException { - JSONObject filters = new JSONObject(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"_shards\": {\n" + - " \"failed\": 0,\n" + - " \"successful\": 5,\n" + - " \"total\": 5\n" + - " },\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"AVJAwyDMZAGQHg9Dhfw2\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073821,\n" + - " \"lon\": 3.9130721\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"customer\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " },\n" + - " {\n" + - " \"_id\": \"AVJAwyOvZAGQHg9Dhfw3\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073683,\n" + - " \"lon\": 3.8999983\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"cab\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " }\n" + - " ],\n" + - " \"max_score\": 1,\n" + - " \"timed_out\": false,\n" + - " \"took\": 307,\n" + - " \"total\": 2\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.scroll(scrollId, new ResponseListener() { - @Override - public void onSuccess(SearchResult result) { - assertEquals(result.getTotal(), 2); - try { - assertEquals(result.getDocuments().get(1).getContent("sibling"), "none"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - } - }); - collection.scroll(scrollId, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "scroll"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchSpecificationsTest.java deleted file mode 100644 index e5d46bf7..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchSpecificationsTest.java +++ /dev/null @@ -1,166 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class searchSpecificationsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSearchSpecificationsSignaturesVariants() { - JSONObject filters = mock(JSONObject.class); - Options options = mock(Options.class); - collection = spy(collection); - - collection.searchSpecifications(listener); - collection.searchSpecifications(filters, listener); - collection.searchSpecifications(options, listener); - collection.searchSpecifications(filters, options, listener); - - verify(collection, times(4)).searchSpecifications(any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchSpecificationsIllegalListener() { - collection.searchSpecifications(null, null, null); - } - - @Test(expected = RuntimeException.class) - public void testSearchSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.searchSpecifications(listener); - } - - @Test(expected = RuntimeException.class) - public void testSearchSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - collection.searchSpecifications(listener); - } - - @Test - public void testSearchSpecifications() throws JSONException { - JSONObject filters = new JSONObject(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"foo#bar\",\n" + - " \"index\": \"foo\",\n" + - " \"collection\": \"bar\",\n" + - " \"_source\": {\n" + - " \"validation\": {\n" + - " \"strict\": true,\n" + - " \"fields\": {\n" + - " \"foo\": {\n" + - " \"mandatory\": true,\n" + - " \"type\": \"string\",\n" + - " \"defaultValue\": \"bar\"\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " },\n" + - " {\n" + - " \"_id\": \"bar#foo\",\n" + - " \"index\": \"bar\",\n" + - " \"collection\": \"foo\",\n" + - " \"_source\": {\n" + - " \"validation\": {\n" + - " \"strict\": false,\n" + - " \"fields\": {\n" + - " \"bar\": {\n" + - " \"mandatory\": true,\n" + - " \"type\": \"string\",\n" + - " \"defaultValue\": \"foo\"\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"total\": 2,\n" + - " \"scrollId\": \"1337\"\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.searchSpecifications(filters, new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - try { - assertEquals(result.getJSONArray("hits").length(), 2); - assertEquals(result.getJSONArray("hits").getJSONObject(1).getJSONObject("_source").getJSONObject("validation").getBoolean("strict"), false); - assertEquals(result.getString("scrollId"), "1337"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - } - }); - collection.searchSpecifications(filters, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "searchSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchTest.java deleted file mode 100644 index ed2f3871..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/searchTest.java +++ /dev/null @@ -1,279 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SearchResult; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class searchTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.search(new JSONObject(), listener); - verify(collection).search(any(JSONObject.class), any(Options.class), eq(listener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchIllegalListener() { - collection.search(null, null, null); - } - - @Test(expected = RuntimeException.class) - public void testSearchQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.search(null, listener); - } - - @Test(expected = RuntimeException.class) - public void testSearchException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - collection.search(null, listener); - } - - @Test - public void testSearch() throws JSONException { - JSONObject filters = new JSONObject(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"_shards\": {\n" + - " \"failed\": 0,\n" + - " \"successful\": 5,\n" + - " \"total\": 5\n" + - " },\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"AVJAwyDMZAGQHg9Dhfw2\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073821,\n" + - " \"lon\": 3.9130721\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"customer\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " },\n" + - " {\n" + - " \"_id\": \"AVJAwyOvZAGQHg9Dhfw3\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073683,\n" + - " \"lon\": 3.8999983\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"cab\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " }\n" + - " ],\n" + - " \"max_score\": 1,\n" + - " \"timed_out\": false,\n" + - " \"took\": 307,\n" + - " \"total\": 2\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.search(filters, new ResponseListener() { - @Override - public void onSuccess(SearchResult result) { - assertEquals(result.getTotal(), 2); - try { - assertEquals(result.getDocuments().get(1).getContent("sibling"), "none"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - } - }); - collection.search(filters, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "search"); - } - - @Test - public void testSearchWithAggregations() throws JSONException { - JSONObject filters = new JSONObject(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"_shards\": {\n" + - " \"failed\": 0,\n" + - " \"successful\": 5,\n" + - " \"total\": 5\n" + - " },\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"AVJAwyDMZAGQHg9Dhfw2\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073821,\n" + - " \"lon\": 3.9130721\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"customer\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " },\n" + - " {\n" + - " \"_id\": \"AVJAwyOvZAGQHg9Dhfw3\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073683,\n" + - " \"lon\": 3.8999983\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"cab\"\n" + - " },\n" + - " \"_meta\": {\n" + - " \"author\": \"foo\"\n" + - " },\n" + - " \"_type\": \"users\"\n" + - " }\n" + - " ],\n" + - " \"aggregations\": {\n" + - " \"aggs_name\": {\n" + - " \"buckets\": [\n" + - " {\n" + - " \"doc_count\": 5,\n" + - " \"key\": \"i\"\n" + - " },\n" + - " {\n" + - " \"doc_count\": 2,\n" + - " \"key\": \"hate\"\n" + - " },\n" + - " {\n" + - " \"doc_count\": 1,\n" + - " \"key\": \"admir\"\n" + - " }\n" + - " ],\n" + - " \"doc_count_error_upper_bound\": 0,\n" + - " \"sum_other_doc_count\": 1\n" + - " }\n" + - " },\n" + - " \"max_score\": 1,\n" + - " \"timed_out\": false,\n" + - " \"took\": 307,\n" + - " \"total\": 2\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.search(filters, new ResponseListener() { - @Override - public void onSuccess(SearchResult result) { - assertEquals(result.getTotal(), 2); - try { - assertEquals(result.getAggregations().getJSONObject("aggs_name").getJSONArray("buckets").getJSONObject(0).getString("key"), "i"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - try { - assertEquals(result.getDocuments().get(1).getContent("sibling"), "none"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - } - }); - collection.search(filters, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "search"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/subscribeTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/subscribeTest.java deleted file mode 100644 index 05a28ac2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/subscribeTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class subscribeTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.subscribe(new JSONObject(), listener); - verify(collection).subscribe(any(JSONObject.class), eq((RoomOptions)null), eq(listener)); - } - - - @Test(expected = IllegalArgumentException.class) - public void testSubscribeIllegalListener() { - collection.subscribe(mock(JSONObject.class), null); - } - - @Test - public void testSubscribe() throws JSONException { - final ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - verify(kuzzle, atLeastOnce()).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "subscribe"); - - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.subscribe(mock(JSONObject.class), new RoomOptions(), listener); - collection.subscribe(mock(JSONObject.class), listener); - collection.subscribe(new RoomOptions(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/truncateTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/truncateTest.java deleted file mode 100644 index 5804fd8c..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/truncateTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class truncateTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - collection = spy(collection); - collection.truncate(); - collection.truncate(mock(Options.class)); - collection.truncate(listener); - verify(collection, times(3)).truncate(any(Options.class), any(ResponseListener.class)); - } - - - @Test(expected = RuntimeException.class) - public void testTruncateQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.truncate(listener); - } - - @Test(expected = RuntimeException.class) - public void testTruncateException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.truncate(listener); - } - - @Test - public void testTruncate() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.truncate(); - collection.truncate(new Options()); - collection.truncate(mock(ResponseListener.class)); - collection.truncate(new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(4)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "truncate"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateDocumentTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateDocumentTest.java deleted file mode 100644 index dafc8938..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateDocumentTest.java +++ /dev/null @@ -1,157 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.KuzzleJSONObject; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class updateDocumentTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkSignaturesVariants() { - JSONObject content = mock(JSONObject.class); - String id = "foo"; - collection = spy(collection); - - collection.updateDocument(id, content); - collection.updateDocument(id, content, mock(Options.class)); - collection.updateDocument(id, content, listener); - - verify(collection, times(3)).updateDocument(any(String.class), any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - - @Test(expected = IllegalArgumentException.class) - public void testUpdateDocumentIllegalDocumentId() { - collection.updateDocument(null, mock(JSONObject.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdateDocumentIllegalContent() { - collection.updateDocument("id", null); - } - - @Test(expected = RuntimeException.class) - public void testupdateDocumentQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.updateDocument("id", mock(JSONObject.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testupdateDocumentException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(String.class)); - collection.updateDocument("id", mock(JSONObject.class), listener); - } - - @Test - public void testUpdateDocument() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", new JSONObject() - .put("_id", "42") - .put("_version", 1337) - .put("_source", new JSONObject()) - .put("_meta", new JSONObject()) - ); - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - } - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - Document doc = new Document(collection); - collection.updateDocument("42", doc.serialize()); - collection.updateDocument("42", doc.serialize(), new Options()); - collection.updateDocument("42", doc.serialize(), new ResponseListener() { - @Override - public void onSuccess(Document document) { - assertEquals(document.getId(), "42"); - assertEquals(document.getVersion(), 1337); - } - - @Override - public void onError(JSONObject error) { - - } - }); - collection.updateDocument("42", doc.serialize(), new Options(), new ResponseListener() { - @Override - public void onSuccess(Document document) { - assertEquals(document.getId(), "42"); - } - - @Override - public void onError(JSONObject error) { - - } - }); - verify(kuzzle, times(6)).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test - public void testRetryOnConflict() throws JSONException { - Options opts = new Options().setRetryOnConflict(42); - Document doc = new Document(collection); - ArgumentCaptor capturedQuery = ArgumentCaptor.forClass(KuzzleJSONObject.class); - - collection.updateDocument("foo", doc.serialize(), opts); - verify(kuzzle).query(any(Kuzzle.QueryArgs.class), (JSONObject)capturedQuery.capture(), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((JSONObject)capturedQuery.getValue()).getInt("retryOnConflict"), 42); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateSpecificationsTest.java deleted file mode 100644 index b550d4ec..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/updateSpecificationsTest.java +++ /dev/null @@ -1,149 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class updateSpecificationsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkUpdateSpecificationsSignaturesVariants() throws JSONException { - JSONObject content = mock(JSONObject.class); - collection = spy(collection); - - collection.updateSpecifications(content); - collection.updateSpecifications(content, mock(Options.class)); - collection.updateSpecifications(content, listener); - collection.updateSpecifications(content, mock(Options.class), listener); - - verify(collection, times(4)).updateSpecifications(any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdateSpecificationsIllegalArgument() throws JSONException { - collection.updateSpecifications(null); - } - - @Test(expected = RuntimeException.class) - public void testUpdateSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.updateSpecifications(mock(JSONObject.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testUpdateSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.updateSpecifications(mock(JSONObject.class), listener); - } - - @Test - public void testUpdateSpecifications() throws JSONException { - final JSONObject specifications = new JSONObject() - .put("index", new JSONObject() - .put("test", new JSONObject() - .put("strict", true) - .put("fields", new JSONObject() - .put("foo", new JSONObject() - .put("mandatory", true) - .put("type", "string") - .put("defaultValue", "bar") - ) - ) - ) - ); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", specifications); - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - } - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.updateSpecifications(new JSONObject()); - collection.updateSpecifications(new JSONObject(), new Options()); - collection.updateSpecifications(new JSONObject(), new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - assertEquals(response, specifications); - assertEquals(response, specifications); - } - - @Override - public void onError(JSONObject error) { - - } - }); - collection.updateSpecifications(new JSONObject(), new Options(), new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - assertEquals(response, specifications); - } - - @Override - public void onError(JSONObject error) { - - } - }); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(4)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "updateSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/validateSpecificationsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/validateSpecificationsTest.java deleted file mode 100644 index 2de8fba6..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataCollection/validateSpecificationsTest.java +++ /dev/null @@ -1,146 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataCollection; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class validateSpecificationsTest { - private Kuzzle kuzzle; - private Collection collection; - private ResponseListener listener; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - } - - @Test - public void checkValidateSpecificationsSignaturesVariants() throws JSONException { - JSONObject specifications = mock(JSONObject.class); - collection = spy(collection); - - collection.validateSpecifications(specifications, listener); - collection.validateSpecifications(specifications, mock(Options.class), listener); - - verify(collection, times(2)).validateSpecifications(any(JSONObject.class), any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testValidateSpecificationsIllegalArgument() throws JSONException { - collection.validateSpecifications(null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testValidateSpecificationsIllegalListener() throws JSONException { - collection.validateSpecifications(null, null); - } - - @Test(expected = RuntimeException.class) - public void testValidateSpecificationsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - collection.validateSpecifications(mock(JSONObject.class), listener); - } - - @Test(expected = RuntimeException.class) - public void testValidateSpecificationsException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("valid", true))); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - collection.validateSpecifications(mock(JSONObject.class), listener); - } - - @Test - public void testValidateSpecifications() throws JSONException { - final JSONObject validateSpecificationsResponse = new JSONObject().put("valid", true); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", validateSpecificationsResponse); - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - } - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - collection.validateSpecifications(new JSONObject(), new ResponseListener() { - @Override - public void onSuccess(Boolean isValid) { - try { - assertEquals(isValid, validateSpecificationsResponse.getBoolean("valid")); - assertEquals(isValid, validateSpecificationsResponse.getBoolean("valid")); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(JSONObject error) { - - } - }); - collection.validateSpecifications(new JSONObject(), new Options(), new ResponseListener() { - @Override - public void onSuccess(Boolean isValid) { - try { - assertEquals(isValid, validateSpecificationsResponse.getBoolean("valid")); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(JSONObject error) { - - } - }); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "validateSpecifications"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/applyTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/applyTest.java deleted file mode 100644 index d83d1118..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/applyTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataMapping; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.CollectionMapping; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class applyTest { - private Kuzzle k; - private Collection dataCollection; - private CollectionMapping dataMapping; - - @Before - public void setUp() { - k = mock(Kuzzle.class); - when(k.getDefaultIndex()).thenReturn("index"); - when(k.getHeaders()).thenReturn(new JSONObject()); - dataCollection = new Collection(k, "test", "index"); - dataMapping = new CollectionMapping(dataCollection); - } - - @Test - public void checkSignaturesVariants() { - dataMapping = spy(dataMapping); - dataMapping.apply(); - dataMapping.apply(mock(Options.class)); - dataMapping.apply(mock(ResponseListener.class)); - verify(dataMapping, times(3)).apply(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testApplyQueryException() throws JSONException { - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - dataMapping.apply(); - } - - @Test(expected = RuntimeException.class) - public void testApplyException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - ResponseListener mockListener = mock(ResponseListener.class); - doThrow(JSONException.class).when(mockListener).onSuccess(any(CollectionMapping.class)); - dataMapping.apply(mockListener); - } - - @Test - public void testApply() throws JSONException { - final JSONObject mockResponse = new JSONObject("{\n" + - " properties: {\n" + - " field1: {type: \"field type\"},\n" + - " field2: {type: \"field type\"},\n" + - " fieldn: {type: \"field type\"}\n" + - " }\n" + - " }"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mockResponse); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - dataMapping.apply(); - dataMapping.apply(new Options()); - dataMapping.apply(mock(ResponseListener.class)); - dataMapping.apply(new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(4)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "updateMapping"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/constructorTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/constructorTest.java deleted file mode 100644 index 139fb5f8..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/constructorTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataMapping; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.CollectionMapping; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class constructorTest { - private Kuzzle k; - private Collection dataCollection; - private CollectionMapping dataMapping; - - @Before - public void setUp() { - k = mock(Kuzzle.class); - when(k.getDefaultIndex()).thenReturn("index"); - when(k.getHeaders()).thenReturn(new JSONObject()); - dataCollection = new Collection(k, "test", "index"); - dataMapping = new CollectionMapping(dataCollection); - } - - @Test(expected = RuntimeException.class) - public void testConstructorException() { - Collection fake = spy(new Collection(k, "test", "index")); - doThrow(JSONException.class).when(fake).getHeaders(); - dataMapping = new CollectionMapping(fake); - } - - @Test - public void testConstructor() throws JSONException { - JSONObject mapping = new JSONObject(); - mapping.put("type", "string"); - dataMapping = new CollectionMapping(dataCollection, mapping); - dataMapping = new CollectionMapping(dataMapping); - } - - @Test - public void testSetHeaders() throws JSONException { - dataMapping.setHeaders(null, true); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - dataMapping.setHeaders(headers, true); - assertEquals(dataMapping.getHeaders().getString("foo"), "bar"); - headers.put("oof", "baz"); - dataMapping.setHeaders(headers); - assertEquals(dataMapping.getHeaders().getString("foo"), "bar"); - assertEquals(dataMapping.getHeaders().getString("oof"), "baz"); - } - - @Test(expected = RuntimeException.class) - public void testSetHeadersException() { - JSONObject json = spy(new JSONObject()); - doThrow(JSONException.class).when(json).keys(); - dataMapping.setHeaders(json, false); - } - - @Test - public void testGetHeaders() throws JSONException { - dataMapping.setHeaders(null); - assertNotNull(dataMapping.getHeaders()); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - dataMapping.setHeaders(headers); - assertEquals(dataMapping.getHeaders().getString("foo"), "bar"); - } - - @Test - public void testSet() throws JSONException { - JSONObject mapping = mock(JSONObject.class); - assertThat(dataMapping.set("foo", mapping), instanceOf(CollectionMapping.class)); - assertEquals(dataMapping.getMapping().getJSONObject("foo"), mapping); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/refreshTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/refreshTest.java deleted file mode 100644 index 8bf8485b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/refreshTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataMapping; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.CollectionMapping; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class refreshTest { - private Kuzzle k; - private Collection dataCollection; - private CollectionMapping dataMapping; - - @Before - public void setUp() { - k = mock(Kuzzle.class); - when(k.getDefaultIndex()).thenReturn("index"); - when(k.getHeaders()).thenReturn(new JSONObject()); - dataCollection = new Collection(k, "test", "index"); - dataMapping = new CollectionMapping(dataCollection); - } - - @Test - public void checkSignaturesVariants() { - dataMapping = spy(dataMapping); - dataMapping.refresh(mock(ResponseListener.class)); - verify(dataMapping).refresh(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testRefreshIllegalListener() { - dataMapping.refresh(null); - } - - @Test(expected = RuntimeException.class) - public void testException() throws JSONException { - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - dataMapping.refresh(mock(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testRefreshException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject("{\"index\": {\n" + - " \"mappings\": {\n" + - " \"users\": {\n" + - " \"properties\": {\n" + - " \"pos\": {\n" + - " \"type\": \"geo_point\"\n" + - " },\n" + - " \"sibling\": {\n" + - " \"type\": \"string\"\n" + - " },\n" + - " \"status\": {\n" + - " \"type\": \"string\"\n" + - " },\n" + - " \"type\": {\n" + - " \"type\": \"string\"\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - " }" + - "}")); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - ResponseListener mockListener = mock(ResponseListener.class); - doThrow(JSONException.class).when(mockListener).onSuccess(any(CollectionMapping.class)); - dataMapping.refresh(mockListener); - } - - @Test - public void testRefresh() throws JSONException { - final JSONObject mockMapping = new JSONObject("{\"index\": {\"mappings\": {" + - " \"test\": {" + - " \"properties\": {" + - " \"available\": {" + - " \"type\": \"boolean\"" + - " }," + - " \"foo\": {" + - " \"type\": \"string\"" + - " }," + - " \"type\": {" + - " \"type\": \"string\"" + - " }," + - " \"userId\": {" + - " \"type\": \"string\"" + - " }" + - " }" + - " }}}}"); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = mockMapping; - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - when(k.getDefaultIndex()).thenReturn("index"); - - dataMapping.refresh(new ResponseListener() { - @Override - public void onSuccess(CollectionMapping response) { - assertNotEquals(dataMapping, response); - try { - assertEquals( - mockMapping.getJSONObject("index").getJSONObject("mappings").getJSONObject("test"), - response.getMapping() - ); - } - catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onError(JSONObject error) { - - } - }); - dataMapping.refresh(new Options(), mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(2)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "collection"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getMapping"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/removeTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/removeTest.java deleted file mode 100644 index e491394b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDataMapping/removeTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDataMapping; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.CollectionMapping; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class removeTest { - private Kuzzle k; - private Collection dataCollection; - private CollectionMapping dataMapping; - - @Before - public void setUp() { - k = mock(Kuzzle.class); - when(k.getDefaultIndex()).thenReturn("index"); - when(k.getHeaders()).thenReturn(new JSONObject()); - dataCollection = new Collection(k, "test", "index"); - dataMapping = new CollectionMapping(dataCollection); - } - - @Test - public void testRemove() throws JSONException { - JSONObject mapping = new JSONObject(); - mapping.put("type", "string"); - dataMapping.set("foo", mapping); - assertEquals(dataMapping.getMapping().getJSONObject("foo").getString("type"), "string"); - dataMapping.remove("foo"); - assertTrue(dataMapping.getMapping().isNull("foo")); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/constructorTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/constructorTest.java deleted file mode 100644 index de64bdd2..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/constructorTest.java +++ /dev/null @@ -1,178 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class constructorTest { - private Kuzzle k; - private Document doc; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - k = spy(extended); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test(expected = IllegalArgumentException.class) - public void testConstructorIllegalDataCollection() throws JSONException { - new Document(null, null, null, null); - } - - @Test - public void testConstructor() throws JSONException { - doc = new Document(new Collection(k, "test", "index"), "42"); - assertEquals(doc.getId(), "42"); - } - - @Test - public void testCollection() throws JSONException { - Kuzzle k = mock(Kuzzle.class); - when(k.getHeaders()).thenReturn(new JSONObject()); - Collection collection = new Collection(k, "test", "index"); - Document doc = new Document(collection); - assertEquals(doc.getCollection(), collection.getCollection()); - } - - @Test - public void testDocumentWithContent() throws JSONException { - JSONObject content = new JSONObject(); - content.put("foo", "bar"); - - doc = new Document(new Collection(k, "test", "index"), content); - assertEquals(doc.getContent().getString("foo"), "bar"); - } - - @Test(expected = RuntimeException.class) - public void testSetContentPutException() throws JSONException { - doc = spy(doc); - doc.setContent(mock(JSONObject.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetContentIllegalKey() throws JSONException { - doc.setContent(null, "value"); - } - - @Test - public void testSetContentUpdateVersion() throws JSONException { - JSONObject content = new JSONObject() - .put("version", 42424242); - doc.setContent(content, false); - assertEquals(42424242, doc.getVersion()); - } - - @Test - public void checkSetContentVariants() throws JSONException { - doc = spy(doc); - doc.setContent(new JSONObject()); - verify(doc).setContent(any(JSONObject.class), eq(false)); - } - - @Test - public void testSetContent() throws JSONException { - assertEquals(doc.getContent().toString(), new JSONObject().toString()); - JSONObject data = new JSONObject(); - data.put("test", "some content"); - doc.setContent(data, false); - assertEquals(doc.getContent().get("test"), "some content"); - data = new JSONObject(); - data.put("test 2", "some other content"); - doc.setContent(data, true); - assertEquals(doc.getContent().get("test 2"), "some other content"); - assertTrue(doc.getContent().isNull("test")); - } - - @Test - public void testGetContent() throws JSONException { - doc.setContent(null); - assertNotNull(doc.getContent()); - doc.setContent("foo", "bar"); - assertEquals(doc.getContent().getString("foo"), "bar"); - assertNull(doc.getContent("!exist")); - } - - @Test - public void testDocumentWithMetadata() throws JSONException { - JSONObject content = new JSONObject(); - content.put("foo", "bar"); - - JSONObject meta = new JSONObject(); - meta.put("author", "foo"); - - doc = new Document(new Collection(k, "test", "index"), content, meta); - assertEquals(doc.getMeta().getString("author"), "foo"); - } - - @Test - public void checkSetHeadersVariants() { - doc = spy(doc); - doc.setHeaders(new JSONObject()); - verify(doc).setHeaders(any(JSONObject.class), eq(false)); - } - - @Test(expected = RuntimeException.class) - public void testSetHeadersException() { - JSONObject fake = spy(new JSONObject()); - doThrow(JSONException.class).when(fake).toString(); - doc.setHeaders(fake, true); - } - - @Test - public void testSetHeaders() throws JSONException { - doc.setHeaders(null, true); - assertNotNull(doc.getHeaders()); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - doc.setHeaders(headers, true); - assertEquals(doc.getHeaders().getString("foo"), "bar"); - headers.put("oof", "baz"); - doc.setHeaders(headers); - assertEquals(doc.getHeaders().getString("foo"), "bar"); - assertEquals(doc.getHeaders().getString("oof"), "baz"); - } - - @Test - public void testGetHeaders() throws JSONException { - doc.setHeaders(null); - assertNotNull(doc.getHeaders()); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - doc.setHeaders(headers); - assertEquals(doc.getHeaders().getString("foo"), "bar"); - } - - @Test - public void testGetVersion() throws JSONException { - assertEquals(-1, doc.getVersion()); - doc.setVersion(42); - assertEquals(42, doc.getVersion()); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/deleteTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/deleteTest.java deleted file mode 100644 index c2538496..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/deleteTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class deleteTest { - private Kuzzle k; - private Document doc; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc.setId("foo"); - doc = spy(doc); - doc.delete(); - doc.delete(mock(Options.class)); - doc.delete(mock(ResponseListener.class)); - verify(doc, times(3)).delete(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = IllegalStateException.class) - public void cannotDeleteWithoutID() { - doc.delete(); - } - - @Test(expected = RuntimeException.class) - public void testDeleteException() throws JSONException { - doc.setId("42"); - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.delete(); - } - - @Test - public void testDelete() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - response.put("result", "foo"); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.setId("id-42"); - doc.delete(mock(ResponseListener.class)); - doc.setId("id-42"); - doc.delete(); - doc.setId("id-42"); - doc.delete(mock(Options.class)); - assertNull(doc.getId()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "delete"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/existsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/existsTest.java deleted file mode 100644 index 634f86bd..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/existsTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class existsTest { - private Kuzzle k; - private Document doc; - private ResponseListener mockListener; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - mockListener = mock(ResponseListener.class); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc.setId("foo"); - doc = spy(doc); - doc.exists(mockListener); - verify(doc).exists(eq((Options)null), eq(mockListener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testExistsNullListenerException() throws IllegalArgumentException { - doc.setId("42"); - doc.exists(null); - } - - @Test(expected = RuntimeException.class) - public void testExistsQueryException() throws JSONException { - doc.setId("42"); - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.exists(mockListener); - } - - @Test(expected = RuntimeException.class) - public void testExistsException() throws JSONException { - doc.setId("42"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", true); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(mockListener).onSuccess(any(JSONObject.class)); - doc.exists(mockListener); - } - - @Test(expected = IllegalStateException.class) - public void testExistsWithoutId() { - doc.exists(null, null); - } - - @Test - public void testExists() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", true); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.setId("42"); - doc.setContent("foo", "baz"); - doc.exists(new ResponseListener() { - @Override - public void onSuccess(Boolean exists) { - assertEquals(exists, true); - } - - @Override - public void onError(JSONObject error) { - - } - }); - doc.exists(mockListener); - doc.exists(mock(Options.class), mockListener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "exists"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/publishTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/publishTest.java deleted file mode 100644 index 9c9613b5..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/publishTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class publishTest { - private Kuzzle k; - private Document doc; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc = spy(doc); - doc.publish(); - verify(doc).publish(eq((Options)null)); - } - - @Test(expected = RuntimeException.class) - public void testPublishException() throws JSONException { - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.publish(); - } - - @Test - public void testPublish() throws JSONException { - doc.publish(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "publish"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/refreshTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/refreshTest.java deleted file mode 100644 index de89ab5b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/refreshTest.java +++ /dev/null @@ -1,140 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class refreshTest { - private Kuzzle k; - private Document doc; - private ResponseListener mockListener; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - mockListener = mock(ResponseListener.class); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc.setId("foo"); - doc = spy(doc); - doc.refresh(mockListener); - verify(doc).refresh(eq((Options)null), eq(mockListener)); - } - - @Test(expected = IllegalArgumentException.class) - public void testRefreshNullListenerException() throws IllegalArgumentException { - doc.setId("42"); - doc.refresh(null); - } - - @Test(expected = RuntimeException.class) - public void testRefreshQueryException() throws JSONException { - doc.setId("42"); - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.refresh(mockListener); - } - - @Test(expected = RuntimeException.class) - public void testRefreshException() throws JSONException { - doc.setId("42"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject result = new JSONObject() - .put("result", new JSONObject() - .put("_id", "foo") - .put("_source", mock(JSONObject.class)) - ); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(mockListener).onSuccess(any(Document.class)); - doc.refresh(mockListener); - } - - @Test(expected = IllegalStateException.class) - public void testRefreshWithoutId() { - doc.refresh(null, null); - } - - @Test - public void testRefresh() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", new JSONObject() - .put("_id", "42") - .put("_version", 1337) - .put("_source", new JSONObject().put("foo", "bar")) - .put("_meta", new JSONObject().put("author", "foo"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.setId("42"); - doc.setContent("foo", "baz"); - doc.refresh(new ResponseListener() { - @Override - public void onSuccess(Document object) { - try { - assertEquals(1337, object.getVersion()); - assertEquals("bar", object.getContent().getString("foo")); - assertNotEquals(doc, object); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(JSONObject error) { - - } - }); - doc.refresh(mockListener); - doc.refresh(mock(Options.class), mockListener); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "get"); - - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/saveTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/saveTest.java deleted file mode 100644 index 87eed549..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/saveTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class saveTest { - private Kuzzle k; - private Document doc; - private ResponseListener mockListener; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - mockListener = mock(ResponseListener.class); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc = spy(doc); - doc.save(); - doc.save(mock(Options.class)); - doc.save(mockListener); - verify(doc, times(3)).save(any(Options.class), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testSaveQueryException() throws JSONException { - doc.setId("42"); - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.save(); - } - - @Test(expected = RuntimeException.class) - public void testSaveException() throws JSONException { - doc.setId("42"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("_id", "42").put("_version", "42"))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(mockListener).onSuccess(any(Document.class)); - doc.save(mockListener); - } - - @Test - public void testSave() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - response.put("_id", "id-42"); - response.put("_version", "42"); - response.put("result", response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(null); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.save(); - doc.save(new Options()); - doc.save(new ResponseListener() { - @Override - public void onSuccess(Document object) { - assertEquals(object.getId(), "id-42"); - } - - @Override - public void onError(JSONObject error) { - - } - }); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(k, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "document"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplace"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/serializeTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/serializeTest.java deleted file mode 100644 index c0369023..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/serializeTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.spy; - -public class serializeTest { - - private Kuzzle k; - private Document doc; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - k = spy(extended); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test(expected = RuntimeException.class) - public void testException() { - doThrow(JSONException.class).when(k).addHeaders(any(JSONObject.class), any(JSONObject.class)); - doc.serialize(); - } - - @Test - public void testToString() throws JSONException { - JSONObject o = new JSONObject() - .put("foo", "bar"); - doc.setId("42"); - doc.setVersion(4242); - doc.setContent(o); - assertEquals(doc.toString(), "{\"_id\":\"42\",\"body\":{\"foo\":\"bar\"},\"_version\":4242}"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/subscribeTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/subscribeTest.java deleted file mode 100644 index 993a4496..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleDocument/subscribeTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleDocument; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class subscribeTest { - private Kuzzle k; - private Document doc; - private Collection mockCollection; - - @Before - public void setUp() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setState(States.CONNECTED); - extended.setSocket(mock(WebSocketClient.class)); - k = spy(extended); - mockCollection = mock(Collection.class); - doc = new Document(new Collection(k, "test", "index")); - } - - @Test - public void checkSignaturesVariants() { - doc.setId("foo"); - doc = spy(doc); - doc.subscribe(mock(ResponseListener.class)); - verify(doc).subscribe(eq((RoomOptions)null), any(ResponseListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testSubscribeException() throws JSONException { - doc = new Document(mockCollection); - doc.setId("42"); - doThrow(JSONException.class).when(mockCollection).subscribe(any(JSONObject.class), any(RoomOptions.class), any(ResponseListener.class)); - doc.subscribe(mock(ResponseListener.class)); - } - - @Test(expected = IllegalStateException.class) - public void testSubscribeNullId() { - doc.subscribe(mock(ResponseListener.class)); - } - - @Test - public void testSubscribe() throws JSONException { - final ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - verify(k, atLeastOnce()).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "subscribe"); - - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doc.setId("42"); - doc.subscribe(mock(ResponseListener.class)); - doc.subscribe(new RoomOptions(), mock(ResponseListener.class)); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleMemoryStorage/methodsTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleMemoryStorage/methodsTest.java deleted file mode 100644 index 84d9433b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleMemoryStorage/methodsTest.java +++ /dev/null @@ -1,2458 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleMemoryStorage; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.skyscreamer.jsonassert.JSONAssert; - -import java.lang.reflect.Method; -import java.util.Arrays; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.MemoryStorage; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.util.KuzzleJSONObject; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class methodsTest { - private Kuzzle kuzzle; - private Kuzzle.QueryArgs queryArgs = new Kuzzle.QueryArgs(); - private MemoryStorage ms; - private ArgumentCaptor capturedQueryArgs; - private ArgumentCaptor capturedQuery; - - private static T[] concat(T[] first, T[] second) { - T[] result = Arrays.copyOf(first, first.length + second.length); - System.arraycopy(second, 0, result, first.length, second.length); - return result; - } - - private void validate(String command, JSONObject expected, boolean withOpts) throws JSONException { - assertEquals(((Kuzzle.QueryArgs) capturedQueryArgs.getValue()).controller, "ms"); - assertEquals(((Kuzzle.QueryArgs) capturedQueryArgs.getValue()).action, command); - - /* - if options are provided, the expected result should come first - as the assertion expects the second argument to contain at least - the JSON properties contained in the first one - - And vice versa without options provided - */ - if (withOpts) { - JSONAssert.assertEquals(expected, (JSONObject)capturedQuery.getValue(), false); - } - else { - JSONAssert.assertEquals(capturedQuery.getValue().toString(), expected, false); - } - } - - private ResponseListener verifyResultLong(long returnValue, final long expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(Long response) { - assertEquals((long)response, expected); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultInt(int returnValue, final int expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(Integer response) { - assertEquals((int)response, expected); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultString(String returnValue, final String expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(String response) { - assertEquals(response, expected); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultStringArray(String returnValue, final String[] expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(String[] response) { - assertArrayEquals(response, expected); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultStringArray(final JSONArray returnValue, final String[] expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(String[] response) { - assertArrayEquals(response, expected); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultJSONObjectArray(JSONArray value, final JSONObject[] expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", value)); - - return new ResponseListener() { - @Override - public void onSuccess(JSONObject[] response) { - for (int i = 0; i < response.length; i++) { - try { - JSONAssert.assertEquals(response[i], expected[i], false); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - private ResponseListener verifyResultDouble(String returnValue, final double expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", returnValue)); - - return new ResponseListener() { - @Override - public void onSuccess(Double response) { - assertEquals(response, expected, 10e-12); - } - - @Override - public void onError(JSONObject error) { - } - }; - } - - private ResponseListener verifyResultJSONObject(JSONArray value, final JSONObject expected) throws JSONException { - mockResult(new KuzzleJSONObject().put("result", value)); - - return new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - try { - JSONAssert.assertEquals(response, expected, false); - } - catch(JSONException e) { - fail(e.getMessage()); - } - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - private void mockResult(final KuzzleJSONObject raw) throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(raw); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - private void testReadMethod(String command, Class[] proto, Object[] args, Options opts, JSONObject expected) throws Exception { - Class[] overloadedProto; - Object[] overloadedArgs; - Method mscommand; - - // With options and listener - overloadedProto = concat(proto, new Class[]{Options.class, ResponseListener.class}); - overloadedArgs = concat(args, new Object[]{opts, mock(ResponseListener.class)}); - mscommand = MemoryStorage.class.getDeclaredMethod(command, overloadedProto); - mscommand.invoke(ms, overloadedArgs); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq(opts), any(OnQueryDoneListener.class)); - validate(command, expected, true); - - // Without options, with listener - overloadedProto = concat(proto, new Class[]{ResponseListener.class}); - overloadedArgs = concat(args, new Object[]{mock(ResponseListener.class)}); - mscommand = MemoryStorage.class.getDeclaredMethod(command, overloadedProto); - mscommand.invoke(ms, overloadedArgs); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq((Options)null), any(OnQueryDoneListener.class)); - validate(command, expected, false); - } - - private void testWriteMethod(String command, Class[] proto, Object[] args, Options opts, JSONObject expected) throws Exception { - Class[] overloadedProto; - Object[] overloadedArgs; - Method mscommand = MemoryStorage.class.getDeclaredMethod(command, proto); - - // Without options nor listener - mscommand.invoke(ms, args); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq((Options)null)); - validate(command, expected, false); - - // With options, without listener - overloadedProto = concat(proto, new Class[]{Options.class}); - overloadedArgs = concat(args, new Object[]{opts}); - mscommand = MemoryStorage.class.getDeclaredMethod(command, overloadedProto); - mscommand.invoke(ms, overloadedArgs); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq(opts)); - validate(command, expected, true); - - // With options and listener - overloadedProto = concat(overloadedProto, new Class[]{ResponseListener.class}); - overloadedArgs = concat(overloadedArgs, new Object[]{mock(ResponseListener.class)}); - mscommand = MemoryStorage.class.getDeclaredMethod(command, overloadedProto); - mscommand.invoke(ms, overloadedArgs); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq(opts), any(OnQueryDoneListener.class)); - validate(command, expected, true); - - // Without options, with listener - overloadedProto = concat(proto, new Class[]{ResponseListener.class}); - overloadedArgs = concat(args, new Object[]{mock(ResponseListener.class)}); - mscommand = MemoryStorage.class.getDeclaredMethod(command, overloadedProto); - mscommand.invoke(ms, overloadedArgs); - verify(kuzzle).query((Kuzzle.QueryArgs) capturedQueryArgs.capture(), (JSONObject)capturedQuery.capture(), eq((Options)null), any(OnQueryDoneListener.class)); - validate(command, expected, false); - } - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - ms = new MemoryStorage(kuzzle); - capturedQueryArgs = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - capturedQuery = ArgumentCaptor.forClass(io.kuzzle.sdk.util.KuzzleJSONObject.class); - queryArgs.controller = "ms"; - } - - @Test - public void append() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("value", "bar") - ); - - this.testWriteMethod("append", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.append("foo", "bar", listener); - } - - @Test - public void bitcount() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setStart((long)13) - .setEnd((long)42); - Object[] args = new Object[]{"foo"}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("start", 13) - .put("end", 42); - - this.testReadMethod("bitcount", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.bitcount("foo", listener); - } - - @Test - public void bitop() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar"}; - Object[] args = new Object[]{"foo", "xor", keys}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("operation", "xor") - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - this.testWriteMethod("bitop", new Class[]{String.class, String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.bitop("foo", "bar", keys, listener); - } - - @Test - public void bitpos() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setStart((long)13) - .setEnd((long)42); - Object[] args = new Object[]{"foo", 1}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("bit", 1) - .put("start", 13) - .put("end", 42); - - this.testReadMethod("bitpos", new Class[]{String.class, int.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.bitpos("foo", 1, listener); - } - - @Test - public void dbsize() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{}; - JSONObject expected = new JSONObject(); - - this.testReadMethod("dbsize", new Class[]{}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.dbsize(listener); - } - - @Test - public void decr() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo"}; - JSONObject expected = new JSONObject().put("_id", "foo"); - - this.testWriteMethod("decr", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.decr("foo", listener); - } - - @Test - public void decrby() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", -42}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("value", -42) - ); - - this.testWriteMethod("decrby", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.decrby("foo", -42, listener); - } - - @Test - public void del() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - this.testWriteMethod("del", new Class[]{String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.del(keys, listener); - } - - @Test - public void exists() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("exists", new Class[]{String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.exists(keys, listener); - } - - @Test - public void expire() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", 42}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("seconds", 42) - ); - - this.testWriteMethod("expire", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.expire("foo", 42, listener); - } - - @Test - public void expireat() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", 42}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("timestamp", 42) - ); - - this.testWriteMethod("expireat", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.expireat("foo", 42, listener); - } - - @Test - public void flushdb() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{}; - JSONObject expected = new JSONObject(); - - this.testWriteMethod("flushdb", new Class[]{}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.flushdb(listener); - } - - @Test - public void geoadd() throws Exception { - Options opts = new Options().setQueuable(true); - JSONObject[] points = new JSONObject[]{ - new JSONObject() - .put("lon", 13.361389) - .put("lat", 38.115556) - .put("name", "Palermo"), - new JSONObject() - .put("lon", 15.087269) - .put("lat", 37.502669) - .put("name", "Catania") - }; - Object[] args = new Object[]{"foo", points}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("points", new JSONArray(Arrays.asList(points))) - ); - - this.testWriteMethod("geoadd", new Class[]{String.class, JSONObject[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.geoadd("foo", points, listener); - } - - @Test - public void geodist() throws Exception { - Options opts = new Options().setQueuable(true).setUnit("ft"); - Object[] args = new Object[]{"key", "Palermo", "Catania"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member1", "Palermo") - .put("member2", "Catania") - .put("unit", "ft"); - - this.testReadMethod("geodist", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultDouble("166274.1516", 166274.1516); - ms.geodist("foo", "Palermo", "Catania", listener); - } - - @Test - public void geohash() throws Exception { - Options opts = new Options().setQueuable(true); - String[] members = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", members}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("members", new JSONArray(Arrays.asList(members))); - - this.testReadMethod("geohash", new Class[]{String.class, String[].class}, args, opts, expected); - - String[] expectedResult = new String[]{"sqc8b49rny0", "sqdtr74hyu0"}; - JSONArray rawResult = new JSONArray().put("sqc8b49rny0").put("sqdtr74hyu0"); - ResponseListener listener = verifyResultStringArray(rawResult, expectedResult); - ms.geohash("key", members, listener); - } - - @Test - public void geopos() throws Exception { - Options opts = new Options().setQueuable(true); - String[] members = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", members}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("members", new JSONArray(Arrays.asList(members))); - - this.testReadMethod("geopos", new Class[]{String.class, String[].class}, args, opts, expected); - - JSONArray rawResult = new JSONArray() - .put(new JSONArray().put("13.361389").put("38.115556")) - .put(new JSONArray().put("15.087269").put("37.502669")); - - mockResult(new KuzzleJSONObject().put("result", rawResult)); - - final Double[][] expectedResult = new Double[][]{ - {13.361389, 38.115556}, - {15.087269, 37.502669} - }; - - ms.geopos("key", members, new ResponseListener() { - @Override - public void onSuccess(Double[][] response) { - for (int i = 0; i < response.length; i++) { - assertArrayEquals(response[i], expectedResult[i]); - } - } - - @Override - public void onError(JSONObject error) { - fail("onError callback should not have been invoked"); - } - }); - } - - @Test - public void georadius() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setSort("asc") - .setWithcoord(true) - .setWithdist(true); - Object[] args = new Object[]{"key", 15, 37, 200, "km"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("lon", 15) - .put("lat", 37) - .put("distance", 200) - .put("unit", "km"); - - this.testReadMethod("georadius", new Class[]{String.class, double.class, double.class, double.class, String.class}, args, opts, expected); - - // without coordinates nor distance - opts.setWithcoord(false).setWithdist(false); - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("Palermo").put("Catania"), - new JSONObject[]{ - new JSONObject().put("name", "Palermo"), - new JSONObject().put("name", "Catania") - } - ); - ms.georadius("key", 15, 37, 200, "km", opts, listener); - - // with coordinates, without distance - opts.setWithcoord(true).setWithdist(false); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put("190.4424") - ).put( - new JSONArray() - .put("Catania").put("56.4413") - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo").put("distance", 190.4424), - new JSONObject().put("name", "Catania").put("distance", 56.4413) - } - ); - ms.georadius("key", 15, 37, 200, "km", opts, listener); - - // without coordinates, with distance - opts.setWithcoord(false).setWithdist(true); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put(new JSONArray().put("13.3613").put("38.1155")) - ).put( - new JSONArray() - .put("Catania").put(new JSONArray().put("15.0872").put("37.5026")) - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo") - .put("coordinates", new JSONArray().put(13.3613).put(38.1155)), - new JSONObject().put("name", "Catania") - .put("coordinates", new JSONArray().put(15.0872).put(37.5026)) - } - ); - ms.georadius("key", 15, 37, 200, "km", opts, listener); - - // with coordinates, with distance - opts.setWithcoord(true).setWithdist(true); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put(new JSONArray().put("13.3613").put("38.1155")).put("190.4424") - ).put( - new JSONArray() - .put("Catania").put("56.4413").put(new JSONArray().put("15.0872").put("37.5026")) - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo") - .put("distance", 190.4424) - .put("coordinates", new JSONArray().put(13.3613).put(38.1155)), - new JSONObject().put("name", "Catania") - .put("distance", 56.4413) - .put("coordinates", new JSONArray().put(15.0872).put(37.5026)) - } - ); - ms.georadius("key", 15, 37, 200, "km", opts, listener); - } - - @Test - public void georadiusbymember() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setSort("asc") - .setWithcoord(true) - .setWithdist(true); - Object[] args = new Object[]{"key", "Palermo", 200, "km"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member", "Palermo") - .put("distance", 200) - .put("unit", "km"); - - this.testReadMethod("georadiusbymember", new Class[]{String.class, String.class, double.class, String.class}, args, opts, expected); - - // without coordinates nor distance - opts.setWithcoord(false).setWithdist(false); - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("Palermo").put("Catania"), - new JSONObject[]{ - new JSONObject().put("name", "Palermo"), - new JSONObject().put("name", "Catania") - } - ); - ms.georadiusbymember("key", "Palermo", 200, "km", opts, listener); - - // with coordinates, without distance - opts.setWithcoord(true).setWithdist(false); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put("190.4424") - ).put( - new JSONArray() - .put("Catania").put("56.4413") - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo").put("distance", 190.4424), - new JSONObject().put("name", "Catania").put("distance", 56.4413) - } - ); - ms.georadiusbymember("key", "Palermo", 200, "km", opts, listener); - - // without coordinates, with distance - opts.setWithcoord(false).setWithdist(true); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put(new JSONArray().put("13.3613").put("38.1155")) - ).put( - new JSONArray() - .put("Catania").put(new JSONArray().put("15.0872").put("37.5026")) - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo") - .put("coordinates", new JSONArray().put(13.3613).put(38.1155)), - new JSONObject().put("name", "Catania") - .put("coordinates", new JSONArray().put(15.0872).put(37.5026)) - } - ); - ms.georadiusbymember("key", "Palermo", 200, "km", opts, listener); - - // with coordinates, with distance - opts.setWithcoord(true).setWithdist(true); - listener = verifyResultJSONObjectArray( - new JSONArray().put( - new JSONArray() - .put("Palermo").put(new JSONArray().put("13.3613").put("38.1155")).put("190.4424") - ).put( - new JSONArray() - .put("Catania").put("56.4413").put(new JSONArray().put("15.0872").put("37.5026")) - ), - new JSONObject[]{ - new JSONObject().put("name", "Palermo") - .put("distance", 190.4424) - .put("coordinates", new JSONArray().put(13.3613).put(38.1155)), - new JSONObject().put("name", "Catania") - .put("distance", 56.4413) - .put("coordinates", new JSONArray().put(15.0872).put(37.5026)) - } - ); - ms.georadiusbymember("key", "Palermo", 200, "km", opts, listener); - } - - @Test - public void get() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("get", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.get("key", listener); - } - - @Test - public void getbit() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 10}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("offset", 10); - - this.testReadMethod("getbit", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.getbit("key", 10, listener); - } - - @Test - public void getrange() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("start", 13) - .put("end", 42); - - this.testReadMethod("getrange", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.getrange("key", 13, 42, listener); - } - - @Test - public void getset() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "value"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("value", "value")); - - this.testWriteMethod("getset", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.getset("key", "value", listener); - } - - @Test - public void hdel() throws Exception { - Options opts = new Options().setQueuable(true); - String[] fields = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", fields}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("fields", new JSONArray(Arrays.asList(fields)))); - - this.testWriteMethod("hdel", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.hdel("key", fields, listener); - } - - @Test - public void hexists() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foobar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("field", "foobar"); - - this.testReadMethod("hexists", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(1, 1); - ms.hexists("key", "foobar", listener); - } - - @Test - public void hget() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("field", "foo"); - - this.testReadMethod("hget", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("bar", "bar"); - ms.hget("key", "foo", listener); - } - - @Test - public void hgetall() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("hgetall", new Class[]{String.class}, args, opts, expected); - - final KuzzleJSONObject result = new KuzzleJSONObject().put("foo", "bar"); - mockResult(new KuzzleJSONObject().put("result", result)); - - ResponseListener listener =new ResponseListener() { - @Override - public void onSuccess(JSONObject response) { - assertEquals(response, result); - } - - @Override - public void onError(JSONObject error) { - } - }; - - ms.hgetall("key", listener); - } - - @Test - public void hincrby() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", 42) - .put("field", "foo") - ); - - this.testWriteMethod("hincrby", new Class[]{String.class, String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.hincrby("foo", "bar", 42, listener); - } - - @Test - public void hincrbyfloat() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", 3.14159}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", 3.14159) - .put("field", "foo") - ); - - this.testWriteMethod("hincrbyfloat", new Class[]{String.class, String.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultDouble("48.14159", 48.14159); - ms.hincrbyfloat("foo", "bar", 3.14159, listener); - } - - @Test - public void hkeys() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("hkeys", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.hkeys("key", listener); - } - - @Test - public void hlen() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("hlen", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.hlen("key", listener); - } - - @Test - public void hmget() throws Exception { - Options opts = new Options().setQueuable(true); - String[] fields = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", fields}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("fields", new JSONArray(Arrays.asList(fields))); - - this.testReadMethod("hmget", new Class[]{String.class, String[].class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(result, fields); - ms.hmget("key", fields, listener); - } - - @Test - public void hmset() throws Exception { - Options opts = new Options().setQueuable(true); - JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("field", "field1").put("value", "foo"), - new JSONObject().put("field", "field2").put("value", "bar"), - new JSONObject().put("field", "...").put("value", "...") - }; - - Object[] args = new Object[]{"key", entries}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("entries", new JSONArray(Arrays.asList(entries))) - ); - - this.testWriteMethod("hmset", new Class[]{String.class, JSONObject[].class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.hmset("key", entries, listener); - } - - @Test - public void hscan() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setMatch("foo*"); - Object[] args = new Object[]{"key", 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("cursor", 42) - .put("count", 10) - .put("match", "foo*"); - - this.testReadMethod("hscan", new Class[]{String.class, long.class}, args, opts, expected); - - JSONArray result = new JSONArray() - .put("18") - .put(new JSONArray() - .put("field1") - .put("field1 value") - .put("field2") - .put("field2 value") - ); - - JSONObject expectedResult = new JSONObject() - .put("cursor", 18) - .put("values", new JSONArray() - .put("field1") - .put("field1 value") - .put("field2") - .put("field2 value") - ); - - ResponseListener listener = verifyResultJSONObject(result, expectedResult); - ms.hscan("key", 42, listener); - } - - @Test - public void hset() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("field", "foo") - .put("value", "bar") - ); - - this.testWriteMethod("hset", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.hset("key", "foo", "bar", listener); - } - - @Test - public void hsetnx() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("field", "foo") - .put("value", "bar") - ); - - this.testWriteMethod("hsetnx", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.hsetnx("key", "foo", "bar", listener); - } - - @Test - public void hstrlen() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("field", "foo"); - - this.testReadMethod("hstrlen", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.hstrlen("key", "foo", listener); - } - - @Test - public void hvals() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("hvals", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.hvals("key", listener); - } - - @Test - public void incr() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo"}; - JSONObject expected = new JSONObject().put("_id", "foo"); - - this.testWriteMethod("incr", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.incr("foo", listener); - } - - @Test - public void incrby() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", -42}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("value", -42) - ); - - this.testWriteMethod("incrby", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.incrby("foo", -42, listener); - } - - @Test - public void incrbyfloat() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo", 3.14159}; - JSONObject expected = new JSONObject() - .put("_id", "foo") - .put("body", new JSONObject() - .put("value", 3.14159) - ); - - this.testWriteMethod("incrbyfloat", new Class[]{String.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultDouble("48.14159", 48.14159); - ms.incrbyfloat("foo", 3.14159, listener); - } - - @Test - public void keys() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"foo*"}; - JSONObject expected = new JSONObject() - .put("pattern", "foo*"); - - this.testReadMethod("keys", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.keys("foo*", listener); - } - - @Test - public void lindex() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 10}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("index", 10); - - this.testReadMethod("lindex", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foo", "foo"); - ms.lindex("key", 10, listener); - } - - @Test - public void linsert() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "before", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "bar") - .put("position", "before") - .put("pivot", "foo") - ); - - this.testWriteMethod("linsert", new Class[]{String.class, String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.linsert("key", "before", "foo", "bar", listener); - } - - @Test - public void llen() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("llen", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.llen("key", listener); - } - - @Test - public void lpop() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testWriteMethod("lpop", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.lpop("key", listener); - } - - @Test - public void lpush() throws Exception { - Options opts = new Options().setQueuable(true); - String[] values = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", values}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("values", new JSONArray(Arrays.asList(values))) - ); - - this.testWriteMethod("lpush", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.lpush("key", values, listener); - } - - @Test - public void lpushx() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "value"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("value", "value")); - - this.testWriteMethod("lpushx", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.lpushx("key", "value", listener); - } - - @Test - public void lrange() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("start", 13) - .put("stop", 42); - - this.testReadMethod("lrange", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.lrange("key", 13, 42, listener); - } - - @Test - public void lrem() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 42, "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "bar") - .put("count", 42) - ); - - this.testWriteMethod("lrem", new Class[]{String.class, long.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.lrem("key", 42, "bar", listener); - } - - - @Test - public void lset() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 42, "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "bar") - .put("index", 42) - ); - - this.testWriteMethod("lset", new Class[]{String.class, long.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foo", "foo"); - ms.lset("key", 42, "bar", listener); - } - - @Test - public void ltrim() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("start", 13) - .put("stop", 42) - ); - - this.testWriteMethod("ltrim", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foo", "foo"); - ms.ltrim("key", 13, 42, listener); - } - - @Test - public void mget() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("mget", new Class[]{String[].class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(result, keys); - ms.mget(keys, listener); - } - - @Test - public void mset() throws Exception { - Options opts = new Options().setQueuable(true); - JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("key", "key1").put("value", "foo"), - new JSONObject().put("key", "key2").put("value", "bar"), - new JSONObject().put("key", "...").put("value", "...") - }; - - Object[] args = new Object[]{entries}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("entries", new JSONArray(Arrays.asList(entries))) - ); - - this.testWriteMethod("mset", new Class[]{JSONObject[].class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.mset(entries, listener); - } - - - @Test - public void msetnx() throws Exception { - Options opts = new Options().setQueuable(true); - JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("key", "key1").put("value", "foo"), - new JSONObject().put("key", "key2").put("value", "bar"), - new JSONObject().put("key", "...").put("value", "...") - }; - - Object[] args = new Object[]{entries}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("entries", new JSONArray(Arrays.asList(entries))) - ); - - this.testWriteMethod("msetnx", new Class[]{JSONObject[].class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.msetnx(entries, listener); - } - - @Test - public void object() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "encoding"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("subcommand", "encoding"); - - this.testReadMethod("object", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.object("key", "encoding", listener); - } - - @Test - public void persist() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testWriteMethod("persist", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.persist("key", listener); - } - - @Test - public void pexpire() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 42000}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("milliseconds", 42000) - ); - - this.testWriteMethod("pexpire", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.pexpire("key", 42000, listener); - } - - @Test - public void pexpireat() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 1234567890}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("timestamp", 1234567890) - ); - - this.testWriteMethod("pexpireat", new Class[]{String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.pexpireat("key", 1234567890, listener); - } - - @Test - public void pfadd() throws Exception { - Options opts = new Options().setQueuable(true); - String[] elements = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", elements}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("elements", new JSONArray(Arrays.asList(elements))) - ); - - this.testWriteMethod("pfadd", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(123, 123); - ms.pfadd("key", elements, listener); - } - - @Test - public void pfcount() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("pfcount", new Class[]{String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.pfcount(keys, listener); - } - - @Test - public void pfmerge() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar" , "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("sources", new JSONArray(Arrays.asList(keys))) - ); - - this.testWriteMethod("pfmerge", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.pfmerge("key", keys, listener); - } - - @Test - public void ping() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{}; - JSONObject expected = new JSONObject(); - - this.testReadMethod("ping", new Class[]{}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.ping(listener); - } - - @Test - public void psetex() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", 42000}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "foo") - .put("milliseconds", 42000) - ); - - this.testWriteMethod("psetex", new Class[]{String.class, String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.psetex("key", "foo", 42000, listener); - } - - @Test - public void pttl() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("pttl", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.pttl("key", listener); - } - - @Test - public void randomkey() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{}; - JSONObject expected = new JSONObject(); - - this.testReadMethod("randomkey", new Class[]{}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.randomkey(listener); - } - - @Test - public void rename() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("newkey", "foo") - ); - - this.testWriteMethod("rename", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.rename("key", "foo", listener); - } - - @Test - public void renamenx() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("newkey", "foo") - ); - - this.testWriteMethod("renamenx", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(1, 1); - ms.renamenx("key", "foo", listener); - } - - @Test - public void rpop() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testWriteMethod("rpop", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.rpop("key", listener); - } - - @Test - public void rpoplpush() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "dest"}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("source", "key") - .put("destination", "dest") - ); - - this.testWriteMethod("rpoplpush", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.rpoplpush("key", "dest", listener); - } - - @Test - public void rpush() throws Exception { - Options opts = new Options().setQueuable(true); - String[] values = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", values}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("values", new JSONArray(Arrays.asList(values))) - ); - - this.testWriteMethod("rpush", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.rpush("key", values, listener); - } - - @Test - public void rpushx() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "value"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("value", "value")); - - this.testWriteMethod("rpushx", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.rpushx("key", "value", listener); - } - - @Test - public void sadd() throws Exception { - Options opts = new Options().setQueuable(true); - String[] members = new String[]{"foo", "bar", "baz"}; - - Object[] args = new Object[]{"key", members}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - this.testWriteMethod("sadd", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.sadd("key", members, listener); - } - - @Test - public void scan() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setMatch("foo*"); - Object[] args = new Object[]{42}; - JSONObject expected = new JSONObject() - .put("cursor", 42) - .put("count", 10) - .put("match", "foo*"); - - this.testReadMethod("scan", new Class[]{long.class}, args, opts, expected); - - JSONArray result = new JSONArray() - .put("18") - .put(new JSONArray() - .put("field1") - .put("field1 value") - .put("field2") - .put("field2 value") - ); - - JSONObject expectedResult = new JSONObject() - .put("cursor", 18) - .put("values", result.getJSONArray(1)); - - ResponseListener listener = verifyResultJSONObject(result, expectedResult); - ms.scan(42, listener); - } - - @Test - public void scard() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("scard", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.scard("key", listener); - } - - @Test - public void sdiff() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("sdiff", new Class[]{String.class, String[].class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(result, keys); - ms.sdiff("key", keys, listener); - } - - @Test - public void sdiffstore() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys, "dest"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - .put("destination", "dest") - ); - - this.testWriteMethod("sdiffstore", new Class[]{String.class, String[].class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.sdiffstore("key", keys, "dest", listener); - } - - @Test - public void set() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setEx((long)123) - .setNx(true) - .setPx((long)456) - .setXx(false); - Object[] args = new Object[]{"key", "value"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "value") - .put("ex", 123) - .put("nx", true) - .put("px", 456) - .put("xx", false) - ); - - this.testWriteMethod("set", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.set("key", "value", listener); - } - - @Test - public void setex() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", "foo") - .put("seconds", 42) - ); - - this.testWriteMethod("setex", new Class[]{String.class, String.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("OK", "OK"); - ms.setex("key", "foo", 42, listener); - } - - @Test - public void setnx() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "value"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("value", "value")); - - this.testWriteMethod("setnx", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(1, 1); - ms.setnx("key", "value", listener); - } - - @Test - public void sinter() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("sinter", new Class[]{String[].class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(result, keys); - ms.sinter(keys, listener); - } - - @Test - public void sinterstore() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - .put("destination", "key") - ); - - this.testWriteMethod("sinterstore", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.sinterstore("key", keys, listener); - } - - @Test - public void sismember() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member", "foo"); - - this.testReadMethod("sismember", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(1, 1); - ms.sismember("key", "foo", listener); - } - - @Test - public void smembers() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("smembers", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.smembers("key", listener); - } - - @Test - public void smove() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("destination", "foo") - .put("member", "bar") - ); - - this.testWriteMethod("smove", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultInt(1, 1); - ms.smove("key", "foo", "bar", listener); - } - - @Test - public void sort() throws Exception { - String[] array = new String[]{"foo", "bar", "baz"}; - Integer[] limit = new Integer[]{13, 42}; - Options opts = new Options() - .setQueuable(true) - .setAlpha(true) - .setBy("foobar") - .setDirection("asc") - .setGet(array) - .setLimit(limit); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("alpha", true) - .put("by", "foobar") - .put("direction", "asc") - .put("get", new JSONArray(Arrays.asList(array))) - .put("limit", new JSONArray(Arrays.asList(limit))); - - this.testReadMethod("sort", new Class[]{String.class}, args, opts, expected); - - JSONArray rawResult = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(rawResult, array); - ms.sort("key", listener); - } - - @Test - public void spop() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject().put("count", 10)); - - this.testWriteMethod("spop", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.spop("key", listener); - - listener = verifyResultStringArray("foo", new String[]{"foo"}); - ms.spop("key", listener); - } - - @Test - public void srandmember() throws Exception { - Options opts = new Options().setQueuable(true).setCount((long)10); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("count", 10); - - this.testReadMethod("srandmember", new Class[]{String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.srandmember("key", listener); - - listener = verifyResultStringArray("foo", new String[]{"foo"}); - ms.srandmember("key", listener); - } - - @Test - public void srem() throws Exception { - Options opts = new Options().setQueuable(true); - String[] members = new String[]{"foo", "bar", "baz"}; - - Object[] args = new Object[]{"key", members}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - this.testWriteMethod("srem", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.srem("key", members, listener); - } - - @Test - public void sscan() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setMatch("foo*"); - Object[] args = new Object[]{"key", 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("cursor", 42) - .put("count", 10) - .put("match", "foo*"); - - this.testReadMethod("sscan", new Class[]{String.class, long.class}, args, opts, expected); - - JSONArray result = new JSONArray() - .put("18") - .put(new JSONArray() - .put("field1") - .put("field1 value") - .put("field2") - .put("field2 value") - ); - - JSONObject expectedResult = new JSONObject() - .put("cursor", 18) - .put("values", result.getJSONArray(1)); - - ResponseListener listener = verifyResultJSONObject(result, expectedResult); - ms.sscan("key", 42, listener); - } - - @Test - public void strlen() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("strlen", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.strlen("key", listener); - } - - @Test - public void sunion() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))); - - this.testReadMethod("sunion", new Class[]{String[].class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - ResponseListener listener = verifyResultStringArray(result, keys); - ms.sunion(keys, listener); - } - - @Test - public void sunionstore() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - .put("destination", "key") - ); - - this.testWriteMethod("sunionstore", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.sunionstore("key", keys, listener); - } - - @Test - public void time() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{}; - JSONObject expected = new JSONObject(); - - this.testReadMethod("time", new Class[]{}, args, opts, expected); - - mockResult(new KuzzleJSONObject().put("result", new JSONArray().put("123").put("456"))); - - ms.time(new ResponseListener() { - @Override - public void onSuccess(Long[] response) { - assertArrayEquals(response, new Long[]{Long.valueOf(123), Long.valueOf(456)}); - } - - @Override - public void onError(JSONObject error) { - - } - }); - } - - @Test - public void touch() throws Exception { - Options opts = new Options().setQueuable(true); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{keys}; - JSONObject expected = new JSONObject() - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - ); - - this.testWriteMethod("touch", new Class[]{String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.touch(keys, listener); - } - - @Test - public void ttl() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("ttl", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.ttl("key", listener); - } - - @Test - public void type() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("type", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultString("foobar", "foobar"); - ms.type("key", listener); - } - - @Test - public void zadd() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCh(true) - .setIncr(true) - .setNx(true) - .setXx(false); - JSONObject[] elements = new JSONObject[]{ - new JSONObject().put("score", 1).put("member", "foo"), - new JSONObject().put("score", 2).put("member", "bar"), - new JSONObject().put("score", 3).put("member", "baz") - }; - - - Object[] args = new Object[]{"key", elements}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("elements", new JSONArray(Arrays.asList(elements))) - .put("ch", true) - .put("incr", true) - .put("nx", true) - .put("xx", false) - ); - - this.testWriteMethod("zadd", new Class[]{String.class, JSONObject[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zadd("key", elements, listener); - } - - @Test - public void zcard() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key"}; - JSONObject expected = new JSONObject() - .put("_id", "key"); - - this.testReadMethod("zcard", new Class[]{String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zcard("key", listener); - } - - @Test - public void zcount() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", 13) - .put("max", 42); - - this.testReadMethod("zcount", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zcount("key", 13, 42, listener); - } - - @Test - public void zincrby() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", 3.14159}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("value", 3.14159) - .put("member", "foo") - ); - - this.testWriteMethod("zincrby", new Class[]{String.class, String.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultDouble("48.14159", 48.14159); - ms.zincrby("foo", "bar", 3.14159, listener); - } - - @Test - public void zinterstore() throws Exception { - Integer[] weights = new Integer[]{1, 2, 3}; - Options opts = new Options() - .setQueuable(true) - .setAggregate("max") - .setWeights(weights); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - .put("aggregate", "max") - .put("weights", new JSONArray(Arrays.asList(weights))) - ); - - this.testWriteMethod("zinterstore", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zinterstore("key", keys, listener); - } - - @Test - public void zlexcount() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", "foo") - .put("max", "bar"); - - this.testReadMethod("zlexcount", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zlexcount("key", "foo", "bar", listener); - } - - @Test - public void zrange() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("start", 13) - .put("stop", 42) - .put("options", new JSONArray().put("withscores")); - - this.testReadMethod("zrange", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("foo").put("3.14159").put("bar").put("123.456"), - new JSONObject[]{ - new JSONObject().put("member", "foo").put("score", 3.14159), - new JSONObject().put("member", "bar").put("score", 123.456) - } - ); - ms.zrange("key", 13, 42, listener); - } - - @Test - public void zrangebylex() throws Exception { - Integer[] limit = new Integer[]{1, 2}; - Options opts = new Options() - .setQueuable(true) - .setLimit(limit); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", "foo") - .put("max", "bar") - .put("limit", new JSONArray(Arrays.asList(limit))); - - this.testReadMethod("zrangebylex", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.zrangebylex("key", "foo", "bar", listener); - } - - @Test - public void zrangebyscore() throws Exception { - Integer[] limit = new Integer[]{1, 2}; - Options opts = new Options() - .setQueuable(true) - .setLimit(limit); - Object[] args = new Object[]{"key", 3.14, 42.24}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", 3.14) - .put("max", 42.24) - .put("limit", new JSONArray(Arrays.asList(limit))) - .put("options", new JSONArray().put("withscores")); - - this.testReadMethod("zrangebyscore", new Class[]{String.class, double.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("foo").put("3.14159").put("bar").put("123.456"), - new JSONObject[]{ - new JSONObject().put("member", "foo").put("score", 3.14159), - new JSONObject().put("member", "bar").put("score", 123.456) - } - ); - ms.zrangebyscore("key", 3.14, 42.24, listener); - } - - @Test - public void zrank() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member", "foo"); - - this.testReadMethod("zrank", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zrank("key", "foo", listener); - } - - @Test - public void zrem() throws Exception { - Options opts = new Options().setQueuable(true); - String[] members = new String[]{"foo", "bar", "baz"}; - - Object[] args = new Object[]{"key", members}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("members", new JSONArray(Arrays.asList(members))) - ); - - this.testWriteMethod("zrem", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zrem("key", members, listener); - } - - @Test - public void zremrangebylex() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("min", "foo") - .put("max", "bar") - ); - - this.testWriteMethod("zremrangebylex", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zremrangebylex("key", "foo", "bar", listener); - } - - @Test - public void zremrangebyrank() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("start", 13) - .put("stop", 42) - ); - - this.testWriteMethod("zremrangebyrank", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zremrangebyrank("key", 13, 42, listener); - } - - @Test - public void zremrangebyscore() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13.1, 42.3}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("min", 13.1) - .put("max", 42.3) - ); - - this.testWriteMethod("zremrangebyscore", new Class[]{String.class, double.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zremrangebyscore("key", 13, 42, listener); - } - - @Test - public void zrevrange() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", 13, 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("start", 13) - .put("stop", 42) - .put("options", new JSONArray().put("withscores")); - - this.testReadMethod("zrevrange", new Class[]{String.class, long.class, long.class}, args, opts, expected); - - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("foo").put("3.14159").put("bar").put("123.456"), - new JSONObject[]{ - new JSONObject().put("member", "foo").put("score", 3.14159), - new JSONObject().put("member", "bar").put("score", 123.456) - } - ); - ms.zrevrange("key", 13, 42, listener); - } - - @Test - public void zrevrangebylex() throws Exception { - Integer[] limit = new Integer[]{1, 2}; - Options opts = new Options() - .setQueuable(true) - .setLimit(limit); - Object[] args = new Object[]{"key", "foo", "bar"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", "foo") - .put("max", "bar") - .put("limit", new JSONArray(Arrays.asList(limit))); - - this.testReadMethod("zrevrangebylex", new Class[]{String.class, String.class, String.class}, args, opts, expected); - - JSONArray result = new JSONArray().put("foo").put("bar").put("baz"); - String[] expectedResult = new String[]{"foo", "bar", "baz"}; - ResponseListener listener = verifyResultStringArray(result, expectedResult); - ms.zrevrangebylex("key", "foo", "bar", listener); - } - - @Test - public void zrevrangebyscore() throws Exception { - Integer[] limit = new Integer[]{1, 2}; - Options opts = new Options() - .setQueuable(true) - .setLimit(limit); - Object[] args = new Object[]{"key", 3.14, 42.24}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("min", 3.14) - .put("max", 42.24) - .put("limit", new JSONArray(Arrays.asList(limit))) - .put("options", new JSONArray().put("withscores")); - - this.testReadMethod("zrevrangebyscore", new Class[]{String.class, double.class, double.class}, args, opts, expected); - - ResponseListener listener = verifyResultJSONObjectArray( - new JSONArray().put("foo").put("3.14159").put("bar").put("123.456"), - new JSONObject[]{ - new JSONObject().put("member", "foo").put("score", 3.14159), - new JSONObject().put("member", "bar").put("score", 123.456) - } - ); - ms.zrevrangebyscore("key", 3.14, 42.24, listener); - } - - @Test - public void zrevrank() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member", "foo"); - - this.testReadMethod("zrevrank", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zrevrank("key", "foo", listener); - } - - @Test - public void zscan() throws Exception { - Options opts = new Options() - .setQueuable(true) - .setCount((long)10) - .setMatch("foo*"); - Object[] args = new Object[]{"key", 42}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("cursor", 42) - .put("count", 10) - .put("match", "foo*"); - - this.testReadMethod("zscan", new Class[]{String.class, long.class}, args, opts, expected); - - JSONArray result = new JSONArray() - .put("18") - .put(new JSONArray() - .put("field1") - .put("field1 value") - .put("field2") - .put("field2 value") - ); - - JSONObject expectedResult = new JSONObject() - .put("cursor", 18) - .put("values", result.getJSONArray(1)); - - ResponseListener listener = verifyResultJSONObject(result, expectedResult); - ms.zscan("key", 42, listener); - } - - @Test - public void zscore() throws Exception { - Options opts = new Options().setQueuable(true); - Object[] args = new Object[]{"key", "foo"}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("member", "foo"); - - this.testReadMethod("zscore", new Class[]{String.class, String.class}, args, opts, expected); - - ResponseListener listener = verifyResultDouble("3.14159", 3.14159); - ms.zscore("key", "foo", listener); - } - - @Test - public void zunionstore() throws Exception { - Integer[] weights = new Integer[]{1, 2, 3}; - Options opts = new Options() - .setQueuable(true) - .setAggregate("max") - .setWeights(weights); - String[] keys = new String[]{"foo", "bar", "baz"}; - Object[] args = new Object[]{"key", keys}; - JSONObject expected = new JSONObject() - .put("_id", "key") - .put("body", new JSONObject() - .put("keys", new JSONArray(Arrays.asList(keys))) - .put("aggregate", "max") - .put("weights", new JSONArray(Arrays.asList(weights))) - ); - - this.testWriteMethod("zunionstore", new Class[]{String.class, String[].class}, args, opts, expected); - - ResponseListener listener = verifyResultLong(123, 123); - ms.zunionstore("key", keys, listener); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/constructorTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/constructorTest.java deleted file mode 100644 index c053acb4..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/constructorTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleRoom; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.listeners.ResponseListener; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class constructorTest { - private ResponseListener listener = mock(ResponseListener.class); - private JSONObject mockNotif = new JSONObject(); - private JSONObject mockResponse = new JSONObject(); - private Kuzzle k; - private RoomExtend room; - - @Before - public void setUp() throws JSONException { - mockNotif.put("type", "type") - .put("index", "index") - .put("status", 200) - .put("collection", "collection") - .put("controller", "controller") - .put("action", "action") - .put("state", "ALL") - .put("scope", "ALL") - .put("volatile", new JSONObject()) - .put("result", new JSONObject()) - .put("requestId", "42"); - mockResponse.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - k = mock(Kuzzle.class); - when(k.getHeaders()).thenReturn(new JSONObject()); - room = new RoomExtend(new Collection(k, "test", "index")); - } - - @Test - public void setSubscribeToSelfThroughConstructor() throws JSONException { - JSONObject meta = new JSONObject(); - meta.put("foo", "bar"); - RoomOptions options = new RoomOptions(); - options.setSubscribeToSelf(false); - Room room = new Room(new Collection(k, "test", "index"), options); - assertEquals(room.isSubscribeToSelf(), false); - room.setSubscribeToSelf(true); - assertEquals(room.isSubscribeToSelf(), true); - } - - @Test(expected = RuntimeException.class) - public void testConstructorException() { - Collection fake = spy(new Collection(k, "test", "index")); - doThrow(JSONException.class).when(fake).getHeaders(); - room = new RoomExtend(fake); - } - - @Test - public void testSetHeaders() throws JSONException { - room.makeHeadersNull(); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - room.setHeaders(headers, true); - assertEquals(room.getHeaders().getString("foo"), "bar"); - headers.put("oof", "baz"); - room.setHeaders(headers); - assertEquals(room.getHeaders().getString("foo"), "bar"); - assertEquals(room.getHeaders().getString("oof"), "baz"); - } - - @Test(expected = RuntimeException.class) - public void testSetHeadersException() { - JSONObject json = spy(new JSONObject()); - doThrow(JSONException.class).when(json).keys(); - room.setHeaders(json, false); - } - - @Test - public void testGetHeaders() throws JSONException { - room.setHeaders(null); - assertNotNull(room.getHeaders()); - JSONObject headers = new JSONObject(); - headers.put("foo", "bar"); - room.setHeaders(headers); - assertEquals(room.getHeaders().getString("foo"), "bar"); - } - - @Test - public void testFilters() throws JSONException { - JSONObject filters = new JSONObject(); - filters.put("foo", "bar"); - - room.renew(filters, listener, null); - assertEquals(room.getFilters().getString("foo"), "bar"); - JSONObject filters2 = new JSONObject(); - filters2.put("foo", "rab"); - room.setFilters(filters2); - assertEquals(room.getFilters().getString("foo"), "rab"); - } - - @Test - public void setVolatileThroughConstructor() throws JSONException { - JSONObject meta = new JSONObject(); - meta.put("foo", "bar"); - RoomOptions options = new RoomOptions(); - options.setVolatile(meta); - Room room = new Room(new Collection(k, "test", "index"), options); - assertEquals(room.getVolatile().get("foo"), "bar"); - JSONObject meta2 = new JSONObject(); - meta2.put("oof", "rab"); - room.setVolatile(meta2); - assertEquals(room.getVolatile().get("oof"), "rab"); - } - - @Test(expected = IllegalArgumentException.class) - public void testConstructorWithNullCollection() { - // Should throw an exception - new Room(null); - } - - @Test - public void testCollection() { - Collection collection = new Collection(k, "test", "index"); - Room room = new Room(collection); - assertEquals(room.getCollection(), collection.getCollection()); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/countTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/countTest.java deleted file mode 100644 index d31c7b95..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/countTest.java +++ /dev/null @@ -1,167 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleRoom; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class countTest { - private ResponseListener listener = mock(ResponseListener.class); - private ResponseListener spyListener = spy(new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); - private JSONObject mockNotif = new JSONObject(); - private JSONObject mockResponse = new JSONObject(); - private KuzzleExtend k; - private RoomExtend room; - - @Before - public void setUp() throws JSONException, URISyntaxException { - mockNotif.put("type", "type") - .put("index", "index") - .put("status", 200) - .put("collection", "collection") - .put("controller", "controller") - .put("action", "action") - .put("state", "ALL") - .put("scope", "ALL") - .put("volatile", new JSONObject()) - .put("result", new JSONObject()) - .put("requestId", "42"); - mockResponse.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - k = spy(new KuzzleExtend("localhost", null, null)); - k.setSocket(mock(WebSocketClient.class)); - k.setState(States.CONNECTED); - when(k.getHeaders()).thenReturn(new JSONObject()); - room = new RoomExtend(new Collection(k, "test", "index")); - } - - @Test(expected = IllegalArgumentException.class) - public void testCountIllegalArgument() { - room.count(null); - } - - @Test - public void testCountWhileSubscribing() throws JSONException, URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.setSubscribing(true); - room.count(spyListener); - room = spy(room); - room.setSubscribing(false); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject() - .put("channel", "channel") - .put("roomId", "42") - .put("count", 42)); - //Call callback with response - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - verify(room).dequeue(); - - } - return null; - } - }).when(extended).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - room.renew(listener); - } - - @Test(expected = RuntimeException.class) - public void testCountQueryException() throws JSONException { - room.setRoomId("foobar"); - doThrow(JSONException.class).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(OnQueryDoneListener.class)); - room.count(listener); - } - - @Test(expected = RuntimeException.class) - public void testCountException() throws JSONException { - room.setRoomId("foobar"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[2]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(k).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - room.count(listener); - } - - @Test(expected = IllegalStateException.class) - public void testCountNoId() { - room.count(listener); - } - - @Test - public void testCount() throws JSONException, URISyntaxException { - JSONObject o = mock(JSONObject.class); - when(o.put(any(String.class), any(Object.class))).thenReturn(new JSONObject()); - - KuzzleExtend extended = new KuzzleExtend("localhost", null, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener)invocation.getArguments()[2]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - ((OnQueryDoneListener)invocation.getArguments()[2]).onError(new JSONObject()); - return null; - } - }).when(extended).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(OnQueryDoneListener.class)); - room.setRoomId("foobar"); - room.count(mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(extended, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "count"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/notificationHandlerTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/notificationHandlerTest.java deleted file mode 100644 index e2686350..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/notificationHandlerTest.java +++ /dev/null @@ -1,167 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleRoom; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Date; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.EventListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class notificationHandlerTest { - private ResponseListener listener = mock(ResponseListener.class); - private JSONObject mockNotif = new JSONObject(); - private JSONObject mockResponse = new JSONObject(); - private Kuzzle k; - private RoomExtend room; - - @Before - public void setUp() throws JSONException { - mockNotif.put("type", "type") - .put("index", "index") - .put("status", 200) - .put("collection", "collection") - .put("controller", "controller") - .put("action", "action") - .put("state", "all") - .put("scope", "all") - .put("volatile", new JSONObject()) - .put("result", new JSONObject()) - .put("requestId", "42"); - mockResponse.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - k = mock(Kuzzle.class); - when(k.getHeaders()).thenReturn(new JSONObject()); - room = new RoomExtend(new Collection(k, "test", "index")); - } - - @Test(expected = IllegalArgumentException.class) - public void testCallAfterRenewWithNoResponse() { - RoomExtend renew = new RoomExtend(new Collection(k, "test", "index")); - // Should throw an exception - renew.callAfterRenew(null); - } - - @Test - public void testCallAfterRenew() throws JSONException { - RoomExtend renew = new RoomExtend(new Collection(k, "test", "index")); - renew.setListener(listener); - JSONObject mockResponse = new JSONObject().put("result", new JSONObject()); - mockResponse.put("requestId", "42"); - renew.callAfterRenew(mockNotif); - } - - @Test - public void testCallAfterRenewWithSubscribeToSelf() throws JSONException, URISyntaxException { - RoomOptions options = new RoomOptions(); - options.setSubscribeToSelf(true); - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - WebSocketClient s = mock(WebSocketClient.class); - extended.setSocket(s); - extended.setState(States.CONNECTED); - extended = spy(extended); - RoomExtend renew = new RoomExtend(new Collection(extended, "test", "index"), options); - renew.setListener(listener); - extended.getRequestHistory().put("42", new Date()); - renew.callAfterRenew(mockNotif); - verify(listener, atLeastOnce()).onSuccess(any(JSONObject.class)); - } - - @Test - public void testRenewOn() throws JSONException, URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - WebSocketClient s = mock(WebSocketClient.class); - extended.setSocket(s); - extended.setState(States.CONNECTED); - extended = spy(extended); - room = new RoomExtend(new Collection(extended, "collection", "index")); - room.setRoomId("foobar"); - room = spy(room); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(extended).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - room.renew(listener); - } - - @Test - public void testTokenExpiredNotification() throws JSONException, URISyntaxException { - k = new Kuzzle("localhost"); - EventListener listener = spy(new EventListener() { - @Override - public void trigger(Object... args) { - - } - }); - k.addListener(Event.tokenExpired, listener); - RoomExtend renew = new RoomExtend(new Collection(k, "test", "index")); - renew.setListener(mock(ResponseListener.class)); - JSONObject mockResponse = new JSONObject().put("result", new JSONObject()); - mockResponse.put("requestId", "42"); - mockNotif.put("type", "TokenExpired"); - renew.callAfterRenew(mockNotif); - verify(listener, times(1)).trigger(); - } - - @Test(expected = RuntimeException.class) - public void testCallAfterRenewException() throws URISyntaxException, JSONException { - RoomOptions options = new RoomOptions(); - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - WebSocketClient s = mock(WebSocketClient.class); - extended.setSocket(s); - extended.setState(States.CONNECTED); - extended = spy(extended); - RoomExtend renew = new RoomExtend(new Collection(extended, "test", "index"), options); - mockNotif = spy(mockNotif); - doThrow(JSONException.class).when(mockNotif).isNull(any(String.class)); - renew.setListener(listener); - extended.getRequestHistory().put("42", new Date()); - mockNotif.put("error", mock(JSONObject.class)); - renew.callAfterRenew(mockNotif); - // should trigger listener.onError - verify(listener, atLeastOnce()).onError(any(JSONObject.class)); - // Now simulate exception on the onError - doThrow(JSONException.class).when(listener).onError(any(JSONObject.class)); - mockNotif.remove("error"); - renew.callAfterRenew(mockNotif); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/renewTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/renewTest.java deleted file mode 100644 index 3110beaf..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/renewTest.java +++ /dev/null @@ -1,166 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleRoom; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.NotificationResponse; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class renewTest { - @Mock - private ResponseListener listener; - - private JSONObject mockNotif = new JSONObject(); - private JSONObject mockResponse = new JSONObject(); - private Kuzzle k; - private RoomExtend room; - - @Before - public void setUp() throws JSONException { - mockNotif.put("type", "type") - .put("index", "index") - .put("status", 200) - .put("collection", "collection") - .put("controller", "controller") - .put("action", "action") - .put("state", "ALL") - .put("scope", "ALL") - .put("volatile", new JSONObject()) - .put("result", new JSONObject()) - .put("requestId", "42"); - mockResponse.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - k = mock(Kuzzle.class); - when(k.getHeaders()).thenReturn(new JSONObject()); - room = new RoomExtend(new Collection(k, "text", "index")); - - MockitoAnnotations.initMocks(this); - } - - @Test(expected = IllegalArgumentException.class) - public void testRenewIllegalListener() { - room.renew(null, null); - } - - @Test - public void testRenew() throws JSONException, URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - WebSocketClient s = mock(WebSocketClient.class); - KuzzleExtend kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setState(States.CONNECTED); - kuzzle.setSocket(s); - - final Kuzzle kuzzleSpy = spy(kuzzle); - Room testRoom = new Room(new Collection(kuzzleSpy, "collection", "index")); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzleSpy, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "subscribe"); - - return null; - } - }).when(kuzzleSpy).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - testRoom.renew(new JSONObject(), listener, null); - } - - @Test - public void testNoRenewal() throws JSONException, URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - KuzzleExtend kuzzle = new KuzzleExtend("localhost", options, null); - kuzzle.setState(States.CONNECTED); - kuzzle.setSocket(mock(WebSocketClient.class)); - - final Kuzzle kuzzleSpy = spy(kuzzle); - RoomExtend testRoom = new RoomExtend(new Collection(kuzzleSpy, "collection", "index")); - testRoom.setRoomId("foobar"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - verify(kuzzleSpy, times(1)).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - return null; - } - }).when(kuzzleSpy).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - testRoom.renew(listener); - testRoom.renew(listener); - } - - @Test - public void testRenewWhileSubscribing() throws JSONException, URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.setSubscribing(true); - room.renew(listener); - room = spy(room); - room.setSubscribing(false); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject() - .put("channel", "channel") - .put("roomId", "42")); - //Call callback with response - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - verify(room).dequeue(); - - return null; - } - }).when(extended).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - room.renew(listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/unsubscribeTest.java b/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/unsubscribeTest.java deleted file mode 100644 index 3ec4765b..00000000 --- a/test/main/java/io/kuzzle/sdk/core/KuzzleRoom/unsubscribeTest.java +++ /dev/null @@ -1,182 +0,0 @@ -package main.java.io.kuzzle.sdk.core.KuzzleRoom; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.Timer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import main.java.io.kuzzle.sdk.testUtils.RoomExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class unsubscribeTest { - private ResponseListener listener = mock(ResponseListener.class); - private JSONObject mockNotif = new JSONObject(); - private JSONObject mockResponse = new JSONObject(); - private Kuzzle k; - private RoomExtend room; - - @Before - public void setUp() throws JSONException { - mockNotif.put("type", "type") - .put("index", "index") - .put("status", 200) - .put("collection", "collection") - .put("controller", "controller") - .put("action", "action") - .put("state", "ALL") - .put("scope", "ALL") - .put("volatile", new JSONObject()) - .put("result", new JSONObject()) - .put("requestId", "42"); - mockResponse.put("result", new JSONObject().put("channel", "channel").put("roomId", "42")); - k = mock(Kuzzle.class); - when(k.getHeaders()).thenReturn(new JSONObject()); - room = new RoomExtend(new Collection(k, "test", "index")); - } - - @Test - public void testUnsubscribe() throws JSONException, URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - WebSocketClient s = mock(WebSocketClient.class); - - KuzzleExtend kuzzle = new KuzzleExtend("localhost", opts, null); - kuzzle.setState(States.CONNECTED); - kuzzle.setSocket(s); - - kuzzle = spy(kuzzle); - room = new RoomExtend(new Collection(kuzzle, "test", "index")); - room.setRoomId("42"); - room.superUnsubscribe(); - assertEquals(room.getRoomId(), null); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "realtime"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "unsubscribe"); - } - - @Test - public void testUnsubscribeWhileSubscribing() throws JSONException, URISyntaxException, InterruptedException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.setSubscribing(true); - room.superUnsubscribe(); - room = spy(room); - room.setSubscribing(false); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - //Mock response - JSONObject result = new JSONObject(); - result.put("result", new JSONObject() - .put("channel", "channel") - .put("roomId", "42")); - //Call callback with response - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(result); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - } - verify(room).dequeue(); - return null; - } - }).when(extended).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - room.renew(listener); - } - - @Test - public void testUnsubscribeWithPendingSubscriptions() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - WebSocketClient s = mock(WebSocketClient.class); - - KuzzleExtend kuzzle = new KuzzleExtend("localhost", opts, null); - kuzzle.setState(States.CONNECTED); - kuzzle.setSocket(s); - - kuzzle = spy(kuzzle); - kuzzle.getPendingSubscriptions().put("42", mock(Room.class)); - - room = new RoomExtend(new Collection(kuzzle, "test", "index")); - room.setRoomId("42"); - room.superUnsubscribe(); - - assertEquals(room.getRoomId(), null); - verify(kuzzle, never()).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testUnsubscribeException() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - doThrow(JSONException.class).when(extended).removeRoom(any(String.class)); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.superUnsubscribe(); - } - - @Test - public void testUnsubscribeTask() throws URISyntaxException, JSONException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.unsubscribeTask(new Timer(), room.getRoomId(), new JSONObject()).run(); - verify(extended).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testUnsubscribeTaskException() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - extended = spy(extended); - doThrow(JSONException.class).when(extended).getPendingSubscriptions(); - room = new RoomExtend(new Collection(extended, "test", "index")); - room.setRoomId("foobar"); - room.unsubscribeTask(new Timer(), room.getRoomId(), new JSONObject()).run(); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/listeners/KuzzleListenerTest.java b/test/main/java/io/kuzzle/sdk/listeners/KuzzleListenerTest.java deleted file mode 100644 index 6b12c6fd..00000000 --- a/test/main/java/io/kuzzle/sdk/listeners/KuzzleListenerTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package main.java.io.kuzzle.sdk.listeners; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.QueryObject; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class KuzzleListenerTest { - private Kuzzle kuzzle; - private KuzzleExtend kuzzleExtend; - private Kuzzle kuzzleSpy; - private WebSocketClient s = mock(WebSocketClient.class); - private io.kuzzle.sdk.util.Event event; - private io.kuzzle.sdk.util.Event eventSpy; - - @Before - public void setUp() throws URISyntaxException { - Options options = new Options(); - options.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(s); - kuzzle = extended; - kuzzleExtend = extended; - } - - private void mockAnswer(Event e) { - event = new io.kuzzle.sdk.util.Event(e) { - @Override - public void trigger(Object... args) { - - } - }; - eventSpy = spy(event); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - eventSpy.trigger(); - return s; - } - }).when(s).connect(); - } - - @Test - public void testCONNECTEDevent() throws URISyntaxException { - mockAnswer(Event.connected); - kuzzle.addListener(Event.connected, event); - kuzzle.connect(); - verify(eventSpy, times(1)).trigger(); - } - - @Test - public void testERRORevent() throws URISyntaxException { - mockAnswer(Event.error); - kuzzle.addListener(Event.error, event); - kuzzle.connect(); - verify(eventSpy, times(1)).trigger(); - } - - @Test - public void testDISCONNECTevent() throws URISyntaxException { - mockAnswer(Event.disconnected); - kuzzle.addListener(Event.disconnected, event); - kuzzle.connect(); - verify(eventSpy, times(1)).trigger(); - } - - @Test - public void testRECONNECTevent() throws URISyntaxException { - mockAnswer(Event.reconnected); - kuzzle.addListener(Event.reconnected, event); - kuzzle.connect(); - verify(eventSpy, times(1)).trigger(); - } - - @Test - public void testOfflineQueuePush() throws JSONException { - event = new io.kuzzle.sdk.util.Event(Event.offlineQueuePush) { - @Override - public void trigger(Object... args) { - - } - }; - eventSpy = spy(event); - kuzzleExtend.addListener(Event.offlineQueuePush, eventSpy); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.controller = "foo"; - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(QueryObject.class); - verify(eventSpy).trigger(argument.capture()); - assertEquals(((QueryObject) argument.getValue()).getQuery().getString("action"), "bar"); - } - - @Test - public void testOfflineQueuePop() throws JSONException, URISyntaxException { - event = new io.kuzzle.sdk.util.Event(Event.offlineQueuePop) { - @Override - public void trigger(Object... args) { - - } - }; - eventSpy = spy(event); - kuzzleExtend.setAutoReplay(true); - kuzzleExtend.addListener(Event.offlineQueuePop, eventSpy); - mockAnswer(Event.reconnected); - - Options opts = new Options().setQueuable(true); - kuzzleExtend.setState(States.OFFLINE); - kuzzleExtend.startQueuing(); - - Kuzzle.QueryArgs args = new Kuzzle.QueryArgs(); - args.controller = "foo"; - args.action = "bar"; - kuzzleExtend.query(args, new JSONObject(), opts, mock(OnQueryDoneListener.class)); - - kuzzleExtend.connect(); - verify(eventSpy).trigger(); - } -} diff --git a/test/main/java/io/kuzzle/sdk/listeners/KuzzleSubscribeListenerTest.java b/test/main/java/io/kuzzle/sdk/listeners/KuzzleSubscribeListenerTest.java deleted file mode 100644 index b952fbbf..00000000 --- a/test/main/java/io/kuzzle/sdk/listeners/KuzzleSubscribeListenerTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package main.java.io.kuzzle.sdk.listeners; - -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.SubscribeListener; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class KuzzleSubscribeListenerTest { - - private SubscribeListener subListener; - private ResponseListener callback; - private JSONObject json = new JSONObject(); - - @Before - public void setUp() { - subListener = new SubscribeListener(); - callback = spy(new ResponseListener() { - @Override - public void onSuccess(Room response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); - } - - @Test - public void testOnDoneError() { - subListener.onDone(callback); - subListener.done(json, null); - verify(callback).onError(any(JSONObject.class)); - } - - @Test - public void testOnDoneSuccess() { - subListener.onDone(callback); - subListener.done(null, mock(Room.class)); - verify(callback).onSuccess(any(Room.class)); - } - - @Test - public void testPostOnDoneError() { - subListener.done(json, null); - subListener.onDone(callback); - verify(callback).onError(any(JSONObject.class)); - } - - @Test - public void testPostOnDoneSuccess() { - subListener.done(null, mock(Room.class)); - subListener.onDone(callback); - verify(callback).onSuccess(any(Room.class)); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/responses/SearchResultTest.java b/test/main/java/io/kuzzle/sdk/responses/SearchResultTest.java deleted file mode 100644 index 37358ec8..00000000 --- a/test/main/java/io/kuzzle/sdk/responses/SearchResultTest.java +++ /dev/null @@ -1,158 +0,0 @@ -package main.java.io.kuzzle.sdk.responses; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.net.URISyntaxException; -import java.util.ArrayList; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Document; -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.responses.SearchResult; -import io.kuzzle.sdk.state.States; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class SearchResultTest { - private Collection collection; - private Kuzzle kuzzle; - private ResponseListener listener; - private long total; - private ArrayList documents; - private Options options; - private String scrollId; - private String scroll; - - @Before - public void setUp() throws URISyntaxException { - options = new Options(); - options.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", options, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - collection = new Collection(kuzzle, "test", "index"); - listener = mock(ResponseListener.class); - total = (long) 42; - documents = new ArrayList<>(); - scrollId = "someScrollId"; - scroll = "someScroll"; - try { - documents.add(new Document(collection, "foo", new JSONObject().put("name", "John").put("age", 42))); - documents.add(new Document(collection, "bar", new JSONObject().put("name", "Michael").put("age", 36))); - } catch(JSONException e) { - throw new RuntimeException(e); - } - } - - @Test - public void checkConstructorArguments() { - SearchResult searchResult = new SearchResult(collection, total, documents, null, options, null); - assertEquals(searchResult.getCollection(), collection); - assertEquals(searchResult.getTotal(), total); - assertEquals(searchResult.getDocuments(), documents); - assertEquals(searchResult.getAggregations(), null); - assertEquals(searchResult.getOptions(), options); - assertEquals(searchResult.getFilters(), null); - assertEquals(searchResult.getFetchedDocument(), (long) 2); - } - - @Test - public void fetchNextBySearchAfter() throws JSONException { - Options localOptions = new Options(options); - localOptions - .setSize((long) 2); - - JSONObject filters = new JSONObject() - .put("sort", new JSONArray() - .put(new JSONObject() - .put("age", "desc") - ) - .put(new JSONObject() - .put("name", "asc") - ) - ); - - collection = spy(collection); - SearchResult searchResult = new SearchResult(collection, total, documents, null, localOptions, filters); - - searchResult.fetchNext(listener); - - JSONObject expectedFilters = new JSONObject() - .put("search_after", new JSONArray() - .put(36) - .put("Michael") - ) - .put("sort", new JSONArray() - .put(new JSONObject() - .put("age", "desc") - ) - .put(new JSONObject() - .put("name", "asc") - ) - ); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(collection).search((JSONObject) argument.capture(), any(Options.class), eq(listener)); - - assertEquals(argument.getValue().toString(), expectedFilters.toString()); - } - - @Test - public void fetchNextByScroll() throws JSONException { - Options localOptions = new Options(options); - localOptions - .setScroll(scroll) - .setScrollId(scrollId); - - collection = spy(collection); - SearchResult searchResult = new SearchResult(collection, total, documents, null, localOptions, null); - - searchResult.fetchNext(listener); - - verify(collection).scroll(eq(scrollId), any(Options.class), any(JSONObject.class), eq(listener)); - } - - @Test - public void fetchNextBySearch() throws JSONException { - Options localOptions = new Options(options); - localOptions - .setFrom((long) 0) - .setSize((long) 2); - - collection = spy(collection); - SearchResult searchResult = new SearchResult(collection, total, documents, null, localOptions, new JSONObject()); - - searchResult.fetchNext(listener); - - verify(collection).search(any(JSONObject.class), any(Options.class), eq(listener)); - } - - @Test(expected = RuntimeException.class) - public void fetchNextOnError() throws JSONException { - Options localOptions = new Options(options); - - collection = spy(collection); - SearchResult searchResult = new SearchResult(collection, total, documents, null, localOptions, new JSONObject()); - - searchResult.fetchNext(listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleProfileTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleProfileTest.java deleted file mode 100644 index 483f9e07..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleProfileTest.java +++ /dev/null @@ -1,214 +0,0 @@ -package main.java.io.kuzzle.sdk.security; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.security.Security; - -import java.util.Map; - -import static org.junit.Assert.assertFalse; -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class KuzzleProfileTest { - private Kuzzle kuzzle; - private Profile stubProfile; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzle.security = new Security(kuzzle); - stubProfile = new Profile(kuzzle, "foo", null, null); - } - - @Test - public void testConstructorNoContent() throws JSONException { - Profile profile = new Profile(kuzzle, "foo", null, null); - assertEquals(profile.id, "foo"); - assertEquals(profile.getPolicies().length, 0); - assertThat(profile.content, instanceOf(JSONObject.class)); - assertEquals(profile.content.length(), 0); - } - - @Test - public void testConstructorContentWithIDs() throws JSONException { - JSONObject content = new JSONObject( - "{" + - "\"policies\": [{\"roleId\": \"foo\"}, {\"roleId\": \"bar\"}, {\"roleId\": \"baz\"}]" + - "}" - ); - Profile profile = new Profile(kuzzle, "foo", content, null); - assertEquals(profile.id, "foo"); - assertEquals(profile.getPolicies().length, 3); - assertEquals(profile.getPolicies()[2].getString("roleId"), "baz"); - assertThat(profile.content, instanceOf(JSONObject.class)); - assertEquals(profile.content.length(), 0); - } - - @Test - public void testConstructorContentWithRoles() throws JSONException { - JSONObject content = new JSONObject( - "{" + - "\"policies\": [" + - "{\"roleId\": \"foo\"}, " + - "{\"roleId\": \"bar\"}, " + - "{\"roleId\": \"baz\"}" + - "]" + - "}" - ); - Profile profile = new Profile(kuzzle, "foo", content, null); - assertEquals(profile.id, "foo"); - assertEquals(profile.getPolicies().length, 3); - assertEquals(profile.getPolicies()[2].getString("roleId"), "baz"); - assertThat(profile.content, instanceOf(JSONObject.class)); - assertEquals(profile.content.length(), 0); - } - - @Test - public void testConstructorMeta() throws JSONException { - JSONObject meta = new JSONObject() - .put("createdAt", "0123456789") - .put("author", "-1"); - Profile profile = new Profile(kuzzle, "foo", null, meta); - assertEquals(profile.id, "foo"); - assertEquals(profile.getMeta().length(), 2); - assertEquals(profile.getMeta().getString("createdAt"), "0123456789"); - assertEquals(profile.getMeta().getString("author"), "-1"); - assertThat(profile.meta, instanceOf(JSONObject.class)); - } - - @Test - public void testAddPolicyObject() throws JSONException { - stubProfile.addPolicy(new JSONObject().put("roleId", "some role")); - assertEquals(stubProfile.getPolicies().length, 1); - assertEquals(stubProfile.getPolicies()[0].getString("roleId"), "some role"); - } - - @Test(expected = IllegalArgumentException.class) - public void testAddNullPolicyObject() throws JSONException { - stubProfile.addPolicy(new JSONObject().put("roleId", (Object)null)); - doThrow(IllegalArgumentException.class).when(stubProfile).addPolicy(any(JSONObject.class)); - } - - @Test - public void testAddPolicyID() throws JSONException { - stubProfile.addPolicy("another role"); - assertEquals(stubProfile.getPolicies().length, 1); - assertEquals(stubProfile.getPolicies()[0].getString("roleId"), "another role"); - } - - @Test(expected = IllegalArgumentException.class) - public void testSaveNoRole() throws JSONException { - stubProfile.save(); - } - - @Test - public void testSaveNoListener() throws JSONException { - stubProfile.addPolicy("baz"); - stubProfile.save(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceProfile"); - } - - @Test - public void testSave() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubProfile.addPolicy("baz"); - stubProfile.save(new ResponseListener() { - @Override - public void onSuccess(Profile response) { - assertEquals(response, stubProfile); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubProfile.save(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceProfile"); - } - - @Test - public void testSetPoliciesObjectList() throws JSONException { - JSONObject[] policies = new JSONObject[]{ - new JSONObject().put("roleId", "bar"), - new JSONObject().put("roleId", "baz"), - new JSONObject().put("roleId", "qux") - }; - - stubProfile.addPolicy("foo"); - stubProfile.setPolicies(policies); - assertEquals(stubProfile.getPolicies().length, 3); - assertEquals(stubProfile.getPolicies()[0].getString("roleId"), "bar"); - assertEquals(stubProfile.getPolicies()[1].getString("roleId"), "baz"); - assertEquals(stubProfile.getPolicies()[2].getString("roleId"), "qux"); - } - - @Test - public void testSetRolesIDs() throws JSONException { - String[] policies = {"bar", "baz", "qux"}; - - stubProfile.addPolicy("foo"); - assertEquals(stubProfile.getPolicies().length, 1); - - stubProfile.setPolicies(policies); - assertEquals(stubProfile.getPolicies().length, 3); - assertEquals(stubProfile.getPolicies()[0].getString("roleId"), "bar"); - assertEquals(stubProfile.getPolicies()[1].getString("roleId"), "baz"); - assertEquals(stubProfile.getPolicies()[2].getString("roleId"), "qux"); - - stubProfile.addPolicy("foo"); - assertEquals(stubProfile.getPolicies().length, 4); - assertEquals(stubProfile.getPolicies()[3].getString("roleId"), "foo"); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetBadPolicies() throws JSONException { - stubProfile.setPolicies(new JSONObject[]{new JSONObject().put("bad", "policy")}); - - doThrow(IllegalArgumentException.class).when(stubProfile).setPolicies(any(JSONObject[].class)); - } - - @Test - public void testSerializeWithNoPolicies() throws JSONException { - assertFalse(stubProfile.serialize().getJSONObject("body").has("policies")); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleRoleTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleRoleTest.java deleted file mode 100644 index b62dabfa..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleRoleTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package main.java.io.kuzzle.sdk.security; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class KuzzleRoleTest { - private Kuzzle kuzzle; - private Role stubRole; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzle.security = new Security(kuzzle); - stubRole = new Role(kuzzle, "foo", null, null); - } - - @Test - public void testConstructorMeta() throws JSONException { - JSONObject meta = new JSONObject() - .put("createdAt", "0123456789") - .put("author", "-1"); - Role role = new Role(kuzzle, "foo", null, meta); - assertEquals(role.id, "foo"); - assertEquals(role.getMeta().length(), 2); - assertEquals(role.getMeta().getString("createdAt"), "0123456789"); - assertEquals(role.getMeta().getString("author"), "-1"); - assertThat(role.meta, instanceOf(JSONObject.class)); - } - - @Test - public void testSaveNoListener() throws JSONException { - stubRole.save(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceRole"); - } - - @Test - public void testSave() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubRole.save(new ResponseListener() { - @Override - public void onSuccess(Role response) { - assertEquals(response, stubRole); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubRole.save(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceRole"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/AbstractKuzzleSecurityDocumentTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/AbstractKuzzleSecurityDocumentTest.java deleted file mode 100644 index 0671e1d6..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/AbstractKuzzleSecurityDocumentTest.java +++ /dev/null @@ -1,186 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.AbstractSecurityDocument; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class AbstractKuzzleSecurityDocumentTest { - private Kuzzle kuzzle; - private Role stubRole; - private ResponseListener listener; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzle.security = new Security(kuzzle); - listener = mock(ResponseListener.class); - stubRole = new Role(kuzzle, "foo", new JSONObject("{\"foo\":\"bar\"}"), null); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetContentNoContent() throws JSONException { - stubRole.setContent(null); - } - - @Test - public void testSetContent() throws JSONException { - JSONObject content = new JSONObject().put("foo", "bar"); - assertEquals(stubRole.setContent(content), stubRole); - assertThat(stubRole.content, not(equalTo(content))); - assertEquals(stubRole.content.toString(), content.toString()); - } - - @Test - public void testSerialize() throws JSONException { - JSONObject - serialized, - content = new JSONObject().put("bar", "qux"); - - stubRole.setContent(content); - - serialized = stubRole.serialize(); - - assertEquals(serialized.getString("_id"), stubRole.id); - assertEquals(serialized.getJSONObject("body").toString(), content.toString()); - } - - @Test - public void testDeleteNoListener() throws JSONException { - stubRole.delete(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteRole"); - } - - @Test - public void testDelete() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject content = new JSONObject("{\"result\": { \"_id\": \"foo\", \"_source\": {} }}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(content); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubRole.delete(new ResponseListener() { - @Override - public void onSuccess(String response) { - assertEquals(response, "foo"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubRole.delete(); - stubRole.delete(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(2)).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class)); - - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteRole"); - } - - @Test(expected = RuntimeException.class) - public void testDeleteInvalidJSON() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject content = new JSONObject(); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(content); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubRole.delete(listener); - } - - @Test - public void testUpdate() throws JSONException { - JSONObject content = new JSONObject(); - - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject content = new JSONObject("{\"result\": { \"_id\": \"foo\", \"_source\": {} }}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(content); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubRole.update(content, new ResponseListener() { - @Override - public void onSuccess(AbstractSecurityDocument response) { - assertEquals(response.getId(), "foo"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubRole.update(content); - stubRole.update(content, mock(Options.class)); - verify(kuzzle, times(2)).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class)); - verify(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test(expected = RuntimeException.class) - public void testUpdateInvalidJSON() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject content = new JSONObject(); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(content); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubRole.update(new JSONObject(), listener); - } - - @Test - public void testGetContent() throws JSONException { - assertTrue(stubRole.getContent().getString("foo").equals("bar")); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createCredentialsTest.java deleted file mode 100644 index 9c4c4b88..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createCredentialsTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class createCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject credentials = mock(JSONObject.class); - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testCreateCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.createCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testCreateCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.createCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test - public void testCreateCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.createCredentials("strategy", "kuid", credentials) - .createCredentials("strategy", "kuid", credentials, mock(Options.class)) - .createCredentials("strategy", "kuid", credentials, mock(ResponseListener.class)) - .createCredentials("strategy", "kuid", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "createCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createProfileTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createProfileTest.java deleted file mode 100644 index 15b02d6e..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createProfileTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class createProfileTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateProfileNoID() throws JSONException { - kuzzleSecurity.createProfile(null, new JSONObject[0]); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateProfileNoContent() throws JSONException { - kuzzleSecurity.createProfile("foo", null); - } - - @Test - public void testCreateProfileNoListener() throws JSONException { - kuzzleSecurity.createProfile("foo", new JSONObject[0], new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createProfile"); - } - - @Test - public void testCreateProfileReplaceIfExists() throws JSONException { - Options options = new Options().setReplaceIfExist(true); - - kuzzleSecurity.createProfile("foo", new JSONObject[0], options); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceProfile"); - } - - @Test - public void testCreateProfileValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createProfile("foobar", new JSONObject[0], new ResponseListener() { - @Override - public void onSuccess(Profile response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createProfile"); - } - - @Test(expected = RuntimeException.class) - public void testCreateProfileBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createProfile("foobar", new JSONObject[0], listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRestrictedUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRestrictedUserTest.java deleted file mode 100644 index 14723542..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRestrictedUserTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class createRestrictedUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateRestrictedUserNoID() throws JSONException { - kuzzleSecurity.createRestrictedUser(null, new JSONObject()); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateRestrictedWithProfileIds() throws JSONException { - kuzzleSecurity.createRestrictedUser("some_id", new JSONObject().put("profileIds", new JSONArray())); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateRestrictedUserNoContent() throws JSONException { - kuzzleSecurity.createRestrictedUser("foo", null); - } - - @Test - public void testCreateRestrictedUserNoListener() throws JSONException { - kuzzleSecurity.createRestrictedUser("foo", new JSONObject(), new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test - public void testCreateRestrictedUserReplaceIfExists() throws JSONException { - Options options = new Options().setReplaceIfExist(true); - - kuzzleSecurity.createRestrictedUser("foo", new JSONObject(), options); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test - public void testCreateRestrictedUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createRestrictedUser("foobar", new JSONObject(), new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test(expected = RuntimeException.class) - public void testCreateRestrictedUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createRestrictedUser("foobar", new JSONObject(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRoleTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRoleTest.java deleted file mode 100644 index a45c6e91..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createRoleTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class createRoleTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateRoleNoID() throws JSONException { - kuzzleSecurity.createRole(null, new JSONObject()); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateRoleNoContent() throws JSONException { - kuzzleSecurity.createRole("foo", null); - } - - @Test - public void testCreateRoleNoListener() throws JSONException { - kuzzleSecurity.createRole("foo", new JSONObject(), new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createRole"); - } - - @Test - public void testCreateRoleReplaceIfExists() throws JSONException { - Options options = new Options().setReplaceIfExist(true); - - kuzzleSecurity.createRole("foo", new JSONObject(), options); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createOrReplaceRole"); - } - - @Test - public void testCreateRoleValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createRole("foobar", new JSONObject(), new ResponseListener() { - @Override - public void onSuccess(Role response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createRole"); - } - - @Test(expected = RuntimeException.class) - public void testCreateRoleBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createRole("foobar", new JSONObject(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createUserTest.java deleted file mode 100644 index 2388e24a..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/createUserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class createUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateUserNoID() throws JSONException { - kuzzleSecurity.createUser(null, new JSONObject()); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateUserNoContent() throws JSONException { - kuzzleSecurity.createUser("foo", null); - } - - @Test - public void testCreateUserNoListener() throws JSONException { - kuzzleSecurity.createUser("foo", new JSONObject(), new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createUser"); - } - - @Test - public void testCreateUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createUser("foobar", new JSONObject(), new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createUser"); - } - - @Test(expected = RuntimeException.class) - public void testCreateUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.createUser("foobar", new JSONObject(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteCredentialsTest.java deleted file mode 100644 index c15df040..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteCredentialsTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class deleteCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testDeleteCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.deleteCredentials("strategy", "kuid", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testDeleteCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.deleteCredentials("strategy", "kuid", null, listener); - } - - @Test - public void testDeleteCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.deleteCredentials("strategy", "kuid") - .deleteCredentials("strategy", "kuid", mock(Options.class)) - .deleteCredentials("strategy", "kuid", mock(ResponseListener.class)) - .deleteCredentials("strategy", "kuid", mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "deleteCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteProfileTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteProfileTest.java deleted file mode 100644 index 8e45bae6..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteProfileTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class deleteProfileTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test - public void testDeleteProfileNoListener() throws JSONException { - kuzzleSecurity.deleteProfile("foo", new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteProfile"); - } - - @Test - public void testDeleteProfileValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteProfile("foobar", new ResponseListener() { - @Override - public void onSuccess(String response) { - assertEquals(response, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteProfile"); - } - - @Test(expected = RuntimeException.class) - public void testDeleteProfileBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteProfile("foobar", new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testDeleteProfileNoID() throws JSONException { - kuzzleSecurity.deleteProfile(null); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteRoleTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteRoleTest.java deleted file mode 100644 index c7860035..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteRoleTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class deleteRoleTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testDeleteRoleNoID() throws JSONException { - kuzzleSecurity.deleteRole(null); - } - - @Test - public void testDeleteRoleNoListener() throws JSONException { - kuzzleSecurity.deleteRole("foo", new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteRole"); - } - - @Test - public void testDeleteRoleValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteRole("foobar", new ResponseListener() { - @Override - public void onSuccess(String response) { - assertEquals(response, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteRole"); - } - - @Test(expected = RuntimeException.class) - public void testDeleteRoleBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteRole("foobar", new Options(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteUserTest.java deleted file mode 100644 index 62861039..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/deleteUserTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class deleteUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testDeleteUserNoID() throws JSONException { - kuzzleSecurity.deleteUser(null); - } - - @Test - public void testDeleteUserNoListener() throws JSONException { - kuzzleSecurity.deleteUser("foo", new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteUser"); - } - - @Test - public void testDeleteUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteUser("foobar", new ResponseListener() { - @Override - public void onSuccess(String response) { - assertEquals(response, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "deleteUser"); - } - - @Test(expected = RuntimeException.class) - public void testDeleteUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.deleteUser("foobar", new Options(), listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/factoriesTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/factoriesTest.java deleted file mode 100644 index ee6f341c..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/factoriesTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; - -public class factoriesTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test - public void testRoleFactory() throws JSONException { - assertThat(kuzzleSecurity.role("id"), instanceOf(Role.class)); - assertThat(kuzzleSecurity.role("id", new JSONObject()), instanceOf(Role.class)); - } - - @Test - public void testProfileFactory() throws JSONException { - assertThat(kuzzleSecurity.profile("id"), instanceOf(Profile.class)); - assertThat(kuzzleSecurity.profile("id", new JSONObject()), instanceOf(Profile.class)); - } - - @Test - public void testUserFactory() throws JSONException { - assertThat(kuzzleSecurity.user("id"), instanceOf(User.class)); - assertThat(kuzzleSecurity.user("id", new JSONObject()), instanceOf(User.class)); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getAllCredentialFieldsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getAllCredentialFieldsTest.java deleted file mode 100644 index 67a6740f..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getAllCredentialFieldsTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class getAllCredentialFieldsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testNullListener() { - kuzzleSecurity.getAllCredentialFields(null, null); - } - - @Test(expected = RuntimeException.class) - public void testGetAllCredentialsFieldsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getAllCredentialFields(listener); - } - - @Test(expected = RuntimeException.class) - public void testGetAllCredentialsFieldsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getAllCredentialFields(listener); - } - - @Test - public void testGetAllCredentialsFields() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.getAllCredentialFields(listener); - kuzzleSecurity.getAllCredentialFields(mock(Options.class), listener); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getAllCredentialFields"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialFieldsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialFieldsTest.java deleted file mode 100644 index 168566c8..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialFieldsTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class getCredentialFieldsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testGetCredentialsFieldsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getCredentialFields("strategy", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testGetCredentialsFieldsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getCredentialFields("strategy", null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzleSecurity.getCredentialFields("strategy", null, null); - } - - @Test - public void testGetCredentialsFields() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("hits", new JSONArray()))); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.getCredentialFields("strategy", mock(ResponseListener.class)); - kuzzleSecurity.getCredentialFields("strategy", mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getCredentialFields"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialsTest.java deleted file mode 100644 index e5b219b9..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getCredentialsTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class getCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testGetCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getCredentials("strategy", "kuid", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testGetCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getCredentials("strategy", "kuid", null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzleSecurity.getCredentials("strategy", null, null); - } - - @Test - public void testGetCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.getCredentials("strategy", "kuid", mock(ResponseListener.class)); - kuzzleSecurity.getCredentials("strategy", "kuid", mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "getCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getProfileTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getProfileTest.java deleted file mode 100644 index 321f396f..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getProfileTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; - -public class getProfileTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - @Test(expected = IllegalArgumentException.class) - public void testGetProfileNoID() throws JSONException { - kuzzleSecurity.fetchProfile(null, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetProfileNoListener() throws JSONException { - kuzzleSecurity.fetchProfile("foo", null); - } - - @Test(expected = RuntimeException.class) - public void testGetProfileBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchProfile("foobar", listener); - } - - @Test - public void testGetProfileGoodFullResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\":{\"_id\":\"foobar\",\"_source\":{\"policies\":[{\"roleId\":\"baz\",\"restrictedTo\":[{\"index\":\"qux\"}],\"allowInternalIndex\":true}]},\"_meta\":{}}}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchProfile("foobar", listener); - } - - @Test - public void testGetProfileGoodMinimalResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\":{\"_id\":\"foobar\",\"_source\":{\"policies\":[{\"roleId\":\"baz\"}]},\"_meta\":{}}}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchProfile("foobar", listener); - } - - @Test - public void testGetProfileGoodWithRestrictedToResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\":{\"_id\":\"foobar\",\"_source\":{\"policies\":[{\"roleId\":\"baz\"}],\"restrictedTo\":[{\"index\":\"qux\"}]},\"_meta\":{}}}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchProfile("foobar", listener); - } - - @Test - public void testGetProfileGoodWithAllowInternalIndexResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\":{\"_id\":\"foobar\",\"_source\":{\"policies\":[{\"roleId\":\"baz\"}],\"allowInternalIndex\":true},\"_meta\":{}}}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchProfile("foobar", listener); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getRoleTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getRoleTest.java deleted file mode 100644 index c5535d67..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getRoleTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getRoleTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetRoleNoID() { - kuzzleSecurity.fetchRole(null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetRoleNoListener() { - kuzzleSecurity.fetchRole("foobar", null); - } - - @Test - public void testGetRoleValid() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchRole("foobar", null, new ResponseListener() { - @Override - public void onSuccess(Role response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } - catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getRole"); - } - - @Test(expected = RuntimeException.class) - public void testGetRoleInvalid() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.fetchRole("foobar", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testGetRoleInvalidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchRole("foobar", null, listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserRightsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserRightsTest.java deleted file mode 100644 index a7993d7b..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserRightsTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class getUserRightsTest { - - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalUserId() { - kuzzleSecurity.getUserRights(null, mock(ResponseListener.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalCallback() { - kuzzleSecurity.getUserRights("id", null); - } - - @Test(expected = RuntimeException.class) - public void testQueryException() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getUserRights("id", listener); - } - - @Test(expected = RuntimeException.class) - public void testException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getUserRights("id", listener); - } - - @Test - public void testGetUserRights() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject() - .put("result", new JSONObject() - .put("hits", new JSONArray())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.getUserRights("id", mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getUserRights"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserTest.java deleted file mode 100644 index 5697a1aa..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/getUserTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class getUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetUserNoID() throws JSONException { - kuzzleSecurity.fetchUser(null, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetUserNoListener() throws JSONException { - kuzzleSecurity.fetchUser("foo", null); - } - - @Test - public void testGetUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchUser("foobar", new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response.id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "getUser"); - } - - @Test(expected = RuntimeException.class) - public void testGetUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.fetchUser("foobar", listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/hasCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/hasCredentialsTest.java deleted file mode 100644 index eb389f22..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/hasCredentialsTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class hasCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testHasCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.hasCredentials("strategy", "kuid", null, listener); - } - - @Test(expected = RuntimeException.class) - public void testHasCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.hasCredentials("strategy", "kuid", null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzleSecurity.hasCredentials("strategy", null, null); - } - - @Test - public void testHasCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.hasCredentials("strategy", "kuid", mock(ResponseListener.class)); - kuzzleSecurity.hasCredentials("strategy", "kuid", mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "hasCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/isActionAllowedTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/isActionAllowedTest.java deleted file mode 100644 index ffa98ab9..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/isActionAllowedTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.enums.Policies; -import io.kuzzle.sdk.security.Security; - -import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; - -public class isActionAllowedTest { - private Security kuzzleSecurity; - private JSONObject[] policies; - - private JSONObject addProperties(final String ctrl, final String action, final String idx, final String collection, final String value) throws JSONException { - return new JSONObject() - .put("controller", ctrl) - .put("action", action) - .put("index", idx) - .put("collection", collection) - .put("value", value); - } - - @Before - public void setUp() throws JSONException { - Kuzzle kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - policies = new JSONObject[]{ - addProperties("document", "get", "*", "*", Policies.allowed.toString()), - addProperties("document", "count", "*", "*", Policies.allowed.toString()), - addProperties("document", "search", "*", "*", Policies.allowed.toString()), - addProperties("document", "*", "index1", "collection1", Policies.allowed.toString()), - addProperties("document", "*", "index1", "collection2", Policies.allowed.toString()), - addProperties("document", "update", "*", "*", Policies.allowed.toString()), - addProperties("document", "create", "*", "*", Policies.allowed.toString()), - addProperties("document", "createOrReplace", "*", "*", Policies.allowed.toString()), - addProperties("document", "delete", "*", "*", Policies.conditional.toString()), - addProperties("realtime", "publish", "index2", "*", Policies.allowed.toString()), - addProperties("security", "searchUsers", "*", "*", Policies.allowed.toString()), - addProperties("security", "updateUser", "*", "*", Policies.conditional.toString()) - }; - } - - @Test(expected = IllegalArgumentException.class) - public void testNullPolicies() { - kuzzleSecurity.isActionAllowed(null, "ctrl", "action"); - } - - @Test(expected = IllegalArgumentException.class) - public void testNullController() { - kuzzleSecurity.isActionAllowed(policies, null, "action"); - } - - @Test(expected = IllegalArgumentException.class) - public void testNullAction() { - kuzzleSecurity.isActionAllowed(policies, "ctrl", null); - } - - @Test(expected = IllegalArgumentException.class) - public void testEmptyController() { - kuzzleSecurity.isActionAllowed(policies, "", null); - } - - @Test(expected = IllegalArgumentException.class) - public void testEmptyAction() { - kuzzleSecurity.isActionAllowed(policies, "ctrl", ""); - } - - @Test - public void testControllerActionAllowed() { - assertEquals(Policies.allowed, kuzzleSecurity.isActionAllowed(policies, "document", "get")); - } - - @Test - public void testControllerActionIndexAllowed() { - assertEquals(Policies.allowed, kuzzleSecurity.isActionAllowed(policies, "document", "count", "myIndex")); - } - - @Test - public void testControllerActionIndexCollectionAllowed() { - assertEquals(Policies.allowed, kuzzleSecurity.isActionAllowed(policies, "document", "search", "index1", "collection1")); - } - - @Test - public void testControllerActionIndexCollection2Allowed() { - assertEquals(Policies.allowed, kuzzleSecurity.isActionAllowed(policies, "document", "search", "index1", "collection2")); - } - - @Test - public void testControllerActionDenied() { - assertEquals(Policies.denied, kuzzleSecurity.isActionAllowed(policies, "document", "replace")); - } - - @Test - public void testControllerActionIndexDenied() { - assertEquals(Policies.denied, kuzzleSecurity.isActionAllowed(policies, "index", "list", "index2")); - } - - @Test - public void testControllerActionConditional() { - assertEquals(Policies.conditional, kuzzleSecurity.isActionAllowed(policies, "security", "updateUser")); - } - - @Test - public void testControllerActionIndexCollectionConditional() { - assertEquals(Policies.conditional, kuzzleSecurity.isActionAllowed(policies, "document", "delete", "index2", "collection1")); - } - - @Test(expected = RuntimeException.class) - public void testJsonException() throws JSONException { - JSONObject spy = spy(policies[0]); - doThrow(JSONException.class).when(spy.getString(any(String.class))); - kuzzleSecurity.isActionAllowed(policies, "document", "delete", "index1", "collection1"); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/replaceUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/replaceUserTest.java deleted file mode 100644 index 956fbf19..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/replaceUserTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class replaceUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject content; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - content = new JSONObject() - .put("foo", "bar"); - } - - @Test - public void testReplaceUserNoListener() throws JSONException { - kuzzleSecurity.replaceUser("foo", content, new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "replaceUser"); - } - - @Test - public void testReplaceUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foo\"," + - "\"_source\": {}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.replaceUser("foo", content, new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response.getId(), "foo"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "replaceUser"); - } - - @Test(expected = RuntimeException.class) - public void testReplaceUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.replaceUser("foo", content, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testReplaceUserNoID() throws JSONException { - kuzzleSecurity.replaceUser(null, content); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollProfilesTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollProfilesTest.java deleted file mode 100644 index 91d35b76..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollProfilesTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.Scroll; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class scrollProfilesTest { - private Kuzzle kuzzle; - private Security security; - private ResponseListener listener; - private Options options; - private Scroll scroll; - private String scrollId; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - security = new Security(kuzzle); - listener = mock(ResponseListener.class); - options = mock(Options.class); - scroll = new Scroll(); - scrollId = "f00ba5"; - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollProfilesNoScrollId() throws JSONException { - security.scrollProfiles(scroll, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollProfilesIllegalListener() throws JSONException { - scroll.setScrollId(scrollId); - security.scrollProfiles(scroll, null); - } - - @Test - public void checkSignaturesVariants() throws JSONException { - security = spy(security); - scroll.setScrollId(scrollId); - - security.scrollProfiles(scroll, listener); - verify(security).scrollProfiles(eq(scroll), eq(listener)); - - security.scrollProfiles(scroll, options, listener); - verify(security).scrollProfiles(eq(scroll), eq(options), eq(listener)); - } - - @Test(expected = RuntimeException.class) - public void testScrollProfilesQueryException() throws JSONException { - scroll.setScrollId(scrollId); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - security.scrollProfiles(scroll, listener); - } - - @Test(expected = RuntimeException.class) - public void testScrollProfilesException() throws JSONException { - scroll.setScrollId(scrollId); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - security.scrollProfiles(scroll, listener); - } - - @Test - public void testScrollProfiles() throws JSONException { - scroll.setScrollId("f00ba5"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"_shards\": {\n" + - " \"failed\": 0,\n" + - " \"successful\": 5,\n" + - " \"total\": 5\n" + - " },\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"AVJAwyDMZAGQHg9Dhfw2\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073821,\n" + - " \"lon\": 3.9130721\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"customer\"\n" + - " },\n" + - " \"_meta\": {},\n" + - " \"_type\": \"users\"\n" + - " },\n" + - " {\n" + - " \"_id\": \"AVJAwyOvZAGQHg9Dhfw3\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073683,\n" + - " \"lon\": 3.8999983\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"cab\"\n" + - " },\n" + - " \"_meta\": {},\n" + - " \"_type\": \"users\"\n" + - " }\n" + - " ],\n" + - " \"max_score\": 1,\n" + - " \"timed_out\": false,\n" + - " \"took\": 307,\n" + - " \"total\": 2\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - security.scrollProfiles(scroll, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList result) { - assertEquals(result.getTotal(), 2); - assertEquals(result.getDocuments().get(1).getId(), "AVJAwyOvZAGQHg9Dhfw3"); - } - - @Override - public void onError(JSONObject error) { - } - }); - security.scrollProfiles(scroll, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "scrollProfiles"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollUsersTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollUsersTest.java deleted file mode 100644 index bd368056..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/scrollUsersTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.enums.Mode; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.Scroll; -import main.java.io.kuzzle.sdk.testUtils.KuzzleExtend; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class scrollUsersTest { - private Kuzzle kuzzle; - private Security security; - private ResponseListener listener; - private Options options; - private Scroll scroll; - private String scrollId; - - @Before - public void setUp() throws URISyntaxException { - Options opts = new Options(); - opts.setConnect(Mode.MANUAL); - KuzzleExtend extended = new KuzzleExtend("localhost", opts, null); - extended.setSocket(mock(WebSocketClient.class)); - extended.setState(States.CONNECTED); - kuzzle = spy(extended); - when(kuzzle.getHeaders()).thenReturn(new JSONObject()); - - security = new Security(kuzzle); - listener = mock(ResponseListener.class); - options = mock(Options.class); - scroll = new Scroll(); - scrollId = "f00ba5"; - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollUsersNoScrollId() throws JSONException { - security.scrollUsers(scroll, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testScrollUsersIllegalListener() throws JSONException { - scroll.setScrollId(scrollId); - security.scrollUsers(scroll, null); - } - - @Test - public void checkSignaturesVariants() throws JSONException { - security = spy(security); - scroll.setScrollId(scrollId); - - security.scrollUsers(scroll, listener); - verify(security).scrollUsers(eq(scroll), eq(listener)); - - security.scrollUsers(scroll, options, listener); - verify(security).scrollUsers(eq(scroll), eq(options), eq(listener)); - } - - @Test(expected = RuntimeException.class) - public void testScrollUsersQueryException() throws JSONException { - scroll.setScrollId(scrollId); - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - security.scrollUsers(scroll, listener); - } - - @Test(expected = RuntimeException.class) - public void testScrollUsersException() throws JSONException { - scroll.setScrollId(scrollId); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject().put("count", 42))); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - doThrow(JSONException.class).when(listener).onSuccess(any(Integer.class)); - security.scrollUsers(scroll, listener); - } - - @Test - public void testScrollUsers() throws JSONException { - scroll.setScrollId("f00ba5"); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject("{\"result\": {\n" + - " \"_shards\": {\n" + - " \"failed\": 0,\n" + - " \"successful\": 5,\n" + - " \"total\": 5\n" + - " },\n" + - " \"hits\": [\n" + - " {\n" + - " \"_id\": \"AVJAwyDMZAGQHg9Dhfw2\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073821,\n" + - " \"lon\": 3.9130721\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"customer\"\n" + - " },\n" + - " \"_meta\": {},\n" + - " \"_type\": \"users\"\n" + - " },\n" + - " {\n" + - " \"_id\": \"AVJAwyOvZAGQHg9Dhfw3\",\n" + - " \"_index\": \"cabble\",\n" + - " \"_score\": 1,\n" + - " \"_source\": {\n" + - " \"pos\": {\n" + - " \"lat\": 43.6073683,\n" + - " \"lon\": 3.8999983\n" + - " },\n" + - " \"sibling\": \"none\",\n" + - " \"status\": \"idle\",\n" + - " \"type\": \"cab\"\n" + - " },\n" + - " \"_meta\": {},\n" + - " \"_type\": \"users\"\n" + - " }\n" + - " ],\n" + - " \"max_score\": 1,\n" + - " \"timed_out\": false,\n" + - " \"took\": 307,\n" + - " \"total\": 2\n" + - " }" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject()); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - security.scrollUsers(scroll, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList result) { - assertEquals(result.getTotal(), 2); - assertEquals(result.getDocuments().get(1).getId(), "AVJAwyOvZAGQHg9Dhfw3"); - } - - @Override - public void onError(JSONObject error) { - } - }); - security.scrollUsers(scroll, mock(ResponseListener.class)); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "scrollUsers"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchProfilesTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchProfilesTest.java deleted file mode 100644 index 277689c6..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchProfilesTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class searchProfilesTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchProfilesNoFilters() throws JSONException { - kuzzleSecurity.searchProfiles(null, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchProfilesNoListener() throws JSONException { - kuzzleSecurity.searchProfiles(new JSONObject(), null); - } - - @Test - public void testSearchProfilesValid() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"hits\": [" + - "{" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"_id\": \"foobar\"," + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "]," + - "\"total\": 1" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchProfiles(new JSONObject(), null, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList response) { - assertEquals(response.getTotal(), 1); - assertEquals(response.getDocuments().get(0).id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "searchProfiles"); - } - - @Test(expected = RuntimeException.class) - public void testSearchProfilesBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchProfiles(new JSONObject(), null, listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchRolesTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchRolesTest.java deleted file mode 100644 index 3f48f745..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchRolesTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class searchRolesTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchRolesNoFilters() throws JSONException { - kuzzleSecurity.searchRoles(null, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchRolesNoListener() throws JSONException { - kuzzleSecurity.searchRoles(new JSONObject(), null); - } - - @Test - public void testSearchRolesValid() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"hits\": [" + - "{" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"_id\": \"foobar\"," + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "]," + - "\"total\": 1" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchRoles(new JSONObject(), null, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList response) { - assertEquals(response.getTotal(), 1); - assertEquals(response.getDocuments().get(0).id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "searchRoles"); - } - - @Test(expected = RuntimeException.class) - public void testSearchRolesBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchRoles(new JSONObject(), null, listener); - } - -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchUsersTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchUsersTest.java deleted file mode 100644 index 99609707..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/searchUsersTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.responses.SecurityDocumentList; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class searchUsersTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchUsersNoFilters() throws JSONException { - kuzzleSecurity.searchUsers(null, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testSearchUsersNoListener() throws JSONException { - kuzzleSecurity.searchUsers(new JSONObject(), null); - } - - @Test - public void testSearchUsersValid() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"hits\": [" + - "{" + - "\"_id\": \"foobar\"," + - "\"_source\": {" + - "\"_id\": \"foobar\"," + - "\"indexes\": {}" + - "}," + - "\"_meta\": {}" + - "}" + - "]," + - "\"total\": 1" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchUsers(new JSONObject(), null, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList response) { - assertEquals(response.getTotal(), 1); - assertEquals(response.getDocuments().get(0).id, "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "searchUsers"); - } - - @Test(expected = RuntimeException.class) - public void testSearchUsersBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.searchUsers(new JSONObject(), null, listener); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateCredentialsTest.java deleted file mode 100644 index cabb6990..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateCredentialsTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class updateCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject credentials = mock(JSONObject.class); - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testUpdateCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.updateCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testUpdateCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.updateCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test - public void testUpdateCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", new JSONObject())); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.updateCredentials("strategy", "kuid", credentials) - .updateCredentials("strategy", "kuid", credentials, mock(Options.class)) - .updateCredentials("strategy", "kuid", credentials, mock(ResponseListener.class)) - .updateCredentials("strategy", "kuid", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(4)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateProfileTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateProfileTest.java deleted file mode 100644 index 15383022..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateProfileTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class updateProfileTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject[] policies; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - policies = new JSONObject[]{new JSONObject().put("foo", "bar")}; - } - - @Test - public void testUpdateProfileNoListener() throws JSONException { - kuzzleSecurity.updateProfile("foo", policies, new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateProfile"); - } - - @Test - public void testUpdateProfileValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateProfile("foobar", policies, new ResponseListener() { - @Override - public void onSuccess(Profile response) { - assertEquals(response.getId(), "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateProfile"); - } - - @Test(expected = RuntimeException.class) - public void testUpdateProfileBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateProfile("foobar", policies, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdateProfileNoID() throws JSONException { - kuzzleSecurity.updateProfile(null, policies); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateRoleTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateRoleTest.java deleted file mode 100644 index 964def24..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateRoleTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Role; -import io.kuzzle.sdk.security.Security; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class updateRoleTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject content; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - content = new JSONObject() - .put("foo", "bar"); - } - - @Test - public void testUpdateRoleNoListener() throws JSONException { - kuzzleSecurity.updateRole("foo", content, new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateRole"); - } - - @Test - public void testUpdateRoleValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateRole("foobar", content, new ResponseListener() { - @Override - public void onSuccess(Role role) { - assertEquals(role.getId(), "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateRole"); - } - - @Test(expected = RuntimeException.class) - public void testUpdateRoleBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateRole("foobar", content, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdateRoleNoID() throws JSONException { - kuzzleSecurity.updateRole(null, content); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateUserTest.java deleted file mode 100644 index 634f6337..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/updateUserTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class updateUserTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject content; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - listener = mock(ResponseListener.class); - content = new JSONObject() - .put("foo", "bar"); - } - - @Test - public void testUpdateUserNoListener() throws JSONException { - kuzzleSecurity.updateUser("foo", content, new Options()); - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateUser"); - } - - @Test - public void testUpdateUserValidResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject( - "{" + - "\"result\": {" + - "\"_id\": \"foobar\"," + - "\"_source\": {}," + - "\"_meta\": {}" + - "}" + - "}"); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateUser("foobar", content, new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response.getId(), "foobar"); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "updateUser"); - } - - @Test(expected = RuntimeException.class) - public void testUpdateUserBadResponse() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - JSONObject response = new JSONObject(); - - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(response); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - kuzzleSecurity.updateUser("foobar", content, new Options(), listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdateUserNoID() throws JSONException { - kuzzleSecurity.updateUser(null, content); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/validateCredentialsTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/validateCredentialsTest.java deleted file mode 100644 index bf814c3d..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleSecurity/validateCredentialsTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package main.java.io.kuzzle.sdk.security.KuzzleSecurity; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.security.Security; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class validateCredentialsTest { - private Kuzzle kuzzle; - private Security kuzzleSecurity; - private ResponseListener listener; - private JSONObject credentials; - - @Before - public void setUp() { - kuzzle = mock(Kuzzle.class); - kuzzleSecurity = new Security(kuzzle); - credentials = mock(JSONObject.class); - listener = new ResponseListener() { - @Override - public void onSuccess(Object response) { - - } - - @Override - public void onError(JSONObject error) { - - } - }; - } - - @Test(expected = RuntimeException.class) - public void testValidateCredentialsException() throws JSONException { - listener = spy(listener); - doThrow(JSONException.class).when(listener).onSuccess(any(JSONObject.class)); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(mock(JSONObject.class)); - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.validateCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test(expected = RuntimeException.class) - public void testValidateCredentialsQueryException() throws JSONException { - doThrow(JSONException.class).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - kuzzleSecurity.validateCredentials("strategy", "kuid", credentials, null, listener); - } - - @Test(expected = IllegalArgumentException.class) - public void testListenerNull() { - kuzzleSecurity.validateCredentials("strategy", "kuid", credentials, null, null); - } - - @Test - public void testValidateCredentials() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (invocation.getArguments()[3] != null) { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject().put("result", true)); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - } - return null; - } - }).when(kuzzle).query(any(Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Kuzzle.QueryArgs.class); - - kuzzleSecurity.validateCredentials("strategy", "kuid", credentials, mock(ResponseListener.class)); - kuzzleSecurity.validateCredentials("strategy", "kuid", credentials, mock(Options.class), mock(ResponseListener.class)); - - verify(kuzzle, times(2)).query((Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((Kuzzle.QueryArgs) argument.getValue()).action, "validateCredentials"); - } -} diff --git a/test/main/java/io/kuzzle/sdk/security/KuzzleUserTest.java b/test/main/java/io/kuzzle/sdk/security/KuzzleUserTest.java deleted file mode 100644 index bfb18f23..00000000 --- a/test/main/java/io/kuzzle/sdk/security/KuzzleUserTest.java +++ /dev/null @@ -1,408 +0,0 @@ -package main.java.io.kuzzle.sdk.security; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.security.Profile; -import io.kuzzle.sdk.security.Security; -import io.kuzzle.sdk.security.User; - -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class KuzzleUserTest { - private Kuzzle kuzzle; - private User stubUser; - - @Before - public void setUp() throws JSONException { - kuzzle = mock(Kuzzle.class); - kuzzle.security = new Security(kuzzle); - stubUser = new User(kuzzle, "foo", null, null); - } - - @Test - public void testKuzzleUserConstructorNoContent() throws JSONException { - User user = new User(kuzzle, "foo", null, null); - assertEquals(user.id, "foo"); - assertEquals(user.getProfileIds().length, 0); - assertThat(user.content, instanceOf(JSONObject.class)); - } - - @Test - public void testKuzzleUserConstructorWithEmptyProfile() throws JSONException { - JSONObject stubProfile = new JSONObject( - "{" + - "\"profileIds\": [\"bar\"]," + - "\"someuseless\": \"field\"" + - "}" - ); - User user = new User(kuzzle, "foo", stubProfile, null); - assertEquals(user.id, "foo"); - assertEquals(user.getProfileIds()[0], "bar"); - assertThat(user.content, instanceOf(JSONObject.class)); - assertEquals(user.content.getString("someuseless"), "field"); - } - - @Test - public void testKuzzleUserConstructorProfileWithContent() throws JSONException { - JSONObject stubProfile = new JSONObject("{\"profileIds\": [\"bar\"]}"); - User user = new User(kuzzle, "foo", stubProfile, null); - assertEquals(user.id, "foo"); - assertThat(user.getProfileIds(), instanceOf(String[].class)); - assertEquals(user.getProfileIds()[0], "bar"); - assertThat(user.content, instanceOf(JSONObject.class)); - } - - @Test - public void testKuzzleUserConstructorMeta() throws JSONException { - JSONObject meta = new JSONObject() - .put("createdAt", "0123456789") - .put("author", "-1"); - User user = new User(kuzzle, "foo", null, meta); - assertEquals(user.id, "foo"); - assertEquals(user.getMeta().length(), 2); - assertEquals(user.getMeta().getString("createdAt"), "0123456789"); - assertEquals(user.getMeta().getString("author"), "-1"); - assertThat(user.meta, instanceOf(JSONObject.class)); - } - - @Test - public void testSetProfileWithKuzzleProfile() throws JSONException { - String[] ids = new String[1]; - ids[0] = "foo"; - stubUser.setProfiles(ids); - assertEquals(stubUser.getProfileIds()[0], "foo"); - } - - @Test(expected = IllegalArgumentException.class) - public void testSetProfileNullID() throws JSONException { - String[] ids = null; - stubUser.setProfiles(ids); - doThrow(IllegalArgumentException.class).when(stubUser).setProfiles(any(String[].class)); - } - - @Test - public void testReplaceNoListener() throws JSONException { - stubUser.replace(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "replaceUser"); - } - - @Test - public void testReplace() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubUser.replace(new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response, stubUser); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubUser.replace(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "replaceUser"); - } - - @Test - public void testCreateNoListener() throws JSONException { - stubUser.create(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createUser"); - } - - @Test - public void testCreate() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubUser.create(new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response, stubUser); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubUser.create(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createUser"); - } - - @Test - public void testSaveRestrictedNoListener() throws JSONException { - stubUser.saveRestricted(); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test - public void testSaveRestrictedNoListenerAndOptions() throws JSONException { - Options options = new Options(); - stubUser.saveRestricted(options); - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test - public void testSaveRestricted() throws JSONException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onSuccess(new JSONObject()); - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(new JSONObject().put("error", "stub")); - return null; - } - }).when(kuzzle).query(any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - - stubUser.saveRestricted(new ResponseListener() { - @Override - public void onSuccess(User response) { - assertEquals(response, stubUser); - } - - @Override - public void onError(JSONObject error) { - try { - assertEquals(error.getString("error"), "stub"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - }); - stubUser.saveRestricted(mock(Options.class)); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - verify(kuzzle, times(1)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class)); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).controller, "security"); - assertEquals(((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.getValue()).action, "createRestrictedUser"); - } - - @Test - public void testSerializeNoProfile() throws JSONException { - stubUser.content.put("foo", "bar"); - JSONObject serialized = stubUser.serialize(); - assertEquals(serialized.getString("_id"), stubUser.id); - assertEquals(serialized.getJSONObject("body").toString(), stubUser.content.toString()); - assertEquals(serialized.has("profile"), false); - } - - @Test - public void testSerializeWithProfile() throws JSONException { - stubUser.content.put("foo", "bar"); - stubUser.setProfiles(new String[]{"profile"}); - JSONObject serialized = stubUser.serialize(); - assertEquals(serialized.getString("_id"), stubUser.id); - assertEquals(serialized.getJSONObject("body").getString("foo"), "bar"); - assertEquals(serialized.getJSONObject("body").getJSONArray("profileIds").getString(0), stubUser.getProfileIds()[0]); - } - - @Test - public void testGetProfileIds() throws JSONException { - JSONObject stubProfile = new JSONObject( - "{\"profileIds\": [\"bar\"]}" - ); - User user = new User(kuzzle, "foo", stubProfile, null); - assertEquals(user.getProfileIds()[0], "bar"); - } - - @Test - public void testAddProfile() throws JSONException { - JSONObject stubProfile = new JSONObject( - "{\"profileIds\": [\"bar\"]}" - ); - User user = new User(kuzzle, "foo", stubProfile, null); - user.addProfile("new profile"); - assertEquals(user.getProfileIds()[1], "new profile"); - } - - @Test(expected = IllegalArgumentException.class) - public void testAddNullProfile() throws JSONException { - JSONObject stubProfile = new JSONObject( - "{\"profileIds\": [\"bar\"]}" - ); - User user = new User(kuzzle, "foo", stubProfile, null); - user.addProfile(null); - doThrow(IllegalArgumentException.class).when(user).addProfile(eq((String)null)); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetProfilesException() throws JSONException { - User user = new User(kuzzle, "foo", new JSONObject(), null); - user.getProfiles(null); - } - - @Test - public void testGetProfilesEmpty() throws JSONException { - User user = new User(kuzzle, "foo", new JSONObject(), null); - - user.getProfiles(new ResponseListener() { - @Override - public void onSuccess(Profile[] response) { - assertEquals(response.length, 0); - } - - @Override - public void onError(JSONObject error) { - fail("onError callback should not have been invoked"); - } - }); - } - - @Test - public void testGetProfiles() throws JSONException { - JSONArray profiles = new JSONArray().put("foo").put("bar").put("baz"); - User user = new User(kuzzle, "foo", new JSONObject().put("profileIds", profiles), null); - - Answer mockAnswer = new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation - .getArguments()[3]) - .onSuccess(new JSONObject() - .put("result", new JSONObject() - .put("_id", "foobar") - .put("_source", new JSONObject() - .put("policies", new JSONArray()) - ) - .put("_meta", new JSONObject()) - ) - ); - return null; - } - }; - - doAnswer(mockAnswer) - .when(kuzzle) - .query( - any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), - any(JSONObject.class), - any(Options.class), - any(OnQueryDoneListener.class) - ); - - user.getProfiles(new ResponseListener() { - @Override - public void onSuccess(Profile[] response) { - assertEquals(response.length, 3); - } - - @Override - public void onError(JSONObject error) { - fail("onError should not have been invoked"); - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } - - @Test - public void testGetProfilesError() throws JSONException { - JSONArray profiles = new JSONArray().put("foo").put("bar").put("baz"); - User user = new User(kuzzle, "foo", new JSONObject().put("profileIds", profiles), null); - final boolean[] invoked = {false}; - - Answer mockAnswer = new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((OnQueryDoneListener) invocation.getArguments()[3]).onError(mock(JSONObject.class)); - return null; - } - }; - - doAnswer(mockAnswer) - .when(kuzzle) - .query( - any(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class), - any(JSONObject.class), - any(Options.class), - any(OnQueryDoneListener.class) - ); - - user.getProfiles(new ResponseListener() { - @Override - public void onSuccess(Profile[] response) { - fail("onSuccess should not have been invoked"); - } - - @Override - public void onError(JSONObject error) { - if (invoked[0] == true) { - fail("onError invoked more than once"); - return; - } - - invoked[0] = true; - } - }); - - ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class); - verify(kuzzle, times(3)).query((io.kuzzle.sdk.core.Kuzzle.QueryArgs) argument.capture(), any(JSONObject.class), any(Options.class), any(OnQueryDoneListener.class)); - } -} diff --git a/test/main/java/io/kuzzle/sdk/testUtils/KuzzleDataCollectionExtend.java b/test/main/java/io/kuzzle/sdk/testUtils/KuzzleDataCollectionExtend.java deleted file mode 100644 index f4ed77c5..00000000 --- a/test/main/java/io/kuzzle/sdk/testUtils/KuzzleDataCollectionExtend.java +++ /dev/null @@ -1,18 +0,0 @@ -package main.java.io.kuzzle.sdk.testUtils; - -import org.json.JSONObject; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.listeners.ResponseListener; - -public class KuzzleDataCollectionExtend extends Collection { - public KuzzleDataCollectionExtend(final Kuzzle kuzzle, final String index, final String collection) { - super(kuzzle, collection, index); - } - - public Collection deleteDocument(final String documentId, final JSONObject filter, final Options options, final ResponseListener listener, final ResponseListener listener2) { - return super.deleteDocument(documentId, filter, options, listener, listener2); - } -} diff --git a/test/main/java/io/kuzzle/sdk/testUtils/KuzzleExtend.java b/test/main/java/io/kuzzle/sdk/testUtils/KuzzleExtend.java deleted file mode 100644 index f1ce41f6..00000000 --- a/test/main/java/io/kuzzle/sdk/testUtils/KuzzleExtend.java +++ /dev/null @@ -1,131 +0,0 @@ -package main.java.io.kuzzle.sdk.testUtils; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.URISyntaxException; -import java.util.Date; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.enums.Event; -import io.kuzzle.sdk.listeners.ResponseListener; -import io.kuzzle.sdk.listeners.OnQueryDoneListener; -import io.kuzzle.sdk.state.States; -import io.kuzzle.sdk.util.EventList; -import tech.gusavila92.websocketclient.WebSocketClient; - -import static org.mockito.Mockito.spy; - -public class KuzzleExtend extends Kuzzle { - protected WebSocketClient savedSocket = null; - - public ResponseListener loginCallback; - - public KuzzleExtend(final String host, final Options options, final ResponseListener connectionCallback) throws URISyntaxException { - super(host, options, connectionCallback); - } - - public void setState(States newState) { - this.state = newState; - } - - public void setSocket(WebSocketClient s) { - this.socket = this.savedSocket = s; - } - - public void setListener(ResponseListener listener) { - this.connectionCallback = listener; - } - - - public Kuzzle deleteSubscription(final String roomId, final String id) { - return super.deleteSubscription(roomId, id); - } - - - protected WebSocketClient createSocket() throws URISyntaxException { - return this.savedSocket != null ? this.savedSocket : super.createSocket(); - } - - /** - * * Returns all registered listeners on a given event - * - * @param event - */ - public EventList getEventListeners(Event event) { - return this.eventListeners.get(event); - } - - /** - * Get the subscription object from a Kuzzle instance - * - * @return - */ - public Map> getSubscriptions() { - return this.subscriptions; - } - - /** - * Gets the internal socket instance from the kuzzle object - * @return - */ - public WebSocketClient getSocket() { - return this.socket; - } - - public void isValid() { - super.isValid(); - } - - public void emitRequest(final JSONObject request, final OnQueryDoneListener listener) throws JSONException { - super.emitRequest(request, listener); - } - - public Kuzzle deletePendingSubscription(final String id) { - return super.deletePendingSubscription(id); - } - - public Map getRequestHistory() { - return super.getRequestHistory(); - } - - public Map getPendingSubscriptions() { - return super.getPendingSubscriptions(); - } - - public boolean isValidState() { - return super.isValidState(); - } - - public ResponseListener spyAndGetConnectionCallback() { - super.connectionCallback = spy(super.connectionCallback); - return super.connectionCallback; - } - - public void setSuperDefaultIndex(final String index) { - super.defaultIndex = index; - } - - public void emitEvent(final Event event, final Object... args) { - super.emitEvent(event, args); - } - - public void renewSubscriptions() { - super.renewSubscriptions(); - } - - public void setJwtTokenWithoutSubscribe(final String token) { - super.jwtToken = token; - } - - public Kuzzle removeRoom(String channel) { - super.removeRoom(channel); - - return this; - } - -} diff --git a/test/main/java/io/kuzzle/sdk/testUtils/QueryArgsHelper.java b/test/main/java/io/kuzzle/sdk/testUtils/QueryArgsHelper.java deleted file mode 100644 index 45aea3dd..00000000 --- a/test/main/java/io/kuzzle/sdk/testUtils/QueryArgsHelper.java +++ /dev/null @@ -1,10 +0,0 @@ -package main.java.io.kuzzle.sdk.testUtils; - -public class QueryArgsHelper { - public static io.kuzzle.sdk.core.Kuzzle.QueryArgs makeQueryArgs(final String controller, final String action) { - io.kuzzle.sdk.core.Kuzzle.QueryArgs args = new io.kuzzle.sdk.core.Kuzzle.QueryArgs(); - args.controller = controller; - args.action = action; - return args; - } -} diff --git a/test/main/java/io/kuzzle/sdk/testUtils/RoomExtend.java b/test/main/java/io/kuzzle/sdk/testUtils/RoomExtend.java deleted file mode 100644 index 593c62ef..00000000 --- a/test/main/java/io/kuzzle/sdk/testUtils/RoomExtend.java +++ /dev/null @@ -1,62 +0,0 @@ -package main.java.io.kuzzle.sdk.testUtils; - -import org.json.JSONObject; - -import java.util.Timer; -import java.util.TimerTask; - -import io.kuzzle.sdk.core.Collection; -import io.kuzzle.sdk.core.Room; -import io.kuzzle.sdk.core.RoomOptions; -import io.kuzzle.sdk.listeners.ResponseListener; - -public class RoomExtend extends Room { - - public RoomExtend(Collection kuzzleDataCollection) { - super(kuzzleDataCollection); - } - - public RoomExtend(Collection kuzzleDataCollection, RoomOptions options) { - super(kuzzleDataCollection, options); - } - - public void callAfterRenew(Object args) { - super.callAfterRenew(args); - } - - public void setListener(final ResponseListener listener) { - this.listener = listener; - } - - public void setRoomId(final String id) { - this.roomId = id; - } - - public void setSubscribing(final boolean isSubscribing) { - super.subscribing = isSubscribing; - } - - public void dequeue() { - super.dequeue(); - } - - @Override - public Room unsubscribe() { - // do nothing - return this; - } - - public Room superUnsubscribe() { - return super.unsubscribe(); - } - - public TimerTask unsubscribeTask(final Timer timer, final String roomId, final JSONObject data) { - return super.unsubscribeTask(timer, roomId, data); - } - - public Room makeHeadersNull() { - super.headers = null; - return this; - } - -} From 3fcef0babc1847a6896276c35396490e53e93c9b Mon Sep 17 00:00:00 2001 From: ycombes Date: Mon, 19 Aug 2019 13:17:54 +0200 Subject: [PATCH 002/134] Base structure --- src/main/java/io/kuzzle/sdk/Kuzzle.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/io/kuzzle/sdk/Kuzzle.java diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java new file mode 100644 index 00000000..4b4eb234 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -0,0 +1,5 @@ +package io.kuzzle.sdk; + +public class Kuzzle { + +} From de7e674b83f6387255f2874b0379161b60cffd39 Mon Sep 17 00:00:00 2001 From: ycombes Date: Fri, 23 Aug 2019 10:54:39 +0200 Subject: [PATCH 003/134] Remove old documentation --- doc/2/.vuepress | 1 - .../collection-mapping/apply/index.md | 43 ------- .../apply/snippets/apply-1.java | 12 -- .../collection-mapping/constructor/index.md | 42 ------ .../constructor/snippets/constructor-1.java | 9 -- .../core-classes/collection-mapping/index.md | 6 - .../collection-mapping/refresh/index.md | 37 ------ .../refresh/snippets/refresh-1.java | 12 -- .../collection-mapping/set-headers/index.md | 31 ----- .../set-headers/snippets/set-headers-1.java | 4 - .../collection-mapping/set/index.md | 33 ----- .../set/snippets/set-1.java | 7 - .../collection/collection-mapping/index.md | 28 ---- .../snippets/collection-mapping-1.java | 15 --- .../collection/constructor/index.md | 42 ------ .../constructor/snippets/constructor-1.java | 2 - doc/2/core-classes/collection/count/index.md | 48 ------- .../collection/count/snippets/count-1.java | 16 --- .../collection/create-document/index.md | 58 --------- .../snippets/create-document-1.java | 22 ---- doc/2/core-classes/collection/create/index.md | 69 ---------- .../collection/create/snippets/create-1.java | 26 ---- .../collection/delete-document/index.md | 66 ---------- .../snippets/delete-document-1.java | 36 ------ .../collection/delete-specifications/index.md | 46 ------- .../snippets/delete-specifications-1.java | 15 --- .../core-classes/collection/document/index.md | 29 ----- .../document/snippets/document-1.java | 5 - .../collection/fetch-document/index.md | 38 ------ .../snippets/fetch-document-1.java | 14 -- .../collection/get-mapping/index.md | 37 ------ .../get-mapping/snippets/get-mapping-1.java | 14 -- .../collection/get-specifications/index.md | 50 -------- .../snippets/get-specifications-1.java | 14 -- doc/2/core-classes/collection/index.md | 6 - .../collection/mcreate-document/index.md | 54 -------- .../snippets/mcreate-document-1.java | 25 ---- .../mcreate-or-replace-document/index.md | 54 -------- .../mcreate-or-replace-document-1.java | 25 ---- .../collection/mdelete-document/index.md | 45 ------- .../snippets/mdelete-document-1.java | 17 --- .../collection/mget-document/index.md | 50 -------- .../snippets/mget-document-1.java | 17 --- .../collection/mreplace-document/index.md | 54 -------- .../snippets/mreplace-document-1.java | 25 ---- .../collection/mupdate-document/index.md | 54 -------- .../snippets/mupdate-document-1.java | 25 ---- .../collection/publish-message/index.md | 55 -------- .../snippets/publish-message-1.java | 8 -- .../collection/replace-document/index.md | 47 ------- .../snippets/replace-document-1.java | 16 --- doc/2/core-classes/collection/room/index.md | 32 ----- .../collection/room/snippets/room-1.java | 23 ---- .../collection/scroll-specifications/index.md | 43 ------- .../snippets/scroll-specifications-1.java | 21 --- doc/2/core-classes/collection/scroll/index.md | 50 -------- .../collection/scroll/snippets/scroll-1.java | 23 ---- .../collection/search-specifications/index.md | 45 ------- .../snippets/search-specifications-1.java | 32 ----- doc/2/core-classes/collection/search/index.md | 59 --------- .../collection/search/snippets/search-1.java | 87 ------------- .../collection/set-headers/index.md | 31 ----- .../set-headers/snippets/set-headers-1.java | 14 -- .../collection/subscribe/index.md | 50 -------- .../subscribe/snippets/subscribe-1.java | 60 --------- .../core-classes/collection/truncate/index.md | 63 --------- .../truncate/snippets/truncate-1.java | 15 --- .../collection/update-document/index.md | 49 ------- .../snippets/update-document-1.java | 16 --- .../collection/update-specifications/index.md | 60 --------- .../snippets/update-specifications-1.java | 26 ---- .../validate-specifications/index.md | 38 ------ .../snippets/validate-specifications-1.java | 26 ---- .../document/constructor/index.md | 46 ------- .../constructor/snippets/constructor-1.java | 10 -- doc/2/core-classes/document/delete/index.md | 39 ------ .../document/delete/snippets/delete-1.java | 12 -- doc/2/core-classes/document/exists/index.md | 37 ------ .../document/exists/snippets/exists-1.java | 12 -- doc/2/core-classes/document/index.md | 6 - doc/2/core-classes/document/publish/index.md | 37 ------ .../document/publish/snippets/publish-1.java | 2 - doc/2/core-classes/document/refresh/index.md | 37 ------ .../document/refresh/snippets/refresh-1.java | 12 -- doc/2/core-classes/document/save/index.md | 48 ------- .../document/save/snippets/save-1.java | 12 -- .../document/set-content/index.md | 36 ------ .../set-content/snippets/set-content-1.java | 4 - .../document/set-headers/index.md | 31 ----- .../set-headers/snippets/set-headers-1.java | 4 - .../core-classes/document/subscribe/index.md | 41 ------ .../subscribe/snippets/subscribe-1.java | 23 ---- doc/2/core-classes/index.md | 7 - .../core-classes/kuzzle/add-listener/index.md | 29 ----- .../add-listener/snippets/add-listener-1.java | 8 -- .../core-classes/kuzzle/check-token/index.md | 54 -------- .../check-token/snippets/check-token-1.java | 12 -- doc/2/core-classes/kuzzle/collection/index.md | 33 ----- .../collection/snippets/collection-1.java | 6 - doc/2/core-classes/kuzzle/connect/index.md | 27 ---- .../kuzzle/connect/snippets/connect-1.java | 2 - .../core-classes/kuzzle/constructor/index.md | 95 -------------- .../constructor/snippets/constructor-1.java | 22 ---- .../core-classes/kuzzle/create-index/index.md | 47 ------- .../create-index/snippets/create-index-1.java | 12 -- .../kuzzle/create-my-credentials/index.md | 39 ------ .../snippets/create-my-credentials-1.java | 14 -- .../kuzzle/delete-my-credentials/index.md | 38 ------ .../snippets/delete-my-credentials-1.java | 12 -- doc/2/core-classes/kuzzle/disconnect/index.md | 16 --- .../disconnect/snippets/disconnect-1.java | 2 - .../core-classes/kuzzle/flush-queue/index.md | 20 --- .../flush-queue/snippets/flush-queue-1.java | 2 - .../kuzzle/get-all-statistics/index.md | 66 ---------- .../snippets/get-all-statistics-1.java | 12 -- .../kuzzle/get-auto-refresh/index.md | 49 ------- .../snippets/get-auto-refresh-1.java | 12 -- .../kuzzle/get-jwt-token/index.md | 20 --- .../snippets/get-jwt-token-1.java | 2 - .../kuzzle/get-my-credentials/index.md | 47 ------- .../snippets/get-my-credentials-1.java | 12 -- .../kuzzle/get-my-rights/index.md | 58 --------- .../snippets/get-my-rights-1.java | 13 -- .../kuzzle/get-server-info/index.md | 120 ------------------ .../snippets/get-server-info-1.java | 12 -- .../kuzzle/get-statistics/index.md | 59 --------- .../snippets/get-statistics-1.java | 12 -- .../snippets/get-statistics-2.java | 13 -- doc/2/core-classes/kuzzle/index.md | 7 - .../kuzzle/list-collections/index.md | 58 --------- .../snippets/list-collections-1.java | 12 -- .../core-classes/kuzzle/list-indexes/index.md | 43 ------- .../list-indexes/snippets/list-indexes-1.java | 12 -- doc/2/core-classes/kuzzle/login/index.md | 49 ------- .../kuzzle/login/snippets/login-1.java | 16 --- doc/2/core-classes/kuzzle/logout/index.md | 41 ------ .../kuzzle/logout/snippets/logout-1.java | 12 -- .../kuzzle/memory-storage/index.md | 10 -- doc/2/core-classes/kuzzle/now/index.md | 43 ------- .../kuzzle/now/snippets/now-1.java | 12 -- doc/2/core-classes/kuzzle/query/index.md | 82 ------------ .../kuzzle/query/snippets/query-1.java | 22 ---- .../kuzzle/refresh-index/index.md | 57 --------- .../snippets/refresh-index-1.java | 2 - .../kuzzle/remove-all-listeners/index.md | 28 ---- .../snippets/remove-all-listeners-1.java | 6 - .../kuzzle/remove-listener/index.md | 29 ----- .../snippets/remove-listener-1.java | 2 - .../core-classes/kuzzle/replay-queue/index.md | 20 --- .../replay-queue/snippets/replay-queue-1.java | 2 - doc/2/core-classes/kuzzle/security/index.md | 10 -- .../kuzzle/set-auto-refresh/index.md | 57 --------- .../snippets/set-auto-refresh-1.java | 2 - .../kuzzle/set-default-index/index.md | 16 --- .../core-classes/kuzzle/set-headers/index.md | 31 ----- .../set-headers/snippets/set-headers-1.java | 4 - .../kuzzle/set-jwt-token/index.md | 42 ------ .../snippets/set-jwt-token-1.java | 12 -- .../kuzzle/start-queuing/index.md | 20 --- .../snippets/start-queuing-1.java | 2 - .../core-classes/kuzzle/stop-queuing/index.md | 20 --- .../stop-queuing/snippets/stop-queuing-1.java | 2 - .../kuzzle/unset-jwt-token/index.md | 20 --- .../snippets/unset-jwt-token-1.java | 2 - .../kuzzle/update-my-credentials/index.md | 39 ------ .../snippets/update-my-credentials-1.java | 14 -- .../core-classes/kuzzle/update-self/index.md | 44 ------- .../update-self/snippets/update-self-1.java | 17 --- .../kuzzle/validate-my-credentials/index.md | 39 ------ .../snippets/validate-my-credentials-1.java | 14 -- doc/2/core-classes/kuzzle/who-am-i/index.md | 28 ---- .../kuzzle/who-am-i/snippets/who-am-i-1.java | 12 -- .../memory-storage/append/index.md | 53 -------- .../append/snippets/append-1.java | 11 -- .../memory-storage/bitcount/index.md | 48 ------- .../bitcount/snippets/bitcount-1.java | 11 -- .../memory-storage/bitop/index.md | 54 -------- .../bitop/snippets/bitop-1.java | 13 -- .../memory-storage/bitpos/index.md | 49 ------- .../bitpos/snippets/bitpos-1.java | 11 -- .../memory-storage/constructor/index.md | 24 ---- .../constructor/snippets/constructor-1.java | 6 - .../memory-storage/dbsize/index.md | 45 ------- .../dbsize/snippets/dbsize-1.java | 11 -- .../core-classes/memory-storage/decr/index.md | 52 -------- .../memory-storage/decr/snippets/decr-1.java | 11 -- .../memory-storage/decrby/index.md | 53 -------- .../decrby/snippets/decrby-1.java | 11 -- .../core-classes/memory-storage/del/index.md | 52 -------- .../memory-storage/del/snippets/del-1.java | 13 -- .../memory-storage/exists/index.md | 46 ------- .../exists/snippets/exists-1.java | 13 -- .../memory-storage/expire/index.md | 53 -------- .../expire/snippets/expire-1.java | 11 -- .../memory-storage/expireat/index.md | 54 -------- .../expireat/snippets/expireat-1.java | 11 -- .../memory-storage/flushdb/index.md | 45 ------- .../flushdb/snippets/flushdb-1.java | 11 -- .../memory-storage/geoadd/index.md | 53 -------- .../geoadd/snippets/geoadd-1.java | 22 ---- .../memory-storage/geodist/index.md | 50 -------- .../geodist/snippets/geodist-1.java | 11 -- .../memory-storage/geohash/index.md | 47 ------- .../geohash/snippets/geohash-1.java | 13 -- .../memory-storage/geopos/index.md | 47 ------- .../geopos/snippets/geopos-1.java | 13 -- .../memory-storage/georadius/index.md | 72 ----------- .../georadius/snippets/georadius-1.java | 11 -- .../memory-storage/georadiusbymember/index.md | 70 ---------- .../snippets/georadiusbymember-1.java | 11 -- .../core-classes/memory-storage/get/index.md | 46 ------- .../memory-storage/get/snippets/get-1.java | 11 -- .../memory-storage/getbit/index.md | 47 ------- .../getbit/snippets/getbit-1.java | 11 -- .../memory-storage/getrange/index.md | 48 ------- .../getrange/snippets/getrange-1.java | 11 -- .../memory-storage/getset/index.md | 53 -------- .../getset/snippets/getset-1.java | 11 -- .../core-classes/memory-storage/hdel/index.md | 53 -------- .../memory-storage/hdel/snippets/hdel-1.java | 13 -- .../memory-storage/hexists/index.md | 47 ------- .../hexists/snippets/hexists-1.java | 11 -- .../core-classes/memory-storage/hget/index.md | 47 ------- .../memory-storage/hget/snippets/hget-1.java | 11 -- .../memory-storage/hgetall/index.md | 50 -------- .../hgetall/snippets/hgetall-1.java | 11 -- .../memory-storage/hincrby/index.md | 54 -------- .../hincrby/snippets/hincrby-1.java | 11 -- .../memory-storage/hincrbyfloat/index.md | 54 -------- .../hincrbyfloat/snippets/hincrbyfloat-1.java | 11 -- .../memory-storage/hkeys/index.md | 46 ------- .../hkeys/snippets/hkeys-1.java | 11 -- .../core-classes/memory-storage/hlen/index.md | 46 ------- .../memory-storage/hlen/snippets/hlen-1.java | 11 -- .../memory-storage/hmget/index.md | 47 ------- .../hmget/snippets/hmget-1.java | 13 -- .../memory-storage/hmset/index.md | 47 ------- .../hmset/snippets/hmset-1.java | 17 --- .../memory-storage/hscan/index.md | 55 -------- .../hscan/snippets/hscan-1.java | 10 -- .../core-classes/memory-storage/hset/index.md | 54 -------- .../memory-storage/hset/snippets/hset-1.java | 11 -- .../memory-storage/hsetnx/index.md | 54 -------- .../hsetnx/snippets/hsetnx-1.java | 11 -- .../memory-storage/hstrlen/index.md | 47 ------- .../hstrlen/snippets/hstrlen-1.java | 11 -- .../memory-storage/hvals/index.md | 46 ------- .../hvals/snippets/hvals-1.java | 11 -- .../core-classes/memory-storage/incr/index.md | 52 -------- .../memory-storage/incr/snippets/incr-1.java | 11 -- .../memory-storage/incrby/index.md | 53 -------- .../incrby/snippets/incrby-1.java | 11 -- .../memory-storage/incrbyfloat/index.md | 53 -------- .../incrbyfloat/snippets/incrbyfloat-1.java | 11 -- doc/2/core-classes/memory-storage/index.md | 6 - .../core-classes/memory-storage/keys/index.md | 46 ------- .../memory-storage/keys/snippets/keys-1.java | 11 -- .../memory-storage/lindex/index.md | 47 ------- .../lindex/snippets/lindex-1.java | 11 -- .../memory-storage/linsert/index.md | 55 -------- .../linsert/snippets/linsert-1.java | 11 -- .../core-classes/memory-storage/llen/index.md | 46 ------- .../memory-storage/llen/snippets/llen-1.java | 11 -- .../core-classes/memory-storage/lpop/index.md | 52 -------- .../memory-storage/lpop/snippets/lpop-1.java | 11 -- .../memory-storage/lpush/index.md | 51 -------- .../lpush/snippets/lpush-1.java | 13 -- .../memory-storage/lpushx/index.md | 53 -------- .../lpushx/snippets/lpushx-1.java | 11 -- .../memory-storage/lrange/index.md | 48 ------- .../lrange/snippets/lrange-1.java | 11 -- .../core-classes/memory-storage/lrem/index.md | 54 -------- .../memory-storage/lrem/snippets/lrem-1.java | 11 -- .../core-classes/memory-storage/lset/index.md | 48 ------- .../memory-storage/lset/snippets/lset-1.java | 11 -- .../memory-storage/ltrim/index.md | 48 ------- .../ltrim/snippets/ltrim-1.java | 11 -- .../core-classes/memory-storage/mget/index.md | 46 ------- .../memory-storage/mget/snippets/mget-1.java | 13 -- .../core-classes/memory-storage/mset/index.md | 46 ------- .../memory-storage/mset/snippets/mset-1.java | 17 --- .../memory-storage/msetnx/index.md | 52 -------- .../msetnx/snippets/msetnx-1.java | 17 --- .../memory-storage/object/index.md | 47 ------- .../object/snippets/object-1.java | 11 -- .../memory-storage/persist/index.md | 50 -------- .../persist/snippets/persist-1.java | 11 -- .../memory-storage/pexpire/index.md | 53 -------- .../pexpire/snippets/pexpire-1.java | 11 -- .../memory-storage/pexpireat/index.md | 54 -------- .../pexpireat/snippets/pexpireat-1.java | 11 -- .../memory-storage/pfadd/index.md | 53 -------- .../pfadd/snippets/pfadd-1.java | 13 -- .../memory-storage/pfcount/index.md | 46 ------- .../pfcount/snippets/pfcount-1.java | 13 -- .../memory-storage/pfmerge/index.md | 41 ------ .../pfmerge/snippets/pfmerge-1.java | 13 -- .../core-classes/memory-storage/ping/index.md | 45 ------- .../memory-storage/ping/snippets/ping-1.java | 11 -- .../memory-storage/psetex/index.md | 48 ------- .../psetex/snippets/psetex-1.java | 11 -- .../core-classes/memory-storage/pttl/index.md | 46 ------- .../memory-storage/pttl/snippets/pttl-1.java | 11 -- .../memory-storage/randomkey/index.md | 45 ------- .../randomkey/snippets/randomkey-1.java | 11 -- .../memory-storage/rename/index.md | 47 ------- .../rename/snippets/rename-1.java | 11 -- .../memory-storage/renamenx/index.md | 53 -------- .../renamenx/snippets/renamenx-1.java | 11 -- .../core-classes/memory-storage/rpop/index.md | 50 -------- .../memory-storage/rpop/snippets/rpop-1.java | 11 -- .../memory-storage/rpoplpush/index.md | 53 -------- .../rpoplpush/snippets/rpoplpush-1.java | 11 -- .../memory-storage/rpush/index.md | 53 -------- .../rpush/snippets/rpush-1.java | 13 -- .../memory-storage/rpushx/index.md | 53 -------- .../rpushx/snippets/rpushx-1.java | 11 -- .../core-classes/memory-storage/sadd/index.md | 53 -------- .../memory-storage/sadd/snippets/sadd-1.java | 13 -- .../core-classes/memory-storage/scan/index.md | 58 --------- .../memory-storage/scan/snippets/scan-1.java | 11 -- .../memory-storage/scard/index.md | 46 ------- .../scard/snippets/scard-1.java | 11 -- .../memory-storage/sdiff/index.md | 53 -------- .../sdiff/snippets/sdiff-1.java | 13 -- .../memory-storage/sdiffstore/index.md | 56 -------- .../sdiffstore/snippets/sdiffstore-1.java | 13 -- .../core-classes/memory-storage/set/index.md | 51 -------- .../memory-storage/set/snippets/set-1.java | 11 -- .../memory-storage/setex/index.md | 48 ------- .../setex/snippets/setex-1.java | 11 -- .../memory-storage/setnx/index.md | 53 -------- .../setnx/snippets/setnx-1.java | 11 -- .../memory-storage/sinter/index.md | 46 ------- .../sinter/snippets/sinter-1.java | 13 -- .../memory-storage/sinterstore/index.md | 55 -------- .../sinterstore/snippets/sinterstore-1.java | 13 -- .../memory-storage/sismember/index.md | 47 ------- .../sismember/snippets/sismember-1.java | 11 -- .../memory-storage/smembers/index.md | 52 -------- .../smembers/snippets/smembers-1.java | 11 -- .../memory-storage/smove/index.md | 54 -------- .../smove/snippets/smove-1.java | 11 -- .../core-classes/memory-storage/sort/index.md | 52 -------- .../memory-storage/sort/snippets/sort-1.java | 11 -- .../core-classes/memory-storage/spop/index.md | 53 -------- .../memory-storage/spop/snippets/spop-1.java | 11 -- .../memory-storage/srandmember/index.md | 48 ------- .../srandmember/snippets/srandmember-1.java | 11 -- .../core-classes/memory-storage/srem/index.md | 53 -------- .../memory-storage/srem/snippets/srem-1.java | 13 -- .../memory-storage/sscan/index.md | 55 -------- .../sscan/snippets/sscan-1.java | 11 -- .../memory-storage/strlen/index.md | 46 ------- .../strlen/snippets/strlen-1.java | 11 -- .../memory-storage/sunion/index.md | 46 ------- .../sunion/snippets/sunion-1.java | 13 -- .../memory-storage/sunionstore/index.md | 49 ------- .../sunionstore/snippets/sunionstore-1.java | 13 -- .../core-classes/memory-storage/time/index.md | 48 ------- .../memory-storage/time/snippets/time-1.java | 11 -- .../memory-storage/touch/index.md | 52 -------- .../touch/snippets/touch-1.java | 13 -- .../core-classes/memory-storage/ttl/index.md | 46 ------- .../memory-storage/ttl/snippets/ttl-1.java | 11 -- .../core-classes/memory-storage/type/index.md | 46 ------- .../memory-storage/type/snippets/type-1.java | 11 -- .../core-classes/memory-storage/zadd/index.md | 61 --------- .../memory-storage/zadd/snippets/zadd-1.java | 16 --- .../memory-storage/zcard/index.md | 46 ------- .../zcard/snippets/zcard-1.java | 11 -- .../memory-storage/zcount/index.md | 50 -------- .../zcount/snippets/zcount-1.java | 11 -- .../memory-storage/zincrby/index.md | 54 -------- .../zincrby/snippets/zincrby-1.java | 11 -- .../memory-storage/zinterstore/index.md | 51 -------- .../zinterstore/snippets/zinterstore-1.java | 13 -- .../memory-storage/zlexcount/index.md | 48 ------- .../zlexcount/snippets/zlexcount-1.java | 11 -- .../memory-storage/zrange/index.md | 62 --------- .../zrange/snippets/zrange-1.java | 11 -- .../memory-storage/zrangebylex/index.md | 55 -------- .../zrangebylex/snippets/zrangebylex-1.java | 11 -- .../memory-storage/zrangebyscore/index.md | 59 --------- .../snippets/zrangebyscore-1.java | 11 -- .../memory-storage/zrank/index.md | 47 ------- .../zrank/snippets/zrank-1.java | 11 -- .../core-classes/memory-storage/zrem/index.md | 53 -------- .../memory-storage/zrem/snippets/zrem-1.java | 13 -- .../memory-storage/zremrangebylex/index.md | 54 -------- .../snippets/zremrangebylex-1.java | 11 -- .../memory-storage/zremrangebyrank/index.md | 56 -------- .../snippets/zremrangebyrank-1.java | 11 -- .../memory-storage/zremrangebyscore/index.md | 54 -------- .../snippets/zremrangebyscore-1.java | 11 -- .../memory-storage/zrevrange/index.md | 61 --------- .../zrevrange/snippets/zrevrange-1.java | 11 -- .../memory-storage/zrevrangebylex/index.md | 55 -------- .../snippets/zrevrangebylex-1.java | 11 -- .../memory-storage/zrevrangebyscore/index.md | 59 --------- .../snippets/zrevrangebyscore-1.java | 11 -- .../memory-storage/zrevrank/index.md | 47 ------- .../zrevrank/snippets/zrevrank-1.java | 11 -- .../memory-storage/zscan/index.md | 55 -------- .../zscan/snippets/zscan-1.java | 11 -- .../memory-storage/zscore/index.md | 47 ------- .../zscore/snippets/zscore-1.java | 11 -- .../memory-storage/zunionstore/index.md | 51 -------- .../zunionstore/snippets/zunionstore-1.java | 13 -- .../core-classes/profile/add-policy/index.md | 40 ------ .../add-policy/snippets/add-policy-1.java | 15 --- .../core-classes/profile/constructor/index.md | 44 ------- .../constructor/snippets/constructor-1.java | 20 --- doc/2/core-classes/profile/delete/index.md | 37 ------ .../profile/delete/snippets/delete-1.java | 13 -- .../profile/get-policies/index.md | 44 ------- .../get-policies/snippets/get-policies-1.java | 3 - doc/2/core-classes/profile/index.md | 6 - doc/2/core-classes/profile/save/index.md | 47 ------- .../profile/save/snippets/save-1.java | 32 ----- .../core-classes/profile/set-content/index.md | 32 ----- .../set-content/snippets/set-content-1.java | 21 --- .../profile/set-policies/index.md | 40 ------ .../set-policies/snippets/set-policies-1.java | 10 -- doc/2/core-classes/profile/update/index.md | 44 ------- .../profile/update/snippets/update-1.java | 17 --- doc/2/core-classes/role/constructor/index.md | 44 ------- .../constructor/snippets/constructor-1.java | 12 -- doc/2/core-classes/role/delete/index.md | 37 ------ .../role/delete/snippets/delete-1.java | 12 -- doc/2/core-classes/role/index.md | 6 - doc/2/core-classes/role/save/index.md | 43 ------- .../role/save/snippets/save-1.java | 12 -- doc/2/core-classes/role/set-content/index.md | 32 ----- .../set-content/snippets/set-content-1.java | 12 -- doc/2/core-classes/role/update/index.md | 53 -------- .../role/update/snippets/update-1.java | 22 ---- doc/2/core-classes/room/constructor/index.md | 55 -------- .../constructor/snippets/constructor-1.java | 5 - doc/2/core-classes/room/count/index.md | 34 ----- .../room/count/snippets/count-1.java | 12 -- doc/2/core-classes/room/index.md | 6 - doc/2/core-classes/room/renew/index.md | 26 ---- .../room/renew/snippets/renew-1.java | 49 ------- doc/2/core-classes/room/set-headers/index.md | 33 ----- .../set-headers/snippets/set-headers-1.java | 4 - doc/2/core-classes/room/unsubscribe/index.md | 20 --- .../unsubscribe/snippets/unsubscribe-1.java | 2 - .../search-result/constructor/index.md | 27 ---- .../search-result/fetch-next/index.md | 40 ------ .../fetch-next/snippets/fetch-next-1.java | 13 -- .../fetch-next/snippets/fetch-next-2.java | 37 ------ doc/2/core-classes/search-result/index.md | 6 - .../security/constructor/index.md | 25 ---- .../constructor/snippets/constructor-1.java | 6 - .../security/create-credentials/index.md | 49 ------- .../snippets/create-credentials-1.java | 14 -- .../security/create-profile/index.md | 46 ------- .../snippets/create-profile-1.java | 29 ----- .../security/create-restricted-user/index.md | 46 ------- .../snippets/create-restricted-user-1.java | 28 ---- .../security/create-role/index.md | 46 ------- .../create-role/snippets/create-role-1.java | 26 ---- .../security/create-user/index.md | 54 -------- .../create-user/snippets/create-user-1.java | 38 ------ .../security/delete-credentials/index.md | 47 ------- .../snippets/delete-credentials-1.java | 12 -- .../security/delete-profile/index.md | 56 -------- .../snippets/delete-profile-1.java | 14 -- .../security/delete-role/index.md | 56 -------- .../delete-role/snippets/delete-role-1.java | 14 -- .../security/delete-user/index.md | 56 -------- .../delete-user/snippets/delete-user-1.java | 14 -- .../security/fetch-profile/index.md | 38 ------ .../snippets/fetch-profile-1.java | 15 --- .../core-classes/security/fetch-role/index.md | 38 ------ .../fetch-role/snippets/fetch-role-1.java | 15 --- .../core-classes/security/fetch-user/index.md | 38 ------ .../fetch-user/snippets/fetch-user-1.java | 14 -- .../get-all-credential-fields/index.md | 45 ------- .../snippets/get-all-credential-fields-1.java | 12 -- .../security/get-credentials-fields/index.md | 44 ------- .../snippets/get-credentials-fields-1.java | 12 -- .../security/get-credentials/index.md | 48 ------- .../snippets/get-credentials-1.java | 12 -- .../security/get-user-rights/index.md | 59 --------- .../snippets/get-user-rights-1.java | 15 --- .../security/has-credentials/index.md | 39 ------ .../snippets/has-credentials-1.java | 12 -- doc/2/core-classes/security/index.md | 6 - .../security/is-action-allowed/index.md | 42 ------ .../snippets/is-action-allowed-1.java | 14 -- doc/2/core-classes/security/profile/index.md | 29 ----- .../security/profile/snippets/profile-1.java | 20 --- .../security/replace-user/index.md | 46 ------- .../replace-user/snippets/replace-user-1.java | 21 --- doc/2/core-classes/security/role/index.md | 29 ----- .../security/role/snippets/role-1.java | 12 -- .../security/scroll-profiles/index.md | 38 ------ .../snippets/scroll-profiles-1.java | 14 -- .../security/scroll-users/index.md | 38 ------ .../scroll-users/snippets/scroll-users-1.java | 14 -- .../security/search-profiles/index.md | 62 --------- .../snippets/search-profiles-1.java | 35 ----- .../security/search-roles/index.md | 59 --------- .../search-roles/snippets/search-roles-1.java | 29 ----- .../security/search-users/index.md | 58 --------- .../search-users/snippets/search-users-1.java | 49 ------- .../security/update-credentials/index.md | 49 ------- .../snippets/update-credentials-1.java | 13 -- .../security/update-profile/index.md | 46 ------- .../snippets/update-profile-1.java | 27 ---- .../security/update-role/index.md | 46 ------- .../update-role/snippets/update-role-1.java | 24 ---- .../security/update-user/index.md | 46 ------- .../update-user/snippets/update-user-1.java | 18 --- doc/2/core-classes/security/user/index.md | 29 ----- .../security/user/snippets/user-1.java | 11 -- .../security/validate-credentials/index.md | 48 ------- .../snippets/validate-credentials-1.java | 14 -- doc/2/core-classes/user/add-profile/index.md | 40 ------ .../add-profile/snippets/add-profile-1.java | 15 --- doc/2/core-classes/user/constructor/index.md | 42 ------ .../constructor/snippets/constructor-1.java | 15 --- doc/2/core-classes/user/create/index.md | 43 ------- .../user/create/snippets/create-1.java | 12 -- doc/2/core-classes/user/delete/index.md | 37 ------ .../user/delete/snippets/delete-1.java | 11 -- .../core-classes/user/get-profileids/index.md | 20 --- .../snippets/get-profileids-1.java | 2 - doc/2/core-classes/user/get-profiles/index.md | 37 ------ .../get-profiles/snippets/get-profiles-1.java | 12 -- doc/2/core-classes/user/index.md | 6 - doc/2/core-classes/user/replace/index.md | 43 ------- .../user/replace/snippets/replace-1.java | 12 -- .../user/save-restricted/index.md | 41 ------ .../snippets/save-restricted-1.java | 12 -- doc/2/core-classes/user/save/index.md | 43 ------- .../user/save/snippets/save-1.java | 12 -- doc/2/core-classes/user/set-content/index.md | 32 ----- .../set-content/snippets/set-content-1.java | 7 - .../user/set-credentials/index.md | 33 ----- .../snippets/set-credentials-1.java | 6 - doc/2/core-classes/user/set-profiles/index.md | 40 ------ .../set-profiles/snippets/set-profiles-1.java | 22 ---- doc/2/core-classes/user/update/index.md | 44 ------- .../user/update/snippets/update-1.java | 16 --- doc/2/essentials/error-handling/index.md | 16 --- .../snippets/handling-errors-1.java | 17 --- doc/2/essentials/events/index.md | 29 ----- doc/2/essentials/index.md | 7 - doc/2/essentials/offline-tools/index.md | 96 -------------- .../realtime-notifications/index.md | 90 ------------- doc/2/index.md | 7 - 554 files changed, 16354 deletions(-) delete mode 120000 doc/2/.vuepress delete mode 100644 doc/2/core-classes/collection-mapping/apply/index.md delete mode 100644 doc/2/core-classes/collection-mapping/apply/snippets/apply-1.java delete mode 100644 doc/2/core-classes/collection-mapping/constructor/index.md delete mode 100644 doc/2/core-classes/collection-mapping/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/collection-mapping/index.md delete mode 100644 doc/2/core-classes/collection-mapping/refresh/index.md delete mode 100644 doc/2/core-classes/collection-mapping/refresh/snippets/refresh-1.java delete mode 100644 doc/2/core-classes/collection-mapping/set-headers/index.md delete mode 100644 doc/2/core-classes/collection-mapping/set-headers/snippets/set-headers-1.java delete mode 100644 doc/2/core-classes/collection-mapping/set/index.md delete mode 100644 doc/2/core-classes/collection-mapping/set/snippets/set-1.java delete mode 100644 doc/2/core-classes/collection/collection-mapping/index.md delete mode 100644 doc/2/core-classes/collection/collection-mapping/snippets/collection-mapping-1.java delete mode 100644 doc/2/core-classes/collection/constructor/index.md delete mode 100644 doc/2/core-classes/collection/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/collection/count/index.md delete mode 100644 doc/2/core-classes/collection/count/snippets/count-1.java delete mode 100644 doc/2/core-classes/collection/create-document/index.md delete mode 100644 doc/2/core-classes/collection/create-document/snippets/create-document-1.java delete mode 100644 doc/2/core-classes/collection/create/index.md delete mode 100644 doc/2/core-classes/collection/create/snippets/create-1.java delete mode 100644 doc/2/core-classes/collection/delete-document/index.md delete mode 100644 doc/2/core-classes/collection/delete-document/snippets/delete-document-1.java delete mode 100644 doc/2/core-classes/collection/delete-specifications/index.md delete mode 100644 doc/2/core-classes/collection/delete-specifications/snippets/delete-specifications-1.java delete mode 100644 doc/2/core-classes/collection/document/index.md delete mode 100644 doc/2/core-classes/collection/document/snippets/document-1.java delete mode 100644 doc/2/core-classes/collection/fetch-document/index.md delete mode 100644 doc/2/core-classes/collection/fetch-document/snippets/fetch-document-1.java delete mode 100644 doc/2/core-classes/collection/get-mapping/index.md delete mode 100644 doc/2/core-classes/collection/get-mapping/snippets/get-mapping-1.java delete mode 100644 doc/2/core-classes/collection/get-specifications/index.md delete mode 100644 doc/2/core-classes/collection/get-specifications/snippets/get-specifications-1.java delete mode 100644 doc/2/core-classes/collection/index.md delete mode 100644 doc/2/core-classes/collection/mcreate-document/index.md delete mode 100644 doc/2/core-classes/collection/mcreate-document/snippets/mcreate-document-1.java delete mode 100644 doc/2/core-classes/collection/mcreate-or-replace-document/index.md delete mode 100644 doc/2/core-classes/collection/mcreate-or-replace-document/snippets/mcreate-or-replace-document-1.java delete mode 100644 doc/2/core-classes/collection/mdelete-document/index.md delete mode 100644 doc/2/core-classes/collection/mdelete-document/snippets/mdelete-document-1.java delete mode 100644 doc/2/core-classes/collection/mget-document/index.md delete mode 100644 doc/2/core-classes/collection/mget-document/snippets/mget-document-1.java delete mode 100644 doc/2/core-classes/collection/mreplace-document/index.md delete mode 100644 doc/2/core-classes/collection/mreplace-document/snippets/mreplace-document-1.java delete mode 100644 doc/2/core-classes/collection/mupdate-document/index.md delete mode 100644 doc/2/core-classes/collection/mupdate-document/snippets/mupdate-document-1.java delete mode 100644 doc/2/core-classes/collection/publish-message/index.md delete mode 100644 doc/2/core-classes/collection/publish-message/snippets/publish-message-1.java delete mode 100644 doc/2/core-classes/collection/replace-document/index.md delete mode 100644 doc/2/core-classes/collection/replace-document/snippets/replace-document-1.java delete mode 100644 doc/2/core-classes/collection/room/index.md delete mode 100644 doc/2/core-classes/collection/room/snippets/room-1.java delete mode 100644 doc/2/core-classes/collection/scroll-specifications/index.md delete mode 100644 doc/2/core-classes/collection/scroll-specifications/snippets/scroll-specifications-1.java delete mode 100644 doc/2/core-classes/collection/scroll/index.md delete mode 100644 doc/2/core-classes/collection/scroll/snippets/scroll-1.java delete mode 100644 doc/2/core-classes/collection/search-specifications/index.md delete mode 100644 doc/2/core-classes/collection/search-specifications/snippets/search-specifications-1.java delete mode 100644 doc/2/core-classes/collection/search/index.md delete mode 100644 doc/2/core-classes/collection/search/snippets/search-1.java delete mode 100644 doc/2/core-classes/collection/set-headers/index.md delete mode 100644 doc/2/core-classes/collection/set-headers/snippets/set-headers-1.java delete mode 100644 doc/2/core-classes/collection/subscribe/index.md delete mode 100644 doc/2/core-classes/collection/subscribe/snippets/subscribe-1.java delete mode 100644 doc/2/core-classes/collection/truncate/index.md delete mode 100644 doc/2/core-classes/collection/truncate/snippets/truncate-1.java delete mode 100644 doc/2/core-classes/collection/update-document/index.md delete mode 100644 doc/2/core-classes/collection/update-document/snippets/update-document-1.java delete mode 100644 doc/2/core-classes/collection/update-specifications/index.md delete mode 100644 doc/2/core-classes/collection/update-specifications/snippets/update-specifications-1.java delete mode 100644 doc/2/core-classes/collection/validate-specifications/index.md delete mode 100644 doc/2/core-classes/collection/validate-specifications/snippets/validate-specifications-1.java delete mode 100644 doc/2/core-classes/document/constructor/index.md delete mode 100644 doc/2/core-classes/document/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/document/delete/index.md delete mode 100644 doc/2/core-classes/document/delete/snippets/delete-1.java delete mode 100644 doc/2/core-classes/document/exists/index.md delete mode 100644 doc/2/core-classes/document/exists/snippets/exists-1.java delete mode 100644 doc/2/core-classes/document/index.md delete mode 100644 doc/2/core-classes/document/publish/index.md delete mode 100644 doc/2/core-classes/document/publish/snippets/publish-1.java delete mode 100644 doc/2/core-classes/document/refresh/index.md delete mode 100644 doc/2/core-classes/document/refresh/snippets/refresh-1.java delete mode 100644 doc/2/core-classes/document/save/index.md delete mode 100644 doc/2/core-classes/document/save/snippets/save-1.java delete mode 100644 doc/2/core-classes/document/set-content/index.md delete mode 100644 doc/2/core-classes/document/set-content/snippets/set-content-1.java delete mode 100644 doc/2/core-classes/document/set-headers/index.md delete mode 100644 doc/2/core-classes/document/set-headers/snippets/set-headers-1.java delete mode 100644 doc/2/core-classes/document/subscribe/index.md delete mode 100644 doc/2/core-classes/document/subscribe/snippets/subscribe-1.java delete mode 100644 doc/2/core-classes/index.md delete mode 100644 doc/2/core-classes/kuzzle/add-listener/index.md delete mode 100644 doc/2/core-classes/kuzzle/add-listener/snippets/add-listener-1.java delete mode 100644 doc/2/core-classes/kuzzle/check-token/index.md delete mode 100644 doc/2/core-classes/kuzzle/check-token/snippets/check-token-1.java delete mode 100644 doc/2/core-classes/kuzzle/collection/index.md delete mode 100644 doc/2/core-classes/kuzzle/collection/snippets/collection-1.java delete mode 100644 doc/2/core-classes/kuzzle/connect/index.md delete mode 100644 doc/2/core-classes/kuzzle/connect/snippets/connect-1.java delete mode 100644 doc/2/core-classes/kuzzle/constructor/index.md delete mode 100644 doc/2/core-classes/kuzzle/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/kuzzle/create-index/index.md delete mode 100644 doc/2/core-classes/kuzzle/create-index/snippets/create-index-1.java delete mode 100644 doc/2/core-classes/kuzzle/create-my-credentials/index.md delete mode 100644 doc/2/core-classes/kuzzle/create-my-credentials/snippets/create-my-credentials-1.java delete mode 100644 doc/2/core-classes/kuzzle/delete-my-credentials/index.md delete mode 100644 doc/2/core-classes/kuzzle/delete-my-credentials/snippets/delete-my-credentials-1.java delete mode 100644 doc/2/core-classes/kuzzle/disconnect/index.md delete mode 100644 doc/2/core-classes/kuzzle/disconnect/snippets/disconnect-1.java delete mode 100644 doc/2/core-classes/kuzzle/flush-queue/index.md delete mode 100644 doc/2/core-classes/kuzzle/flush-queue/snippets/flush-queue-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-all-statistics/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-all-statistics/snippets/get-all-statistics-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-auto-refresh/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-auto-refresh/snippets/get-auto-refresh-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-jwt-token/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-jwt-token/snippets/get-jwt-token-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-my-credentials/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-my-credentials/snippets/get-my-credentials-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-my-rights/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-my-rights/snippets/get-my-rights-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-server-info/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-server-info/snippets/get-server-info-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-statistics/index.md delete mode 100644 doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-1.java delete mode 100644 doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-2.java delete mode 100644 doc/2/core-classes/kuzzle/index.md delete mode 100644 doc/2/core-classes/kuzzle/list-collections/index.md delete mode 100644 doc/2/core-classes/kuzzle/list-collections/snippets/list-collections-1.java delete mode 100644 doc/2/core-classes/kuzzle/list-indexes/index.md delete mode 100644 doc/2/core-classes/kuzzle/list-indexes/snippets/list-indexes-1.java delete mode 100644 doc/2/core-classes/kuzzle/login/index.md delete mode 100644 doc/2/core-classes/kuzzle/login/snippets/login-1.java delete mode 100644 doc/2/core-classes/kuzzle/logout/index.md delete mode 100644 doc/2/core-classes/kuzzle/logout/snippets/logout-1.java delete mode 100644 doc/2/core-classes/kuzzle/memory-storage/index.md delete mode 100644 doc/2/core-classes/kuzzle/now/index.md delete mode 100644 doc/2/core-classes/kuzzle/now/snippets/now-1.java delete mode 100644 doc/2/core-classes/kuzzle/query/index.md delete mode 100644 doc/2/core-classes/kuzzle/query/snippets/query-1.java delete mode 100644 doc/2/core-classes/kuzzle/refresh-index/index.md delete mode 100644 doc/2/core-classes/kuzzle/refresh-index/snippets/refresh-index-1.java delete mode 100644 doc/2/core-classes/kuzzle/remove-all-listeners/index.md delete mode 100644 doc/2/core-classes/kuzzle/remove-all-listeners/snippets/remove-all-listeners-1.java delete mode 100644 doc/2/core-classes/kuzzle/remove-listener/index.md delete mode 100644 doc/2/core-classes/kuzzle/remove-listener/snippets/remove-listener-1.java delete mode 100644 doc/2/core-classes/kuzzle/replay-queue/index.md delete mode 100644 doc/2/core-classes/kuzzle/replay-queue/snippets/replay-queue-1.java delete mode 100644 doc/2/core-classes/kuzzle/security/index.md delete mode 100644 doc/2/core-classes/kuzzle/set-auto-refresh/index.md delete mode 100644 doc/2/core-classes/kuzzle/set-auto-refresh/snippets/set-auto-refresh-1.java delete mode 100644 doc/2/core-classes/kuzzle/set-default-index/index.md delete mode 100644 doc/2/core-classes/kuzzle/set-headers/index.md delete mode 100644 doc/2/core-classes/kuzzle/set-headers/snippets/set-headers-1.java delete mode 100644 doc/2/core-classes/kuzzle/set-jwt-token/index.md delete mode 100644 doc/2/core-classes/kuzzle/set-jwt-token/snippets/set-jwt-token-1.java delete mode 100644 doc/2/core-classes/kuzzle/start-queuing/index.md delete mode 100644 doc/2/core-classes/kuzzle/start-queuing/snippets/start-queuing-1.java delete mode 100644 doc/2/core-classes/kuzzle/stop-queuing/index.md delete mode 100644 doc/2/core-classes/kuzzle/stop-queuing/snippets/stop-queuing-1.java delete mode 100644 doc/2/core-classes/kuzzle/unset-jwt-token/index.md delete mode 100644 doc/2/core-classes/kuzzle/unset-jwt-token/snippets/unset-jwt-token-1.java delete mode 100644 doc/2/core-classes/kuzzle/update-my-credentials/index.md delete mode 100644 doc/2/core-classes/kuzzle/update-my-credentials/snippets/update-my-credentials-1.java delete mode 100644 doc/2/core-classes/kuzzle/update-self/index.md delete mode 100644 doc/2/core-classes/kuzzle/update-self/snippets/update-self-1.java delete mode 100644 doc/2/core-classes/kuzzle/validate-my-credentials/index.md delete mode 100644 doc/2/core-classes/kuzzle/validate-my-credentials/snippets/validate-my-credentials-1.java delete mode 100644 doc/2/core-classes/kuzzle/who-am-i/index.md delete mode 100644 doc/2/core-classes/kuzzle/who-am-i/snippets/who-am-i-1.java delete mode 100644 doc/2/core-classes/memory-storage/append/index.md delete mode 100644 doc/2/core-classes/memory-storage/append/snippets/append-1.java delete mode 100644 doc/2/core-classes/memory-storage/bitcount/index.md delete mode 100644 doc/2/core-classes/memory-storage/bitcount/snippets/bitcount-1.java delete mode 100644 doc/2/core-classes/memory-storage/bitop/index.md delete mode 100644 doc/2/core-classes/memory-storage/bitop/snippets/bitop-1.java delete mode 100644 doc/2/core-classes/memory-storage/bitpos/index.md delete mode 100644 doc/2/core-classes/memory-storage/bitpos/snippets/bitpos-1.java delete mode 100644 doc/2/core-classes/memory-storage/constructor/index.md delete mode 100644 doc/2/core-classes/memory-storage/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/memory-storage/dbsize/index.md delete mode 100644 doc/2/core-classes/memory-storage/dbsize/snippets/dbsize-1.java delete mode 100644 doc/2/core-classes/memory-storage/decr/index.md delete mode 100644 doc/2/core-classes/memory-storage/decr/snippets/decr-1.java delete mode 100644 doc/2/core-classes/memory-storage/decrby/index.md delete mode 100644 doc/2/core-classes/memory-storage/decrby/snippets/decrby-1.java delete mode 100644 doc/2/core-classes/memory-storage/del/index.md delete mode 100644 doc/2/core-classes/memory-storage/del/snippets/del-1.java delete mode 100644 doc/2/core-classes/memory-storage/exists/index.md delete mode 100644 doc/2/core-classes/memory-storage/exists/snippets/exists-1.java delete mode 100644 doc/2/core-classes/memory-storage/expire/index.md delete mode 100644 doc/2/core-classes/memory-storage/expire/snippets/expire-1.java delete mode 100644 doc/2/core-classes/memory-storage/expireat/index.md delete mode 100644 doc/2/core-classes/memory-storage/expireat/snippets/expireat-1.java delete mode 100644 doc/2/core-classes/memory-storage/flushdb/index.md delete mode 100644 doc/2/core-classes/memory-storage/flushdb/snippets/flushdb-1.java delete mode 100644 doc/2/core-classes/memory-storage/geoadd/index.md delete mode 100644 doc/2/core-classes/memory-storage/geoadd/snippets/geoadd-1.java delete mode 100644 doc/2/core-classes/memory-storage/geodist/index.md delete mode 100644 doc/2/core-classes/memory-storage/geodist/snippets/geodist-1.java delete mode 100644 doc/2/core-classes/memory-storage/geohash/index.md delete mode 100644 doc/2/core-classes/memory-storage/geohash/snippets/geohash-1.java delete mode 100644 doc/2/core-classes/memory-storage/geopos/index.md delete mode 100644 doc/2/core-classes/memory-storage/geopos/snippets/geopos-1.java delete mode 100644 doc/2/core-classes/memory-storage/georadius/index.md delete mode 100644 doc/2/core-classes/memory-storage/georadius/snippets/georadius-1.java delete mode 100644 doc/2/core-classes/memory-storage/georadiusbymember/index.md delete mode 100644 doc/2/core-classes/memory-storage/georadiusbymember/snippets/georadiusbymember-1.java delete mode 100644 doc/2/core-classes/memory-storage/get/index.md delete mode 100644 doc/2/core-classes/memory-storage/get/snippets/get-1.java delete mode 100644 doc/2/core-classes/memory-storage/getbit/index.md delete mode 100644 doc/2/core-classes/memory-storage/getbit/snippets/getbit-1.java delete mode 100644 doc/2/core-classes/memory-storage/getrange/index.md delete mode 100644 doc/2/core-classes/memory-storage/getrange/snippets/getrange-1.java delete mode 100644 doc/2/core-classes/memory-storage/getset/index.md delete mode 100644 doc/2/core-classes/memory-storage/getset/snippets/getset-1.java delete mode 100644 doc/2/core-classes/memory-storage/hdel/index.md delete mode 100644 doc/2/core-classes/memory-storage/hdel/snippets/hdel-1.java delete mode 100644 doc/2/core-classes/memory-storage/hexists/index.md delete mode 100644 doc/2/core-classes/memory-storage/hexists/snippets/hexists-1.java delete mode 100644 doc/2/core-classes/memory-storage/hget/index.md delete mode 100644 doc/2/core-classes/memory-storage/hget/snippets/hget-1.java delete mode 100644 doc/2/core-classes/memory-storage/hgetall/index.md delete mode 100644 doc/2/core-classes/memory-storage/hgetall/snippets/hgetall-1.java delete mode 100644 doc/2/core-classes/memory-storage/hincrby/index.md delete mode 100644 doc/2/core-classes/memory-storage/hincrby/snippets/hincrby-1.java delete mode 100644 doc/2/core-classes/memory-storage/hincrbyfloat/index.md delete mode 100644 doc/2/core-classes/memory-storage/hincrbyfloat/snippets/hincrbyfloat-1.java delete mode 100644 doc/2/core-classes/memory-storage/hkeys/index.md delete mode 100644 doc/2/core-classes/memory-storage/hkeys/snippets/hkeys-1.java delete mode 100644 doc/2/core-classes/memory-storage/hlen/index.md delete mode 100644 doc/2/core-classes/memory-storage/hlen/snippets/hlen-1.java delete mode 100644 doc/2/core-classes/memory-storage/hmget/index.md delete mode 100644 doc/2/core-classes/memory-storage/hmget/snippets/hmget-1.java delete mode 100644 doc/2/core-classes/memory-storage/hmset/index.md delete mode 100644 doc/2/core-classes/memory-storage/hmset/snippets/hmset-1.java delete mode 100644 doc/2/core-classes/memory-storage/hscan/index.md delete mode 100644 doc/2/core-classes/memory-storage/hscan/snippets/hscan-1.java delete mode 100644 doc/2/core-classes/memory-storage/hset/index.md delete mode 100644 doc/2/core-classes/memory-storage/hset/snippets/hset-1.java delete mode 100644 doc/2/core-classes/memory-storage/hsetnx/index.md delete mode 100644 doc/2/core-classes/memory-storage/hsetnx/snippets/hsetnx-1.java delete mode 100644 doc/2/core-classes/memory-storage/hstrlen/index.md delete mode 100644 doc/2/core-classes/memory-storage/hstrlen/snippets/hstrlen-1.java delete mode 100644 doc/2/core-classes/memory-storage/hvals/index.md delete mode 100644 doc/2/core-classes/memory-storage/hvals/snippets/hvals-1.java delete mode 100644 doc/2/core-classes/memory-storage/incr/index.md delete mode 100644 doc/2/core-classes/memory-storage/incr/snippets/incr-1.java delete mode 100644 doc/2/core-classes/memory-storage/incrby/index.md delete mode 100644 doc/2/core-classes/memory-storage/incrby/snippets/incrby-1.java delete mode 100644 doc/2/core-classes/memory-storage/incrbyfloat/index.md delete mode 100644 doc/2/core-classes/memory-storage/incrbyfloat/snippets/incrbyfloat-1.java delete mode 100644 doc/2/core-classes/memory-storage/index.md delete mode 100644 doc/2/core-classes/memory-storage/keys/index.md delete mode 100644 doc/2/core-classes/memory-storage/keys/snippets/keys-1.java delete mode 100644 doc/2/core-classes/memory-storage/lindex/index.md delete mode 100644 doc/2/core-classes/memory-storage/lindex/snippets/lindex-1.java delete mode 100644 doc/2/core-classes/memory-storage/linsert/index.md delete mode 100644 doc/2/core-classes/memory-storage/linsert/snippets/linsert-1.java delete mode 100644 doc/2/core-classes/memory-storage/llen/index.md delete mode 100644 doc/2/core-classes/memory-storage/llen/snippets/llen-1.java delete mode 100644 doc/2/core-classes/memory-storage/lpop/index.md delete mode 100644 doc/2/core-classes/memory-storage/lpop/snippets/lpop-1.java delete mode 100644 doc/2/core-classes/memory-storage/lpush/index.md delete mode 100644 doc/2/core-classes/memory-storage/lpush/snippets/lpush-1.java delete mode 100644 doc/2/core-classes/memory-storage/lpushx/index.md delete mode 100644 doc/2/core-classes/memory-storage/lpushx/snippets/lpushx-1.java delete mode 100644 doc/2/core-classes/memory-storage/lrange/index.md delete mode 100644 doc/2/core-classes/memory-storage/lrange/snippets/lrange-1.java delete mode 100644 doc/2/core-classes/memory-storage/lrem/index.md delete mode 100644 doc/2/core-classes/memory-storage/lrem/snippets/lrem-1.java delete mode 100644 doc/2/core-classes/memory-storage/lset/index.md delete mode 100644 doc/2/core-classes/memory-storage/lset/snippets/lset-1.java delete mode 100644 doc/2/core-classes/memory-storage/ltrim/index.md delete mode 100644 doc/2/core-classes/memory-storage/ltrim/snippets/ltrim-1.java delete mode 100644 doc/2/core-classes/memory-storage/mget/index.md delete mode 100644 doc/2/core-classes/memory-storage/mget/snippets/mget-1.java delete mode 100644 doc/2/core-classes/memory-storage/mset/index.md delete mode 100644 doc/2/core-classes/memory-storage/mset/snippets/mset-1.java delete mode 100644 doc/2/core-classes/memory-storage/msetnx/index.md delete mode 100644 doc/2/core-classes/memory-storage/msetnx/snippets/msetnx-1.java delete mode 100644 doc/2/core-classes/memory-storage/object/index.md delete mode 100644 doc/2/core-classes/memory-storage/object/snippets/object-1.java delete mode 100644 doc/2/core-classes/memory-storage/persist/index.md delete mode 100644 doc/2/core-classes/memory-storage/persist/snippets/persist-1.java delete mode 100644 doc/2/core-classes/memory-storage/pexpire/index.md delete mode 100644 doc/2/core-classes/memory-storage/pexpire/snippets/pexpire-1.java delete mode 100644 doc/2/core-classes/memory-storage/pexpireat/index.md delete mode 100644 doc/2/core-classes/memory-storage/pexpireat/snippets/pexpireat-1.java delete mode 100644 doc/2/core-classes/memory-storage/pfadd/index.md delete mode 100644 doc/2/core-classes/memory-storage/pfadd/snippets/pfadd-1.java delete mode 100644 doc/2/core-classes/memory-storage/pfcount/index.md delete mode 100644 doc/2/core-classes/memory-storage/pfcount/snippets/pfcount-1.java delete mode 100644 doc/2/core-classes/memory-storage/pfmerge/index.md delete mode 100644 doc/2/core-classes/memory-storage/pfmerge/snippets/pfmerge-1.java delete mode 100644 doc/2/core-classes/memory-storage/ping/index.md delete mode 100644 doc/2/core-classes/memory-storage/ping/snippets/ping-1.java delete mode 100644 doc/2/core-classes/memory-storage/psetex/index.md delete mode 100644 doc/2/core-classes/memory-storage/psetex/snippets/psetex-1.java delete mode 100644 doc/2/core-classes/memory-storage/pttl/index.md delete mode 100644 doc/2/core-classes/memory-storage/pttl/snippets/pttl-1.java delete mode 100644 doc/2/core-classes/memory-storage/randomkey/index.md delete mode 100644 doc/2/core-classes/memory-storage/randomkey/snippets/randomkey-1.java delete mode 100644 doc/2/core-classes/memory-storage/rename/index.md delete mode 100644 doc/2/core-classes/memory-storage/rename/snippets/rename-1.java delete mode 100644 doc/2/core-classes/memory-storage/renamenx/index.md delete mode 100644 doc/2/core-classes/memory-storage/renamenx/snippets/renamenx-1.java delete mode 100644 doc/2/core-classes/memory-storage/rpop/index.md delete mode 100644 doc/2/core-classes/memory-storage/rpop/snippets/rpop-1.java delete mode 100644 doc/2/core-classes/memory-storage/rpoplpush/index.md delete mode 100644 doc/2/core-classes/memory-storage/rpoplpush/snippets/rpoplpush-1.java delete mode 100644 doc/2/core-classes/memory-storage/rpush/index.md delete mode 100644 doc/2/core-classes/memory-storage/rpush/snippets/rpush-1.java delete mode 100644 doc/2/core-classes/memory-storage/rpushx/index.md delete mode 100644 doc/2/core-classes/memory-storage/rpushx/snippets/rpushx-1.java delete mode 100644 doc/2/core-classes/memory-storage/sadd/index.md delete mode 100644 doc/2/core-classes/memory-storage/sadd/snippets/sadd-1.java delete mode 100644 doc/2/core-classes/memory-storage/scan/index.md delete mode 100644 doc/2/core-classes/memory-storage/scan/snippets/scan-1.java delete mode 100644 doc/2/core-classes/memory-storage/scard/index.md delete mode 100644 doc/2/core-classes/memory-storage/scard/snippets/scard-1.java delete mode 100644 doc/2/core-classes/memory-storage/sdiff/index.md delete mode 100644 doc/2/core-classes/memory-storage/sdiff/snippets/sdiff-1.java delete mode 100644 doc/2/core-classes/memory-storage/sdiffstore/index.md delete mode 100644 doc/2/core-classes/memory-storage/sdiffstore/snippets/sdiffstore-1.java delete mode 100644 doc/2/core-classes/memory-storage/set/index.md delete mode 100644 doc/2/core-classes/memory-storage/set/snippets/set-1.java delete mode 100644 doc/2/core-classes/memory-storage/setex/index.md delete mode 100644 doc/2/core-classes/memory-storage/setex/snippets/setex-1.java delete mode 100644 doc/2/core-classes/memory-storage/setnx/index.md delete mode 100644 doc/2/core-classes/memory-storage/setnx/snippets/setnx-1.java delete mode 100644 doc/2/core-classes/memory-storage/sinter/index.md delete mode 100644 doc/2/core-classes/memory-storage/sinter/snippets/sinter-1.java delete mode 100644 doc/2/core-classes/memory-storage/sinterstore/index.md delete mode 100644 doc/2/core-classes/memory-storage/sinterstore/snippets/sinterstore-1.java delete mode 100644 doc/2/core-classes/memory-storage/sismember/index.md delete mode 100644 doc/2/core-classes/memory-storage/sismember/snippets/sismember-1.java delete mode 100644 doc/2/core-classes/memory-storage/smembers/index.md delete mode 100644 doc/2/core-classes/memory-storage/smembers/snippets/smembers-1.java delete mode 100644 doc/2/core-classes/memory-storage/smove/index.md delete mode 100644 doc/2/core-classes/memory-storage/smove/snippets/smove-1.java delete mode 100644 doc/2/core-classes/memory-storage/sort/index.md delete mode 100644 doc/2/core-classes/memory-storage/sort/snippets/sort-1.java delete mode 100644 doc/2/core-classes/memory-storage/spop/index.md delete mode 100644 doc/2/core-classes/memory-storage/spop/snippets/spop-1.java delete mode 100644 doc/2/core-classes/memory-storage/srandmember/index.md delete mode 100644 doc/2/core-classes/memory-storage/srandmember/snippets/srandmember-1.java delete mode 100644 doc/2/core-classes/memory-storage/srem/index.md delete mode 100644 doc/2/core-classes/memory-storage/srem/snippets/srem-1.java delete mode 100644 doc/2/core-classes/memory-storage/sscan/index.md delete mode 100644 doc/2/core-classes/memory-storage/sscan/snippets/sscan-1.java delete mode 100644 doc/2/core-classes/memory-storage/strlen/index.md delete mode 100644 doc/2/core-classes/memory-storage/strlen/snippets/strlen-1.java delete mode 100644 doc/2/core-classes/memory-storage/sunion/index.md delete mode 100644 doc/2/core-classes/memory-storage/sunion/snippets/sunion-1.java delete mode 100644 doc/2/core-classes/memory-storage/sunionstore/index.md delete mode 100644 doc/2/core-classes/memory-storage/sunionstore/snippets/sunionstore-1.java delete mode 100644 doc/2/core-classes/memory-storage/time/index.md delete mode 100644 doc/2/core-classes/memory-storage/time/snippets/time-1.java delete mode 100644 doc/2/core-classes/memory-storage/touch/index.md delete mode 100644 doc/2/core-classes/memory-storage/touch/snippets/touch-1.java delete mode 100644 doc/2/core-classes/memory-storage/ttl/index.md delete mode 100644 doc/2/core-classes/memory-storage/ttl/snippets/ttl-1.java delete mode 100644 doc/2/core-classes/memory-storage/type/index.md delete mode 100644 doc/2/core-classes/memory-storage/type/snippets/type-1.java delete mode 100644 doc/2/core-classes/memory-storage/zadd/index.md delete mode 100644 doc/2/core-classes/memory-storage/zadd/snippets/zadd-1.java delete mode 100644 doc/2/core-classes/memory-storage/zcard/index.md delete mode 100644 doc/2/core-classes/memory-storage/zcard/snippets/zcard-1.java delete mode 100644 doc/2/core-classes/memory-storage/zcount/index.md delete mode 100644 doc/2/core-classes/memory-storage/zcount/snippets/zcount-1.java delete mode 100644 doc/2/core-classes/memory-storage/zincrby/index.md delete mode 100644 doc/2/core-classes/memory-storage/zincrby/snippets/zincrby-1.java delete mode 100644 doc/2/core-classes/memory-storage/zinterstore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zinterstore/snippets/zinterstore-1.java delete mode 100644 doc/2/core-classes/memory-storage/zlexcount/index.md delete mode 100644 doc/2/core-classes/memory-storage/zlexcount/snippets/zlexcount-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrange/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrange/snippets/zrange-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrangebylex/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrangebylex/snippets/zrangebylex-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrangebyscore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrangebyscore/snippets/zrangebyscore-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrank/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrank/snippets/zrank-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrem/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrem/snippets/zrem-1.java delete mode 100644 doc/2/core-classes/memory-storage/zremrangebylex/index.md delete mode 100644 doc/2/core-classes/memory-storage/zremrangebylex/snippets/zremrangebylex-1.java delete mode 100644 doc/2/core-classes/memory-storage/zremrangebyrank/index.md delete mode 100644 doc/2/core-classes/memory-storage/zremrangebyrank/snippets/zremrangebyrank-1.java delete mode 100644 doc/2/core-classes/memory-storage/zremrangebyscore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zremrangebyscore/snippets/zremrangebyscore-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrevrange/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrevrange/snippets/zrevrange-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrevrangebylex/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrevrangebylex/snippets/zrevrangebylex-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrevrangebyscore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrevrangebyscore/snippets/zrevrangebyscore-1.java delete mode 100644 doc/2/core-classes/memory-storage/zrevrank/index.md delete mode 100644 doc/2/core-classes/memory-storage/zrevrank/snippets/zrevrank-1.java delete mode 100644 doc/2/core-classes/memory-storage/zscan/index.md delete mode 100644 doc/2/core-classes/memory-storage/zscan/snippets/zscan-1.java delete mode 100644 doc/2/core-classes/memory-storage/zscore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zscore/snippets/zscore-1.java delete mode 100644 doc/2/core-classes/memory-storage/zunionstore/index.md delete mode 100644 doc/2/core-classes/memory-storage/zunionstore/snippets/zunionstore-1.java delete mode 100644 doc/2/core-classes/profile/add-policy/index.md delete mode 100644 doc/2/core-classes/profile/add-policy/snippets/add-policy-1.java delete mode 100644 doc/2/core-classes/profile/constructor/index.md delete mode 100644 doc/2/core-classes/profile/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/profile/delete/index.md delete mode 100644 doc/2/core-classes/profile/delete/snippets/delete-1.java delete mode 100644 doc/2/core-classes/profile/get-policies/index.md delete mode 100644 doc/2/core-classes/profile/get-policies/snippets/get-policies-1.java delete mode 100644 doc/2/core-classes/profile/index.md delete mode 100644 doc/2/core-classes/profile/save/index.md delete mode 100644 doc/2/core-classes/profile/save/snippets/save-1.java delete mode 100644 doc/2/core-classes/profile/set-content/index.md delete mode 100644 doc/2/core-classes/profile/set-content/snippets/set-content-1.java delete mode 100644 doc/2/core-classes/profile/set-policies/index.md delete mode 100644 doc/2/core-classes/profile/set-policies/snippets/set-policies-1.java delete mode 100644 doc/2/core-classes/profile/update/index.md delete mode 100644 doc/2/core-classes/profile/update/snippets/update-1.java delete mode 100644 doc/2/core-classes/role/constructor/index.md delete mode 100644 doc/2/core-classes/role/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/role/delete/index.md delete mode 100644 doc/2/core-classes/role/delete/snippets/delete-1.java delete mode 100644 doc/2/core-classes/role/index.md delete mode 100644 doc/2/core-classes/role/save/index.md delete mode 100644 doc/2/core-classes/role/save/snippets/save-1.java delete mode 100644 doc/2/core-classes/role/set-content/index.md delete mode 100644 doc/2/core-classes/role/set-content/snippets/set-content-1.java delete mode 100644 doc/2/core-classes/role/update/index.md delete mode 100644 doc/2/core-classes/role/update/snippets/update-1.java delete mode 100644 doc/2/core-classes/room/constructor/index.md delete mode 100644 doc/2/core-classes/room/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/room/count/index.md delete mode 100644 doc/2/core-classes/room/count/snippets/count-1.java delete mode 100644 doc/2/core-classes/room/index.md delete mode 100644 doc/2/core-classes/room/renew/index.md delete mode 100644 doc/2/core-classes/room/renew/snippets/renew-1.java delete mode 100644 doc/2/core-classes/room/set-headers/index.md delete mode 100644 doc/2/core-classes/room/set-headers/snippets/set-headers-1.java delete mode 100644 doc/2/core-classes/room/unsubscribe/index.md delete mode 100644 doc/2/core-classes/room/unsubscribe/snippets/unsubscribe-1.java delete mode 100644 doc/2/core-classes/search-result/constructor/index.md delete mode 100644 doc/2/core-classes/search-result/fetch-next/index.md delete mode 100644 doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-1.java delete mode 100644 doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-2.java delete mode 100644 doc/2/core-classes/search-result/index.md delete mode 100644 doc/2/core-classes/security/constructor/index.md delete mode 100644 doc/2/core-classes/security/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/security/create-credentials/index.md delete mode 100644 doc/2/core-classes/security/create-credentials/snippets/create-credentials-1.java delete mode 100644 doc/2/core-classes/security/create-profile/index.md delete mode 100644 doc/2/core-classes/security/create-profile/snippets/create-profile-1.java delete mode 100644 doc/2/core-classes/security/create-restricted-user/index.md delete mode 100644 doc/2/core-classes/security/create-restricted-user/snippets/create-restricted-user-1.java delete mode 100644 doc/2/core-classes/security/create-role/index.md delete mode 100644 doc/2/core-classes/security/create-role/snippets/create-role-1.java delete mode 100644 doc/2/core-classes/security/create-user/index.md delete mode 100644 doc/2/core-classes/security/create-user/snippets/create-user-1.java delete mode 100644 doc/2/core-classes/security/delete-credentials/index.md delete mode 100644 doc/2/core-classes/security/delete-credentials/snippets/delete-credentials-1.java delete mode 100644 doc/2/core-classes/security/delete-profile/index.md delete mode 100644 doc/2/core-classes/security/delete-profile/snippets/delete-profile-1.java delete mode 100644 doc/2/core-classes/security/delete-role/index.md delete mode 100644 doc/2/core-classes/security/delete-role/snippets/delete-role-1.java delete mode 100644 doc/2/core-classes/security/delete-user/index.md delete mode 100644 doc/2/core-classes/security/delete-user/snippets/delete-user-1.java delete mode 100644 doc/2/core-classes/security/fetch-profile/index.md delete mode 100644 doc/2/core-classes/security/fetch-profile/snippets/fetch-profile-1.java delete mode 100644 doc/2/core-classes/security/fetch-role/index.md delete mode 100644 doc/2/core-classes/security/fetch-role/snippets/fetch-role-1.java delete mode 100644 doc/2/core-classes/security/fetch-user/index.md delete mode 100644 doc/2/core-classes/security/fetch-user/snippets/fetch-user-1.java delete mode 100644 doc/2/core-classes/security/get-all-credential-fields/index.md delete mode 100644 doc/2/core-classes/security/get-all-credential-fields/snippets/get-all-credential-fields-1.java delete mode 100644 doc/2/core-classes/security/get-credentials-fields/index.md delete mode 100644 doc/2/core-classes/security/get-credentials-fields/snippets/get-credentials-fields-1.java delete mode 100644 doc/2/core-classes/security/get-credentials/index.md delete mode 100644 doc/2/core-classes/security/get-credentials/snippets/get-credentials-1.java delete mode 100644 doc/2/core-classes/security/get-user-rights/index.md delete mode 100644 doc/2/core-classes/security/get-user-rights/snippets/get-user-rights-1.java delete mode 100644 doc/2/core-classes/security/has-credentials/index.md delete mode 100644 doc/2/core-classes/security/has-credentials/snippets/has-credentials-1.java delete mode 100644 doc/2/core-classes/security/index.md delete mode 100644 doc/2/core-classes/security/is-action-allowed/index.md delete mode 100644 doc/2/core-classes/security/is-action-allowed/snippets/is-action-allowed-1.java delete mode 100644 doc/2/core-classes/security/profile/index.md delete mode 100644 doc/2/core-classes/security/profile/snippets/profile-1.java delete mode 100644 doc/2/core-classes/security/replace-user/index.md delete mode 100644 doc/2/core-classes/security/replace-user/snippets/replace-user-1.java delete mode 100644 doc/2/core-classes/security/role/index.md delete mode 100644 doc/2/core-classes/security/role/snippets/role-1.java delete mode 100644 doc/2/core-classes/security/scroll-profiles/index.md delete mode 100644 doc/2/core-classes/security/scroll-profiles/snippets/scroll-profiles-1.java delete mode 100644 doc/2/core-classes/security/scroll-users/index.md delete mode 100644 doc/2/core-classes/security/scroll-users/snippets/scroll-users-1.java delete mode 100644 doc/2/core-classes/security/search-profiles/index.md delete mode 100644 doc/2/core-classes/security/search-profiles/snippets/search-profiles-1.java delete mode 100644 doc/2/core-classes/security/search-roles/index.md delete mode 100644 doc/2/core-classes/security/search-roles/snippets/search-roles-1.java delete mode 100644 doc/2/core-classes/security/search-users/index.md delete mode 100644 doc/2/core-classes/security/search-users/snippets/search-users-1.java delete mode 100644 doc/2/core-classes/security/update-credentials/index.md delete mode 100644 doc/2/core-classes/security/update-credentials/snippets/update-credentials-1.java delete mode 100644 doc/2/core-classes/security/update-profile/index.md delete mode 100644 doc/2/core-classes/security/update-profile/snippets/update-profile-1.java delete mode 100644 doc/2/core-classes/security/update-role/index.md delete mode 100644 doc/2/core-classes/security/update-role/snippets/update-role-1.java delete mode 100644 doc/2/core-classes/security/update-user/index.md delete mode 100644 doc/2/core-classes/security/update-user/snippets/update-user-1.java delete mode 100644 doc/2/core-classes/security/user/index.md delete mode 100644 doc/2/core-classes/security/user/snippets/user-1.java delete mode 100644 doc/2/core-classes/security/validate-credentials/index.md delete mode 100644 doc/2/core-classes/security/validate-credentials/snippets/validate-credentials-1.java delete mode 100644 doc/2/core-classes/user/add-profile/index.md delete mode 100644 doc/2/core-classes/user/add-profile/snippets/add-profile-1.java delete mode 100644 doc/2/core-classes/user/constructor/index.md delete mode 100644 doc/2/core-classes/user/constructor/snippets/constructor-1.java delete mode 100644 doc/2/core-classes/user/create/index.md delete mode 100644 doc/2/core-classes/user/create/snippets/create-1.java delete mode 100644 doc/2/core-classes/user/delete/index.md delete mode 100644 doc/2/core-classes/user/delete/snippets/delete-1.java delete mode 100644 doc/2/core-classes/user/get-profileids/index.md delete mode 100644 doc/2/core-classes/user/get-profileids/snippets/get-profileids-1.java delete mode 100644 doc/2/core-classes/user/get-profiles/index.md delete mode 100644 doc/2/core-classes/user/get-profiles/snippets/get-profiles-1.java delete mode 100644 doc/2/core-classes/user/index.md delete mode 100644 doc/2/core-classes/user/replace/index.md delete mode 100644 doc/2/core-classes/user/replace/snippets/replace-1.java delete mode 100644 doc/2/core-classes/user/save-restricted/index.md delete mode 100644 doc/2/core-classes/user/save-restricted/snippets/save-restricted-1.java delete mode 100644 doc/2/core-classes/user/save/index.md delete mode 100644 doc/2/core-classes/user/save/snippets/save-1.java delete mode 100644 doc/2/core-classes/user/set-content/index.md delete mode 100644 doc/2/core-classes/user/set-content/snippets/set-content-1.java delete mode 100644 doc/2/core-classes/user/set-credentials/index.md delete mode 100644 doc/2/core-classes/user/set-credentials/snippets/set-credentials-1.java delete mode 100644 doc/2/core-classes/user/set-profiles/index.md delete mode 100644 doc/2/core-classes/user/set-profiles/snippets/set-profiles-1.java delete mode 100644 doc/2/core-classes/user/update/index.md delete mode 100644 doc/2/core-classes/user/update/snippets/update-1.java delete mode 100644 doc/2/essentials/error-handling/index.md delete mode 100644 doc/2/essentials/error-handling/snippets/handling-errors-1.java delete mode 100644 doc/2/essentials/events/index.md delete mode 100644 doc/2/essentials/index.md delete mode 100644 doc/2/essentials/offline-tools/index.md delete mode 100644 doc/2/essentials/realtime-notifications/index.md delete mode 100644 doc/2/index.md diff --git a/doc/2/.vuepress b/doc/2/.vuepress deleted file mode 120000 index c7af454d..00000000 --- a/doc/2/.vuepress +++ /dev/null @@ -1 +0,0 @@ -../framework/src/.vuepress \ No newline at end of file diff --git a/doc/2/core-classes/collection-mapping/apply/index.md b/doc/2/core-classes/collection-mapping/apply/index.md deleted file mode 100644 index 8dab0698..00000000 --- a/doc/2/core-classes/collection-mapping/apply/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: apply -description: CollectionMapping:apply ---- - -# apply - -Applies the new mapping to the collection. - ---- - -## apply([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns this `CollectionMapping` object to allow chaining. - ---- - -## Callback Response - -Returns the updated `CollectionMapping` object. - -## Usage - -<<< ./snippets/apply-1.java diff --git a/doc/2/core-classes/collection-mapping/apply/snippets/apply-1.java b/doc/2/core-classes/collection-mapping/apply/snippets/apply-1.java deleted file mode 100644 index 0fc3a79e..00000000 --- a/doc/2/core-classes/collection-mapping/apply/snippets/apply-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -dataMapping.apply(new ResponseListener() { - @Override - public void onSuccess(CollectionMapping object) { - // called once the mapping action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/collection-mapping/constructor/index.md b/doc/2/core-classes/collection-mapping/constructor/index.md deleted file mode 100644 index 5627fb6a..00000000 --- a/doc/2/core-classes/collection-mapping/constructor/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -code: true -type: page -title: constructor -description: CollectionMapping:constructor -order: 1 ---- - -# CollectionMapping - -When creating a new collection in the persistent data storage layer, Kuzzle uses a default mapping. -This means that, by default, you won't be able to exploit the full capabilities of our persistent data storage layer (currently handled by [ElasticSearch](https://www.elastic.co/products/elasticsearch)), and your searches may suffer from below-average performance, depending on the amount of data you stored in a collection and the complexity of your database. - -The CollectionMapping object allows you to get the current mapping in a collection and to modify it if necessary. - -:::info -Once a field mapping has been set, it cannot be removed without reconstructing the collection. -::: - ---- - -## CollectionMapping(Collection, [mapping]) - -| Arguments | Type | Description | -| ------------ | ---------------------------------------------------- | --------------------------------- | -| `Collection` | [Collection](/sdk/java/2/core-classes/collection) | An instantiated Collection object | -| `mapping` | JSON Object | Optional mapping | - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ----------- | --------------------------------------------- | ------- | -| `headers` | JSON Object | Common headers for all sent documents. | get/set | -| `mapping` | object | Easy-to-understand list of mappings per field | get/set | - -**Note:** the `headers` property is inherited from the provided [Collection](/sdk/java/2/core-classes/collection) object and can be overrided - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/collection-mapping/constructor/snippets/constructor-1.java b/doc/2/core-classes/collection-mapping/constructor/snippets/constructor-1.java deleted file mode 100644 index 179c1145..00000000 --- a/doc/2/core-classes/collection-mapping/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,9 +0,0 @@ - -CollectionMapping dataMapping = new CollectionMapping(dataCollection); - -JSONObject mapping = new JSONObject(); -JSONObject type = new JSONObject(); -type.put("type", "string"); -mapping.put("foo", type); - -CollectionMapping dataMapping = new CollectionMapping(dataCollection, mapping); diff --git a/doc/2/core-classes/collection-mapping/index.md b/doc/2/core-classes/collection-mapping/index.md deleted file mode 100644 index e2a17cc9..00000000 --- a/doc/2/core-classes/collection-mapping/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: CollectionMapping -description: CollectionMapping documentation ---- diff --git a/doc/2/core-classes/collection-mapping/refresh/index.md b/doc/2/core-classes/collection-mapping/refresh/index.md deleted file mode 100644 index 1ef27ec2..00000000 --- a/doc/2/core-classes/collection-mapping/refresh/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: refresh -description: CollectionMapping:refresh ---- - -# refresh - -Instantiates a new CollectionMapping object with an up-to-date content. - ---- - -## refresh([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the updated `CollectionMapping` object. - -## Usage - -<<< ./snippets/refresh-1.java diff --git a/doc/2/core-classes/collection-mapping/refresh/snippets/refresh-1.java b/doc/2/core-classes/collection-mapping/refresh/snippets/refresh-1.java deleted file mode 100644 index 6c562b46..00000000 --- a/doc/2/core-classes/collection-mapping/refresh/snippets/refresh-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -dataMapping.refresh(new ResponseListener() { - @Override - public void onSuccess(CollectionMapping object) { - // called once the mapping has been retrieved from Kuzzle - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/collection-mapping/set-headers/index.md b/doc/2/core-classes/collection-mapping/set-headers/index.md deleted file mode 100644 index b081b8b0..00000000 --- a/doc/2/core-classes/collection-mapping/set-headers/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -code: true -type: page -title: setHeaders -description: CollectionMapping:setHeaders ---- - -# setHeaders - -This is a helper function returning itself, allowing to easily chain calls. - ---- - -## setHeaders(content, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `content` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return value - -Returns this `CollectionMapping` object to allow chaining. - -## Usage - -<<< ./snippets/set-headers-1.java diff --git a/doc/2/core-classes/collection-mapping/set-headers/snippets/set-headers-1.java b/doc/2/core-classes/collection-mapping/set-headers/snippets/set-headers-1.java deleted file mode 100644 index 4ba87e2c..00000000 --- a/doc/2/core-classes/collection-mapping/set-headers/snippets/set-headers-1.java +++ /dev/null @@ -1,4 +0,0 @@ - -JSONObject headers = new JSONObject(); -headers.put("someContent", "someValue"); -dataMapping.setHeaders(headers, true); diff --git a/doc/2/core-classes/collection-mapping/set/index.md b/doc/2/core-classes/collection-mapping/set/index.md deleted file mode 100644 index 7c8e9199..00000000 --- a/doc/2/core-classes/collection-mapping/set/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -code: true -type: page -title: set -description: CollectionMapping:set ---- - -# set - -Adds or updates a field mapping. - -:::info -Changes made by this function won't be applied until you call the `apply` method -::: - ---- - -## set(field, mapping) - -| Arguments | Type | Description | -| --------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `field` | string | Name of the field from which the mapping is to be added or updated | -| `mapping` | JSON Object | Mapping for this field, following the [Elasticsearch Mapping format](https://www.elastic.co/guide/en/elasticsearch/reference/5.x/mapping.html) | - ---- - -## Return Value - -Returns this `CollectionMapping` object to allow chaining. - -## Usage - -<<< ./snippets/set-1.java diff --git a/doc/2/core-classes/collection-mapping/set/snippets/set-1.java b/doc/2/core-classes/collection-mapping/set/snippets/set-1.java deleted file mode 100644 index 8631d14a..00000000 --- a/doc/2/core-classes/collection-mapping/set/snippets/set-1.java +++ /dev/null @@ -1,7 +0,0 @@ - -JSONObject mapping = new JSONObject(); -mapping.put("type", "string"); -mapping.put("index", "analyzed"); -mapping.put("null_value", ""); - -dataMapping.set("field", mapping); diff --git a/doc/2/core-classes/collection/collection-mapping/index.md b/doc/2/core-classes/collection/collection-mapping/index.md deleted file mode 100644 index 68e15885..00000000 --- a/doc/2/core-classes/collection/collection-mapping/index.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -code: true -type: page -title: collectionMapping -description: Collection:collectionMapping ---- - -# collectionMapping - -Creates a new [CollectionMapping](/sdk/java/2/core-classes/collection-mapping) object, using its constructor. - ---- - -## collectionMapping([mapping]) - -| Arguments | Type | Description | -| --------- | ----------- | ---------------- | -| `mapping` | JSON Object | Optional mapping | - ---- - -## Return Value - -Returns the newly created [CollectionMapping](/sdk/java/2/core-classes/collection-mapping) object. - -## Usage - -<<< ./snippets/collection-mapping-1.java diff --git a/doc/2/core-classes/collection/collection-mapping/snippets/collection-mapping-1.java b/doc/2/core-classes/collection/collection-mapping/snippets/collection-mapping-1.java deleted file mode 100644 index 2205594c..00000000 --- a/doc/2/core-classes/collection/collection-mapping/snippets/collection-mapping-1.java +++ /dev/null @@ -1,15 +0,0 @@ - -CollectionMapping dataMapping = kuzzle - .collection("collection", "index") - .collectionMapping(new JSONObject().put("someFiled", new JSONObject().put("type", "string").put("index", "analyzed")) - .apply(new ResponseListener() { - @Override - public void onSuccess(CollectionMapping object) { - // called once the mapping action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/constructor/index.md b/doc/2/core-classes/collection/constructor/index.md deleted file mode 100644 index 4506e554..00000000 --- a/doc/2/core-classes/collection/constructor/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Collection:constructor -order: 1 ---- - -# Collection - -In Kuzzle, you manipulate documents and subscriptions, both related to collections. - -A collection is a set of data managed by Kuzzle. It acts like a data table for persistent documents, or like a room for pub/sub messages. - ---- - -## Collection(kuzzle, collection, index) - -| Arguments | Type | Description | -| ------------ | ------ | ------------------------------------------------------ | -| `kuzzle` | object | Kuzzle object | -| `collection` | string | The name of the collection you want to manipulate | -| `index` | string | Name of the index containing the collection | - -**Note:** We recommend you instantiate a Collection object by calling [Kuzzle.collection](/sdk/java/2/core-classes/kuzzle/collection) rather than using the constructor directly - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ------ | -------------------------------------------------------- | ------- | -| `collection` | string | The name of the collection handled by this instance | get | -| `index` | object | Name of the index containing the collection | get | -| `headers` | object | Headers for all sent documents. | get/set | -| `kuzzle` | object | linked Kuzzle instance | get | - -**Note:** the `headers` property is inherited from the main `Kuzzle` object and can be overrided - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/collection/constructor/snippets/constructor-1.java b/doc/2/core-classes/collection/constructor/snippets/constructor-1.java deleted file mode 100644 index 6a97b6a3..00000000 --- a/doc/2/core-classes/collection/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,2 +0,0 @@ - - Collection myCollection = new Collection(kuzzle, "my-collection", "my-index"); diff --git a/doc/2/core-classes/collection/count/index.md b/doc/2/core-classes/collection/count/index.md deleted file mode 100644 index 631d4abc..00000000 --- a/doc/2/core-classes/collection/count/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: count -description: Collection:count ---- - -# count - -Returns the number of documents matching the provided set of filters. - -:::info -There is a small delay between the time a document is created and its availability in our search layer (usually a couple of seconds). That means that a document that was just created might not be immediately returned by this function. -::: - ---- - -## count(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- | -| `filters` | JSON Object | Filters in [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/5.x/query-dsl.html) format | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a count for the number of document matches as an `integer`. - -## Usage - -<<< ./snippets/count-1.java - -> Callback response: - -```json -12 -``` diff --git a/doc/2/core-classes/collection/count/snippets/count-1.java b/doc/2/core-classes/collection/count/snippets/count-1.java deleted file mode 100644 index f9f9ea2a..00000000 --- a/doc/2/core-classes/collection/count/snippets/count-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject filters = new JSONObject(); - -kuzzle - .collection("collection", "index") - .count(filters, new ResponseListener() { - @Override - public void onSuccess(Integer object) { - // Handle success - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/create-document/index.md b/doc/2/core-classes/collection/create-document/index.md deleted file mode 100644 index dcc286e3..00000000 --- a/doc/2/core-classes/collection/create-document/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -code: true -type: page -title: createDocument -description: Collection:createDocument ---- - -# createDocument - -Create a new document in Kuzzle and instantiate a [Document](/sdk/java/2/core-classes/document) object. - ---- - -## createDocument(Document, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------- | -| `Document` | object | [Document](/sdk/java/2/core-classes/document) object | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## createDocument([id], content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------- | -| `id` | string | Optional document identifier | -| `content` | JSON object | Content of the document to create | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | -| `ifExist` | string | If the same document already exists: resolves to an `error`. Replaces the existing document if set to `replace` | `false` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a [Document](/sdk/java/2/core-classes/document) object containing the newly created document. - -## Usage - -<<< ./snippets/create-document-1.java diff --git a/doc/2/core-classes/collection/create-document/snippets/create-document-1.java b/doc/2/core-classes/collection/create-document/snippets/create-document-1.java deleted file mode 100644 index 7f4681c6..00000000 --- a/doc/2/core-classes/collection/create-document/snippets/create-document-1.java +++ /dev/null @@ -1,22 +0,0 @@ - -Document myDocument = new Document(collection); -myDocument.setContent("title", "foo"); -myDocument.setContent("content", "bar"); - -Options opts = new Options(); -opts.setIfExist = "replace"; - -kuzzle - .collection("collection", "index") - .createDocument(myDocument, new ResponseListener() { - @Override - public void onSuccess(Document object) { - // callback called once the create action has been completed - // => the result is a Document object - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/create/index.md b/doc/2/core-classes/collection/create/index.md deleted file mode 100644 index 75a38919..00000000 --- a/doc/2/core-classes/collection/create/index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -code: true -type: page -title: create -description: Collection:create ---- - -# create - -Creates a new [collection](/core/1/guides/essentials/store-access-data) in the provided `index`. - - - -You can also provide an optional data mapping that allow you to exploit the full capabilities of our -persistent data storage layer, [ElasticSearch](https://www.elastic.co/products/elasticsearch) (check here the [mapping capabilities of ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/mapping.html)). - -This method will only update the mapping if the collection already exists. - ---- - -## create([mapping], [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------- | -| `mapping` | JSON Object | Optional data mapping | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Ralue - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. - -## Usage - -<<< ./snippets/create-1.java - -> Callback response: - -```json -{ - "status": 200, - "error": null, - "requestId": "", - "controller": "collection", - "action": "create", - "collection": "", - "index": "index", - "volatile": null, - "result": { - "acknowledged": true - } -} -``` diff --git a/doc/2/core-classes/collection/create/snippets/create-1.java b/doc/2/core-classes/collection/create/snippets/create-1.java deleted file mode 100644 index 137e24a4..00000000 --- a/doc/2/core-classes/collection/create/snippets/create-1.java +++ /dev/null @@ -1,26 +0,0 @@ - -// Optional: a mapping can be provided and will be -// applied when the collection is created -JSONObject mapping = new JSONObject() - .put("properties", new JSONObject() - .put("field1", new JSONObject().put("type", "")) - .put("field2", new JSONObject().put("type", "")) - ); - -kuzzle - .collection("collection", "index") - .create(mapping, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the create operation has completed - // => the result is a JSON object containing the raw Kuzzle response: - // { - // acknowledged: true - // } - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/delete-document/index.md b/doc/2/core-classes/collection/delete-document/index.md deleted file mode 100644 index 27e216a8..00000000 --- a/doc/2/core-classes/collection/delete-document/index.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -code: true -type: page -title: deleteDocument -description: Collection:deleteDocument ---- - -# deleteDocument - -Delete a stored document, or all stored documents matching a search filter. - -:::info -There is a small delay between the time a document is deleted and it being reflected in the search layer (usually a couple of seconds). That means that a document that was just deleted might still be returned by this function. -::: - ---- - -## deleteDocument(documentId, [options], [callback]) - -| Arguments | Type | Description | -| ------------ | ----------- | -------------------------- | -| `documentId` | string | Unique document identifier | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## deleteDocument(filters, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- | -| `filters` | JSON object | Filters in [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/5.x/query-dsl.html) format | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns an `array` containing the ids of the deleted documents. - -## Usage - -<<< ./snippets/delete-document-1.java - -> Callback response: - -```json -["AVCoeBkimsySTKTfa8AX"] -``` diff --git a/doc/2/core-classes/collection/delete-document/snippets/delete-document-1.java b/doc/2/core-classes/collection/delete-document/snippets/delete-document-1.java deleted file mode 100644 index 9bd203ba..00000000 --- a/doc/2/core-classes/collection/delete-document/snippets/delete-document-1.java +++ /dev/null @@ -1,36 +0,0 @@ - -// Deleting one document -kuzzle - .collection("collection", "index") - .deleteDocument("document unique ID", new ResponseListener() { - @Override - public void onSuccess(String object) { - // The resulting string contains the deleted document ID - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); - -// Deleting multiple documents -JSONObject equalsFilter = new JSONObject() - .put("filter", new JSONObject() - .put("equals", - new JSONObject().put("title", "foo") - )); - -kuzzle - .collection("collection", "index") - .deleteDocument(equalsFilter, new ResponseListener() { - @Override - public void onSuccess(String[] object) { - // The resulting object contains the list of deleted document IDs - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/delete-specifications/index.md b/doc/2/core-classes/collection/delete-specifications/index.md deleted file mode 100644 index bad83f54..00000000 --- a/doc/2/core-classes/collection/delete-specifications/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: deleteSpecifications -description: Collection:deleteSpecifications ---- - -# deleteSpecifications - -Delete specifications linked to the collection object. - ---- - -## deleteSpecifications([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer indexation to return (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - -## Usage - -<<< ./snippets/delete-specifications-1.java - -> Callback response: - -```json -{ - "acknowledged": true -} -``` diff --git a/doc/2/core-classes/collection/delete-specifications/snippets/delete-specifications-1.java b/doc/2/core-classes/collection/delete-specifications/snippets/delete-specifications-1.java deleted file mode 100644 index 5f824b96..00000000 --- a/doc/2/core-classes/collection/delete-specifications/snippets/delete-specifications-1.java +++ /dev/null @@ -1,15 +0,0 @@ - -// Deleting one document -kuzzle - .collection("collection", "index") - .deleteSpecifications(new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/document/index.md b/doc/2/core-classes/collection/document/index.md deleted file mode 100644 index 22b8c904..00000000 --- a/doc/2/core-classes/collection/document/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: document -description: Collection:document ---- - -# document - -Creates a new [Document](/sdk/java/2/core-classes/document) object, using its constructor. - ---- - -## document([id], [content]) - -| Arguments | Type | Description | -| --------- | ----------- | --------------------------- | -| `id` | string | Optional document unique ID | -| `content` | JSON object | Optional document content | - ---- - -## Return Value - -Returns the newly created [Document](/sdk/java/2/core-classes/document) object. - -## Usage - -<<< ./snippets/document-1.java diff --git a/doc/2/core-classes/collection/document/snippets/document-1.java b/doc/2/core-classes/collection/document/snippets/document-1.java deleted file mode 100644 index 26a9c121..00000000 --- a/doc/2/core-classes/collection/document/snippets/document-1.java +++ /dev/null @@ -1,5 +0,0 @@ - -Document document = kuzzle - .collection("collection", "index") - .document("id", new JSONObject().put("some", "content")) - .save(); diff --git a/doc/2/core-classes/collection/fetch-document/index.md b/doc/2/core-classes/collection/fetch-document/index.md deleted file mode 100644 index f9b1edbd..00000000 --- a/doc/2/core-classes/collection/fetch-document/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: fetchDocument -description: Collection:fetchDocument ---- - -# fetchDocument - -Retrieves a single stored document using its unique document ID, and returns it as a [Document](/sdk/java/2/core-classes/document) object. - ---- - -## fetchDocument(documentId, [options], callback) - -| Arguments | Type | Description | -| ------------ | ----------- | ------------------------------ | -| `documentId` | string | Unique document identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a [Document](/sdk/java/2/core-classes/document) object. - -## Usage - -<<< ./snippets/fetch-document-1.java diff --git a/doc/2/core-classes/collection/fetch-document/snippets/fetch-document-1.java b/doc/2/core-classes/collection/fetch-document/snippets/fetch-document-1.java deleted file mode 100644 index 1c209d32..00000000 --- a/doc/2/core-classes/collection/fetch-document/snippets/fetch-document-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .collection("collection", "index") - .fetchDocument("documentId", new ResponseListener() { - @Override - public void onSuccess(Document object) { - // result is a Document object - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/get-mapping/index.md b/doc/2/core-classes/collection/get-mapping/index.md deleted file mode 100644 index 0f9831e2..00000000 --- a/doc/2/core-classes/collection/get-mapping/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: getMapping -description: Collection:getMapping ---- - -# getMapping - -Retrieves the current mapping of this collection as a [CollectionMapping](/sdk/java/2/core-classes/collection-mapping) object. - ---- - -## getMapping([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a [CollectionMapping](/sdk/java/2/core-classes/collection-mapping) object. - -## Usage - -<<< ./snippets/get-mapping-1.java diff --git a/doc/2/core-classes/collection/get-mapping/snippets/get-mapping-1.java b/doc/2/core-classes/collection/get-mapping/snippets/get-mapping-1.java deleted file mode 100644 index 0fdd7119..00000000 --- a/doc/2/core-classes/collection/get-mapping/snippets/get-mapping-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .collection("collection", "index") - .getMapping(new ResponseListener() { - @Override - public void onSuccess(CollectionMapping object) { - // result is a CollectionMapping object - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/get-specifications/index.md b/doc/2/core-classes/collection/get-specifications/index.md deleted file mode 100644 index b1925896..00000000 --- a/doc/2/core-classes/collection/get-specifications/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: getSpecifications -description: Collection:getSpecifications ---- - -# getSpecifications - -Retrieves the specifications linked to the collection object. - ---- - -## getSpecifications([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - -## Usage - -<<< ./snippets/get-specifications-1.java - -> Callback response - -```json -{ - "validation": { - "strict": "true", - "fields": { - "foo": { - "mandatory": "true", - "type": "string", - "defaultValue": "bar" - } - } - }, - "index": "index", - "collection": "collection" -} -``` diff --git a/doc/2/core-classes/collection/get-specifications/snippets/get-specifications-1.java b/doc/2/core-classes/collection/get-specifications/snippets/get-specifications-1.java deleted file mode 100644 index f2cccbd8..00000000 --- a/doc/2/core-classes/collection/get-specifications/snippets/get-specifications-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .collection("collection", "index") - .getSpecifications(new ResponseListener() { - @Override - public void onSuccess(JSONObject specifications) { - // specifications is a JSONObject - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/index.md b/doc/2/core-classes/collection/index.md deleted file mode 100644 index a0b54cf6..00000000 --- a/doc/2/core-classes/collection/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Collection -description: Collection documentation ---- diff --git a/doc/2/core-classes/collection/mcreate-document/index.md b/doc/2/core-classes/collection/mcreate-document/index.md deleted file mode 100644 index f488edfb..00000000 --- a/doc/2/core-classes/collection/mcreate-document/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: mcreateDocument -description: Collection:mcreateDocument ---- - -# mCreateDocument - -Create the input [Documents](/sdk/java/2/core-classes/document). - ---- - -## mCreateDocument(documents, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | ------------------------------------------------------------------- | -| `documents` | Document[] | Array of [Document](/sdk/java/2/core-classes/document) to create | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. -Can return a 206 partial error in cases where some documents could not be created. - -## Usage - -<<< ./snippets/mcreate-document-1.java - -> Callback response: - -```json -{ - "hits": [{ "first": "document" }, { "second": "document" }], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/mcreate-document/snippets/mcreate-document-1.java b/doc/2/core-classes/collection/mcreate-document/snippets/mcreate-document-1.java deleted file mode 100644 index 548fe332..00000000 --- a/doc/2/core-classes/collection/mcreate-document/snippets/mcreate-document-1.java +++ /dev/null @@ -1,25 +0,0 @@ - -Document firstDocument = new Document(collection, "doc1"); -firstDocument.setContent("title", "foo"); -firstDocument.setContent("content", "bar"); - -Document secondDocument = new Document(collection, "doc2"); -secondDocument.setContent("title", "foo"); -secondDocument.setContent("content", "bar"); - -Document[] documents = new Document[]{firstDocument, secondDocument}; - -kuzzle - .collection("collection", "index") - .mCreateDocument(documents, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mCreate operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/mcreate-or-replace-document/index.md b/doc/2/core-classes/collection/mcreate-or-replace-document/index.md deleted file mode 100644 index cec209e6..00000000 --- a/doc/2/core-classes/collection/mcreate-or-replace-document/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: mcreateOrReplaceDocument -description: Collection:mcreateOrReplaceDocument ---- - -# mCreateOrReplaceDocument - -Create or replace the input [Documents](/sdk/java/2/core-classes/document). - ---- - -## mCreateOrReplaceDocument(documents, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | ------------------------------------------------------------------------------ | -| `documents` | Document[] | Array of [Document](/sdk/java/2/core-classes/document) to create or replace | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. -Can return a 206 partial error in cases where some documents could not be created or replaced. - -## Usage - -<<< ./snippets/mcreate-or-replace-document-1.java - -> Callback response: - -```json -{ - "hits": [{ "first": "document" }, { "second": "document" }], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/mcreate-or-replace-document/snippets/mcreate-or-replace-document-1.java b/doc/2/core-classes/collection/mcreate-or-replace-document/snippets/mcreate-or-replace-document-1.java deleted file mode 100644 index 7f79fecb..00000000 --- a/doc/2/core-classes/collection/mcreate-or-replace-document/snippets/mcreate-or-replace-document-1.java +++ /dev/null @@ -1,25 +0,0 @@ - -Document firstDocument = new Document(collection, "doc1"); -firstDocument.setContent("title", "foo"); -firstDocument.setContent("content", "bar"); - -Document secondDocument = new Document(collection, "doc2"); -secondDocument.setContent("title", "foo"); -secondDocument.setContent("content", "bar"); - -Document[] documents = new Document[]{firstDocument, secondDocument}; - -kuzzle - .collection("collection", "index") - .mCreateOrReplaceDocument(documents, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mCreateOrReplace operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/mdelete-document/index.md b/doc/2/core-classes/collection/mdelete-document/index.md deleted file mode 100644 index 97e008fe..00000000 --- a/doc/2/core-classes/collection/mdelete-document/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: mdeleteDocument -description: Collection:mdeleteDocument ---- - -# mDeleteDocument - -Delete multiple [Documents](/sdk/java/2/core-classes/document) according to the input IDs. - ---- - -## mDeleteDocument(documentIds, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ----------------------------------- | -| `documentIds` | String[] | Array of IDs of documents to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. -Can return a 206 partial error in cases where some documents could not be deleted. - -## Usage - -<<< ./snippets/mdelete-document-1.java - -> Callback response: - -```json -["doc1", "doc2"] -``` diff --git a/doc/2/core-classes/collection/mdelete-document/snippets/mdelete-document-1.java b/doc/2/core-classes/collection/mdelete-document/snippets/mdelete-document-1.java deleted file mode 100644 index 2a853bb3..00000000 --- a/doc/2/core-classes/collection/mdelete-document/snippets/mdelete-document-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -String[] documentIds = new String[]{"doc1", "doc2"}; - -kuzzle - .collection("collection", "index") - .mDeleteDocument(documentIds, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mDelete operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/mget-document/index.md b/doc/2/core-classes/collection/mget-document/index.md deleted file mode 100644 index 83478d0d..00000000 --- a/doc/2/core-classes/collection/mget-document/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: mgetDocument -description: Collection:mgetDocument ---- - -# mGetDocument - -Get multiple [Documents](/sdk/java/2/core-classes/document) according to the input document IDs. - ---- - -## mGetDocument(documentIds, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------- | -| `documentIds` | String[] | Array of IDs of documents to retrieve | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. - -## Usage - -<<< ./snippets/mget-document-1.java - -> Callback response: - -```json -{ - "hits": [ - { "_id": "doc1", "first": "document" }, - { "_id": "doc2", "second": "document" } - ], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/mget-document/snippets/mget-document-1.java b/doc/2/core-classes/collection/mget-document/snippets/mget-document-1.java deleted file mode 100644 index 78ade1d5..00000000 --- a/doc/2/core-classes/collection/mget-document/snippets/mget-document-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -String[] documentIds = new String[]{"doc1", "doc2"}; - -kuzzle - .collection("collection", "index") - .mGetDocument(documentIds, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mGet operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/mreplace-document/index.md b/doc/2/core-classes/collection/mreplace-document/index.md deleted file mode 100644 index c0718309..00000000 --- a/doc/2/core-classes/collection/mreplace-document/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: mreplaceDocument -description: Collection:mreplaceDocument ---- - -# mReplaceDocument - -Replace the provided [Documents](/sdk/java/2/core-classes/document). - ---- - -## mReplaceDocument(documents, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | -------------------------------------------------------------------- | -| `documents` | Document[] | Array of [Document](/sdk/java/2/core-classes/document) to replace | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. -Can return a 206 partial error in cases where documents could not be replaced. - -## Usage - -<<< ./snippets/mreplace-document-1.java - -> Callback response: - -```json -{ - "hits": [{ "first": "document" }, { "second": "document" }], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/mreplace-document/snippets/mreplace-document-1.java b/doc/2/core-classes/collection/mreplace-document/snippets/mreplace-document-1.java deleted file mode 100644 index c299a099..00000000 --- a/doc/2/core-classes/collection/mreplace-document/snippets/mreplace-document-1.java +++ /dev/null @@ -1,25 +0,0 @@ - -Document firstDocument = new Document(collection, "doc1"); -firstDocument.setContent("title", "foo"); -firstDocument.setContent("content", "bar"); - -Document secondDocument = new Document(collection, "doc2"); -secondDocument.setContent("title", "foo"); -secondDocument.setContent("content", "bar"); - -Document[] documents = new Document[]{firstDocument, secondDocument}; - -kuzzle - .collection("collection", "index") - .mReplaceDocument(documents, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mReplace operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/mupdate-document/index.md b/doc/2/core-classes/collection/mupdate-document/index.md deleted file mode 100644 index de8a8669..00000000 --- a/doc/2/core-classes/collection/mupdate-document/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: mupdateDocument -description: Collection:mupdateDocument ---- - -# mUpdateDocument - -Update the provided [Documents](/sdk/java/2/core-classes/document). - ---- - -## mUpdateDocument(documents, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | -------------------------------------------------------------------- | -| `documents` | Document[] | Array of [Documents](/sdk/java/2/core-classes/document) to update | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. -Can return a 206 partial error in cases where documents could not be updated. - -## Usage - -<<< ./snippets/mupdate-document-1.java - -> Callback response: - -```json -{ - "hits": [{ "first": "document" }, { "second": "document" }], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/mupdate-document/snippets/mupdate-document-1.java b/doc/2/core-classes/collection/mupdate-document/snippets/mupdate-document-1.java deleted file mode 100644 index 9ff2e2a8..00000000 --- a/doc/2/core-classes/collection/mupdate-document/snippets/mupdate-document-1.java +++ /dev/null @@ -1,25 +0,0 @@ - -Document firstDocument = new Document(collection, "doc1"); -firstDocument.setContent("title", "foo"); -firstDocument.setContent("content", "bar"); - -Document secondDocument = new Document(collection, "doc2"); -secondDocument.setContent("title", "foo"); -secondDocument.setContent("content", "bar"); - -Document[] documents = new Document[]{firstDocument, secondDocument}; - -kuzzle - .collection("collection", "index") - .mUpdateDocument(documents, new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the mUpdate operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/publish-message/index.md b/doc/2/core-classes/collection/publish-message/index.md deleted file mode 100644 index 83c2aef7..00000000 --- a/doc/2/core-classes/collection/publish-message/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: publishMessage -description: Collection:publishMessage ---- - -# publishMessage - -Publish a real-time message. - ---- - -## publishMessage(Document, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------- | -| `Document` | object | [Document](/sdk/java/2/core-classes/document) object | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## publishMessage(content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------- | -| `content` | JSON Object | Content of the document to publish | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | ------------------------------------------------------------- | ------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a raw Kuzzle response in JSON format. - -## Usage - -<<< ./snippets/publish-message-1.java diff --git a/doc/2/core-classes/collection/publish-message/snippets/publish-message-1.java b/doc/2/core-classes/collection/publish-message/snippets/publish-message-1.java deleted file mode 100644 index 909f700b..00000000 --- a/doc/2/core-classes/collection/publish-message/snippets/publish-message-1.java +++ /dev/null @@ -1,8 +0,0 @@ - -JSONObject message = new JSONObject().put("some", "content"); -JSONObject volatile = new JSONObject().put("volatile", "are volatile information"); -Options opts = new Options().setVolatile(volatile); - -kuzzle - .collection("collection", "index") - .publish(message, opts); diff --git a/doc/2/core-classes/collection/replace-document/index.md b/doc/2/core-classes/collection/replace-document/index.md deleted file mode 100644 index 3d066207..00000000 --- a/doc/2/core-classes/collection/replace-document/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: replaceDocument -description: Collection:replaceDocument ---- - -# replaceDocument - -Replace an existing document and return the updated version as a [Document](/sdk/java/2/core-classes/document) object. - ---- - -## replaceDocument(documentId, content, [options], [callback]) - -| Arguments | Type | Description | -| ------------ | ----------- | --------------------------------- | -| `documentId` | string | Unique document identifier | -| `content` | JSON Object | Content of the document to create | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns an updated [Document](/sdk/java/2/core-classes/document) object. - -## Usage - -<<< ./snippets/replace-document-1.java diff --git a/doc/2/core-classes/collection/replace-document/snippets/replace-document-1.java b/doc/2/core-classes/collection/replace-document/snippets/replace-document-1.java deleted file mode 100644 index 9c2c57ce..00000000 --- a/doc/2/core-classes/collection/replace-document/snippets/replace-document-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject newContent = new JSONObject("new", "document content"); - -kuzzle - .collection("collection", "index") - .replaceDocument("documentId", newContent, new ResponseListener() { - @Override - public void onSuccess(Document document) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/collection/room/index.md b/doc/2/core-classes/collection/room/index.md deleted file mode 100644 index 16490bf6..00000000 --- a/doc/2/core-classes/collection/room/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -code: true -type: page -title: room -description: Collection:room ---- - -# room - -Creates a new [Room](/sdk/java/2/core-classes/room) object, using its constructor. - ---- - -## room([options]) - -| Arguments | Type | Description | -| --------- | ------ | -------------------------- | -| `options` | object | Subscription configuration | - -## Options - -Provided options are passed directly to the [Room](/sdk/java/2/core-classes/room) object constructor. - ---- - -## Return Value - -Returns the newly created [Room](/sdk/java/2/core-classes/room) object. - -## Usage - -<<< ./snippets/room-1.java diff --git a/doc/2/core-classes/collection/room/snippets/room-1.java b/doc/2/core-classes/collection/room/snippets/room-1.java deleted file mode 100644 index 2cd5aeb1..00000000 --- a/doc/2/core-classes/collection/room/snippets/room-1.java +++ /dev/null @@ -1,23 +0,0 @@ - -JSONObject filters = new JSONObject() - .put("in", - new JSONObject("field") - .put(new JSONArray() - .put("some") - .put("filter") - ) - ); - -Room room = kuzzle.collection("collection", "index") - .room() - .renew(filters, new ResponseListener() { - @Override - public void onSuccess(NotificationResponse object) { - // handle notifications - } - - @Override - public void onError(JSONObject error) { - // Handle notifications error - } - }); diff --git a/doc/2/core-classes/collection/scroll-specifications/index.md b/doc/2/core-classes/collection/scroll-specifications/index.md deleted file mode 100644 index 436785ed..00000000 --- a/doc/2/core-classes/collection/scroll-specifications/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: scrollSpecifications -description: Collection:scrollSpecifications ---- - -# scrollSpecifications - -Returns a JSON object containing the next page of the scroll session, and the `scrollId` to be used in the next `scroll` action. -A scroll session is always initiated by a `searchSpecification` action with the `scroll` argument. - ---- - -## scrollSpecifications(scrollId, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------- | -| `scrollId` | string | The "scrollId" provided with the last scrollSpecifications response or from the initial searchSpecifications request | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Re-initializes the scroll session timeout to its value. If not defined, the scroll timeout is defaulted to a Kuzzle configuration | `undefined` | - -## Usage - -<<< ./snippets/scroll-specifications-1.java - -> Callback response - -```json -{ - "hits": [{ "first": "specification" }, { "second": "specification" }], - "total": 2 -} -``` diff --git a/doc/2/core-classes/collection/scroll-specifications/snippets/scroll-specifications-1.java b/doc/2/core-classes/collection/scroll-specifications/snippets/scroll-specifications-1.java deleted file mode 100644 index 8bb8301a..00000000 --- a/doc/2/core-classes/collection/scroll-specifications/snippets/scroll-specifications-1.java +++ /dev/null @@ -1,21 +0,0 @@ - -Options opts = new Options(); -opts.setScroll("1m"); - -kuzzle - .collection("collection", "index") - .scrollSpecifications(scrollId, opts, new ResponseListener() { - @Override - public void onSuccess(JSONObject res) { - for (int i = 0; i < res.getJSONArray("hits").length(); i++) { - res.getJSONArray("hits").getJSONObject(i) // Specification - } - - res.getString("total"); // Total specifications count - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/scroll/index.md b/doc/2/core-classes/collection/scroll/index.md deleted file mode 100644 index 61c3819c..00000000 --- a/doc/2/core-classes/collection/scroll/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: scroll -description: Collection:scroll ---- - -# scroll - -Returns a [SearchResult](/sdk/java/2/core-classes/search-result) object containing the next page of the scroll session, and the `scrollId` to be used in the next `scroll` action. -A scroll session is always initiated by a `search` action and including the `scroll` argument; more information below. - -:::info -There is a small delay between the time a document is created and its availability in our search layer (usually a couple of seconds). That means that a document that was just created might not be returned immediately by this function. -::: - -:::info -To get more information about scroll sessions, please refer to the [API reference documentation](/core/1/api/controllers/document/search). -::: - ---- - -## scroll(scrollId, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- | -| `scrollId` | string | The "scrollId" provided with the last scroll response or from the initial search request if it is the first scroll call | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Re-initializes the scroll session timeout to its value. If not defined, the scroll timeout is defaulted to a Kuzzle configuration | `undefined` | - ---- - -## Callback Response - -Returns an instantiated [SearchResult](/sdk/java/2/core-classes/search-result) object. - ---- - -## Usage - -<<< ./snippets/scroll-1.java diff --git a/doc/2/core-classes/collection/scroll/snippets/scroll-1.java b/doc/2/core-classes/collection/scroll/snippets/scroll-1.java deleted file mode 100644 index 1c94a896..00000000 --- a/doc/2/core-classes/collection/scroll/snippets/scroll-1.java +++ /dev/null @@ -1,23 +0,0 @@ - -Options opts = new Options(); -opts.setScroll("1m"); - -kuzzle - .collection("collection", "index") - .scroll(scrollId, opts, new ResponseListener() { - @Override - public void onSuccess(SearchResult searchResult) { - for (Document doc : searchResult.getDocuments()) { - // Get documents - } - - searchResult.getTotal(); // return total of documents returned - - searchResult.getAggregations(): // return a JSONObject representing the aggregations response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/search-specifications/index.md b/doc/2/core-classes/collection/search-specifications/index.md deleted file mode 100644 index 15242569..00000000 --- a/doc/2/core-classes/collection/search-specifications/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: searchSpecifications -description: Collection:searchSpecifications ---- - -# searchSpecifications - -Retrieves every specifications across indexes/collections according to the given filters. - ---- - -## searchSpecifications(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `filters` | JSON object | Search request body, using [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-body.html) format.
If given an empty object, matches all specifications across index/collections | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `from` | number | Provide the starting offset of the request (used to paginate results) | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Start a scroll session, with a time to live equals to this parameter's value following the [Elastisearch time format](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/common-options.html#time-units) | `undefined` | -| `size` | number | Provide the maximum number of results of the request (used to paginate results) | `10` | - -## Usage - -<<< ./snippets/search-specifications-1.java - -> Callback response - -```json -{ - "hits": [{ "first": "specification" }, { "second": "specification" }], - "total": 2, - "scrollId": "foobar" -} -``` diff --git a/doc/2/core-classes/collection/search-specifications/snippets/search-specifications-1.java b/doc/2/core-classes/collection/search-specifications/snippets/search-specifications-1.java deleted file mode 100644 index 516f9840..00000000 --- a/doc/2/core-classes/collection/search-specifications/snippets/search-specifications-1.java +++ /dev/null @@ -1,32 +0,0 @@ - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; - -Kuzzle kuzzle = new Kuzzle("localhost"); - -JSONObject filters = new JSONObject() - .put("match_all", new JSONObject() - .put("boost", 1) - ); - -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 20); - -kuzzle - .collection("collection", "index") - .searchSpecifications(filters, options, new ResponseListener() { - @Override - public void onSuccess(JSONObject res) { - for (int i = 0; i < res.getJSONArray("hits").length(); i++) { - res.getJSONArray("hits").getJSONObject(i) // Specification - } - - res.getString("total"); // Total specifications count - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/search/index.md b/doc/2/core-classes/collection/search/index.md deleted file mode 100644 index b0a1fb7f..00000000 --- a/doc/2/core-classes/collection/search/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: search -description: Collection:search ---- - -# search - -Executes a search on the collection. - -:::info -There is a small delay between the time a document is created and its availability in our search layer (usually a couple of seconds). That means that a document that was just created might not be returned immediately by this function. -::: - -## Processing large data sets - -When processing a large number of documents (i.e. more than 1000), using `search` is not always the best option. - -Pagination of results can be done by using the from and size but the cost becomes prohibitive when deep pagination is reached. In fact, Elasticsearch, Kuzzle's embedded database, limits results to 10,000 records by default. - -Instead, the recommended way to process a large number of documents is to use [`Collection.scroll`](/sdk/java/2/core-classes/collection/scroll) or, easier, [`SearchResult.fetchNext`](/sdk/java/2/core-classes/search-result/fetch-next). - -See [`SearchResult.fetchNext`](/sdk/java/2/core-classes/search-result/fetch-next#how-to-process-every-document-of-a-collection) for an example of how to process every document of a collection. - ---- - -## search(body, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `body` | JSON object | Search request body, using [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-body.html) format.
If given an empty object, matches all documents in the collection | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `from` | number | Provide the starting offset of the request (used to paginate results) | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Start a scroll session, with a time to live equals to this parameter's value following the [Elastisearch time format](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/common-options.html#time-units) | `undefined` | -| `size` | number | Provide the maximum number of results of the request (used to paginate results) | `10` | - -:::info -To get more information about scroll sessions, please refer to the [API reference documentation](/core/1/api/controllers/document/search). -::: - ---- - -## Callback Response - -Returns an instance of [SearchResult](/sdk/java/2/core-classes/search-result). - -## Usage - -<<< ./snippets/search-1.java diff --git a/doc/2/core-classes/collection/search/snippets/search-1.java b/doc/2/core-classes/collection/search/snippets/search-1.java deleted file mode 100644 index 8f202ed3..00000000 --- a/doc/2/core-classes/collection/search/snippets/search-1.java +++ /dev/null @@ -1,87 +0,0 @@ - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; - -Kuzzle kuzzle = new Kuzzle("localhost"); - -JSONObject body = new JSONObject() - .put("query", new JSONObject() - .put("bool", new JSONObject() - .put("must", new JSONArray() - .put( - new JSONObject().put("terms", - new JSONObject().put("status", - new JSONArray() - .put("idle") - .put("wantToHire") - .put("toHire") - .put("riding") - ) - ) - ) - .put( - new JSONObject().put("term", - new JSONObject() - .put("type", new JSONArray().put("cab")) - ) - ) - .put( - new JSONObject().put("geo_distance", - new JSONObject() - .put("distance", "10km") - .put("pos", - new JSONObject() - .put("lat", "48.8566140") - .put("lon", "2.352222") - ) - ) - ) - ) - ) - ) - .put("sort", new JSONArray() - .put("status") - .put(new JSONObject() - .put("_geo_distance", new JSONObject() - .put("pos", new JSONObject() - .put("lat", "48.8566140") - .put("lon", "2.352222") - ) - .put('order'; "asc") - ) - ) - .put(new JSONObject() - .put("date", "desc") - ) - ) - .put("aggregations", new JSONObject() - .put("aggs_name", new JSONObject() - .put("terms", new JSONObject() - .put("field", "field_name") - ) - ) - ); - -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 20); - -kuzzle - .collection("collection", "index") - .search(body, options, new ResponseListener() { - @Override - public void onSuccess(SearchResult searchResult) { - for (Document doc : searchResult.getDocuments()) { - // Get documents - } - - searchResult.getTotal(); // return total of documents returned - - searchResult.getAggregations(): // return a JSONObject representing the aggregations response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/set-headers/index.md b/doc/2/core-classes/collection/set-headers/index.md deleted file mode 100644 index f22fc285..00000000 --- a/doc/2/core-classes/collection/set-headers/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -code: true -type: page -title: setHeaders -description: Collection:setHeaders ---- - -# setHeaders - -This is a helper function returning itself, allowing to easily set headers while chaining calls. - ---- - -## setHeaders(content, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `content` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return value - -Returns the `Collection` object to allow chaining. - -## Usage - -<<< ./snippets/set-headers-1.java diff --git a/doc/2/core-classes/collection/set-headers/snippets/set-headers-1.java b/doc/2/core-classes/collection/set-headers/snippets/set-headers-1.java deleted file mode 100644 index 2dd625fb..00000000 --- a/doc/2/core-classes/collection/set-headers/snippets/set-headers-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject headers = new JSONObject() - .put("someContent", "someValue") - .put("volatile", new JSONObject() - .put("someVolatileData", new JSONArray() - .put("with") - .put("some") - .put("values") - ) - ); - -kuzzle - .collection("collection", "index") - .setHeaders(content, true); diff --git a/doc/2/core-classes/collection/subscribe/index.md b/doc/2/core-classes/collection/subscribe/index.md deleted file mode 100644 index 4de9b718..00000000 --- a/doc/2/core-classes/collection/subscribe/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: subscribe -description: Collection:subscribe ---- - -# subscribe - -Subscribes to this collection with a set of filters. - -The provided callback will be called everytime a [notification](/sdk/java/2/essentials/realtime-notifications) is received from Kuzzle. - ---- - -## subscribe(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------------------------------------- | -| `filters` | JSON Object | [Koncorde Filters](/core/1/guides/cookbooks/realtime-api) | -| `options` | object | (Optional) Subscription configuration. Passed to the Room constructor. | -| `callback` | function | Callback to call every time a notification is received on this subscription | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `scope` | string | Filter document notifications depending on their scope status. You may receive entering documents (scope: `in`), leaving documents (scope: `out`), all documents changes (scope: `all`) or filter these notifications completely (scope: `none`). This filter does not affect pub/sub messages or user events. | `all` | -| `state` | string | Filter document notifications depending on the state of the modifying request. You may receive real-time notifications when a document is about to be changed (state: `pending`), or be notified when the change has been fully written in the database (state: `done`), or both (state: `all`). This filter does not affect pub/sub messages or user events. | `done` | -| `subscribeToSelf` | boolean | (Don't) subscribe to notifications fired as a consequence of our own queries | `true` | -| `users` | string | Filter notifications fired upon a user entering the room (user: `in`), leaving the room (user: `out`), or both (user: `all`). Setting this variable to `none` prevents receiving these notifications | `none` | - -The `options` object is directly passed to the Room constructor. -See the [Room object](/sdk/java/2/core-classes/room) documentation for more information about these options and notifications. - ---- - -## Return Value - -Returns an object exposing the following method: - `onDone(callback)` - -The `callback` argument is called when the subscription ends, either successfully or with an error. - -## Usage - -<<< ./snippets/subscribe-1.java diff --git a/doc/2/core-classes/collection/subscribe/snippets/subscribe-1.java b/doc/2/core-classes/collection/subscribe/snippets/subscribe-1.java deleted file mode 100644 index ce798483..00000000 --- a/doc/2/core-classes/collection/subscribe/snippets/subscribe-1.java +++ /dev/null @@ -1,60 +0,0 @@ - -JSONObject filter = new JSONObject() - .put("and", new JSONArray() - .put( - new JSONObject().put("in", - new JSONObject().put("status", - new JSONArray() - .put("idle") - .put("wantToHire") - .put("toHire") - .put("riding") - ) - ) - ) - .put( - new JSONObject().put("in", - new JSONObject() - .put("type", new JSONArray().put("cab")) - ) - ) - .put( - new JSONObject().put("geo_distance", - new JSONObject() - .put("distance", "10km") - .put("pos", - new JSONObject() - .put("lat", "48.8566140") - .put("lon", "2.352222") - ) - ) - ) - ); - -kuzzle - .collection("collection", "index") - .subscribe(filter, new ResponseListener() { - @Override - public void onSuccess(NotificationResponse object) { - // called each time a new notification on this filter is received - - // check the Room/Notifications section of this documentation - // to get notification examples - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }) - .onDone(new ResponseListener() { - @Override - public void onSuccess(Room response) { - // Handle subscription success - } - - @Override - public void onError(JSONObject error) { - // Handle subscription error - } - }); diff --git a/doc/2/core-classes/collection/truncate/index.md b/doc/2/core-classes/collection/truncate/index.md deleted file mode 100644 index f828a090..00000000 --- a/doc/2/core-classes/collection/truncate/index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -code: true -type: page -title: truncate -description: Collection:truncate ---- - -# truncate - -Truncate the collection, removing all stored documents but keeping all associated mappings. - -This method is a lot faster than removing all documents using multiple delete requests. - ---- - -## truncate([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. - -## Usage - -<<< ./snippets/truncate-1.java - -> Callback response: - -```json -{ - "status": 200, - "error": null, - "requestId": "8fdc0efb-6fc7-427d-a3a1-fd8cf5eabc20", - "controller": "admin", - "action": "truncateCollection", - "collection": "name of the truncated collection", - "index": "name of the index containing the truncated collection", - "volatile": {}, - "state": "done", - "result": { "acknowledged": true } -} -``` diff --git a/doc/2/core-classes/collection/truncate/snippets/truncate-1.java b/doc/2/core-classes/collection/truncate/snippets/truncate-1.java deleted file mode 100644 index 610dee52..00000000 --- a/doc/2/core-classes/collection/truncate/snippets/truncate-1.java +++ /dev/null @@ -1,15 +0,0 @@ - -kuzzle - .collection("collection", "index") - .truncate(new ResponseListener() { - @Override - public void onSuccess(JSONObject object) { - // callback called once the truncate operation has completed - // => the result is a JSON object containing the raw Kuzzle response - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/update-document/index.md b/doc/2/core-classes/collection/update-document/index.md deleted file mode 100644 index ce1f11af..00000000 --- a/doc/2/core-classes/collection/update-document/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: updateDocument -description: Collection:updateDocument ---- - -# updateDocument - -Update parts of a document, by replacing some fields or adding new ones. -Note that you cannot remove fields this way: missing fields will simply be left unchanged. - ---- - -## updateDocument(documentId, content, [options], [callback]) - -| Arguments | Type | Description | -| ------------ | ----------- | --------------------------------- | -| `documentId` | string | Unique document identifier | -| `content` | JSON object | Content of the document to create | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | -| `retryOnConflict` | int | Number of retries to attempt before rejecting this update because of a cluster sync conflict | `0` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - ---- - -## Callback Response - -Returns an up-to-date [Document](/sdk/java/2/core-classes/document) object. - -## Usage - -<<< ./snippets/update-document-1.java diff --git a/doc/2/core-classes/collection/update-document/snippets/update-document-1.java b/doc/2/core-classes/collection/update-document/snippets/update-document-1.java deleted file mode 100644 index 35782bfb..00000000 --- a/doc/2/core-classes/collection/update-document/snippets/update-document-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject newTitle = new JSONObject().put("title", "a shiny new title"); - -kuzzle - .collection("collection", "index") - .updateDocument("documentId", newTitle, new ResponseListener() { - @Override - public void onSuccess(Document result) { - // result is an updated Document object - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/update-specifications/index.md b/doc/2/core-classes/collection/update-specifications/index.md deleted file mode 100644 index 2e352526..00000000 --- a/doc/2/core-classes/collection/update-specifications/index.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -code: true -type: page -title: updateSpecifications -description: Collection:updateSpecifications ---- - -# updateSpecifications - -Update parts of a specification, by replacing some fields or adding new ones. -Note that you cannot remove fields this way: missing fields will simply be left unchanged. - ---- - -## updateSpecifications(content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------- | -| `content` | JSON object | Content of the specification to update | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | -| `retryOnConflict` | int | Number of retries to attempt before rejecting this update because of a cluster sync conflict | `0` | - ---- - -## Return Value - -Returns the `Collection` object to allow chaining. - -## Usage - -<<< ./snippets/update-specifications-1.java - -> Callback response - -```json -{ - "index": { - "collection": { - "strict": "true", - "fields": { - "foo": { - "mandatory": "true", - "type": "string", - "defaultValue": "bar" - } - } - } - } -} -``` diff --git a/doc/2/core-classes/collection/update-specifications/snippets/update-specifications-1.java b/doc/2/core-classes/collection/update-specifications/snippets/update-specifications-1.java deleted file mode 100644 index e3b32e80..00000000 --- a/doc/2/core-classes/collection/update-specifications/snippets/update-specifications-1.java +++ /dev/null @@ -1,26 +0,0 @@ - -JSONObject fooField = new JSONObject() - .put("mandatory", "true") - .put("type", "string") - .put("defaultValue", "bar"); - -JSONObject fields = new JSONObject() - .put("foo", fooField); - -JSONObject specifications = new JSONObject() - .put("strict", "true") - .put("fields", fields); - -kuzzle - .collection("collection", "index") - .updateSpecifications(specifications, new ResponseListener() { - @Override - public void onSuccess(JSONObject res) { - // result is a JSONObject - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/collection/validate-specifications/index.md b/doc/2/core-classes/collection/validate-specifications/index.md deleted file mode 100644 index 6391b73c..00000000 --- a/doc/2/core-classes/collection/validate-specifications/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: validateSpecifications -description: Collection:validateSpecifications ---- - -# validateSpecifications - -Validate a specification. - ---- - -## validateSpecifications(content, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------- | -| `content` | JSON object | Content of the specification to validate | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a boolean indicating whether or not the input specifications is valid or not. - -## Usage - -<<< ./snippets/validate-specifications-1.java diff --git a/doc/2/core-classes/collection/validate-specifications/snippets/validate-specifications-1.java b/doc/2/core-classes/collection/validate-specifications/snippets/validate-specifications-1.java deleted file mode 100644 index cae3e309..00000000 --- a/doc/2/core-classes/collection/validate-specifications/snippets/validate-specifications-1.java +++ /dev/null @@ -1,26 +0,0 @@ - -JSONObject fooField = new JSONObject() - .put("mandatory", "true") - .put("type", "string") - .put("defaultValue", "bar"); - -JSONObject fields = new JSONObject() - .put("foo", fooField); - -JSONObject specifications = new JSONObject() - .put("strict", "true") - .put("fields", fields); - -kuzzle - .collection("collection", "index") - .validateSpecifications(specifications, new ResponseListener() { - @Override - public void onSuccess(Boolean isValid) { - // isValid is a boolean - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/document/constructor/index.md b/doc/2/core-classes/document/constructor/index.md deleted file mode 100644 index 53133737..00000000 --- a/doc/2/core-classes/document/constructor/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Document:constructor -order: 1 ---- - -# Document - -Kuzzle handles two types of documents: realtime messages and stored documents. Document is the object representation of one of these document types. - ---- - -## Document(Collection, [documentId], [content]) - -| Arguments | Type | Description | -| ------------ | ----------- | --------------------------------------------------- | -| `Collection` | object | An instantiated Collection object | -| `content` | JSON Object | Initializes this document with the provided content | -| `documentId` | string | ID of an existing document. | - -**Note:** this constructor won't make any call to Kuzzle. When providing only a document ID, the `refresh` method should be called to retrieve the corresponding document content. - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ----------- | ----------------------------------------------- | ------- | -| `collection` | string | The collection associated to this document | get | -| `content` | JSON Object | The content of the document | get/set | -| `headers` | JSON Object | Common headers for all sent documents. | get/set | -| `id` | string | Unique document identifier | get/set | -| `meta` | JSON Object | Document metadata | get | -| `version` | integer | Current document version | get | - -**Notes:** - -- setting a new value to the `content` property is equivalent to calling `setContent(data, false)` -- setting a new value to the `id` property will force this value for this document -- the `headers` property is inherited from the provided `Collection` object and can be overrided - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/document/constructor/snippets/constructor-1.java b/doc/2/core-classes/document/constructor/snippets/constructor-1.java deleted file mode 100644 index 201adaf0..00000000 --- a/doc/2/core-classes/document/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,10 +0,0 @@ - -Document document = new Document(collection); - -Document document = new Document(collection, "id"); - -JSONObject content = new JSONObject(); -content.put("content", "some content"); -Document document = new Document(collection, content); - -Document document = new Document(collection, "id", content); diff --git a/doc/2/core-classes/document/delete/index.md b/doc/2/core-classes/document/delete/index.md deleted file mode 100644 index 8972d033..00000000 --- a/doc/2/core-classes/document/delete/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -code: true -type: page -title: delete -description: Document:delete ---- - -# delete - -Deletes this document in Kuzzle. - ---- - -## delete([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Callback Response - -Returns a string containing the ID of the deleted document. - -## Usage - -<<< ./snippets/delete-1.java diff --git a/doc/2/core-classes/document/delete/snippets/delete-1.java b/doc/2/core-classes/document/delete/snippets/delete-1.java deleted file mode 100644 index f7ba4b63..00000000 --- a/doc/2/core-classes/document/delete/snippets/delete-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -document.delete(new ResponseListener() { - @Override - public void onSuccess(Document object) { - // called once the delete action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/document/exists/index.md b/doc/2/core-classes/document/exists/index.md deleted file mode 100644 index 02d80deb..00000000 --- a/doc/2/core-classes/document/exists/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: exists -description: Document:exists ---- - -# exists - -Checks if the document exists in Kuzzle. - ---- - -## exists([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Return a boolean indicating whether or not the document exists in Kuzzle. - -## Usage - -<<< ./snippets/exists-1.java diff --git a/doc/2/core-classes/document/exists/snippets/exists-1.java b/doc/2/core-classes/document/exists/snippets/exists-1.java deleted file mode 100644 index 01de2360..00000000 --- a/doc/2/core-classes/document/exists/snippets/exists-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -document.exists(new ResponseListener() { - @Override - public void onSuccess(Boolean exists) { - // called once the exists check has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/document/index.md b/doc/2/core-classes/document/index.md deleted file mode 100644 index ad9a6cc9..00000000 --- a/doc/2/core-classes/document/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Document -description: Document documentation ---- diff --git a/doc/2/core-classes/document/publish/index.md b/doc/2/core-classes/document/publish/index.md deleted file mode 100644 index 064d023d..00000000 --- a/doc/2/core-classes/document/publish/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: publish -description: Document:publish ---- - -# publish - -Publishes the content of this document as a real-time message. - ---- - -## publish([options]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | ------------------------------------------------------------- | ------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns this `Document` object to allow chaining. - -## Usage - -<<< ./snippets/publish-1.java diff --git a/doc/2/core-classes/document/publish/snippets/publish-1.java b/doc/2/core-classes/document/publish/snippets/publish-1.java deleted file mode 100644 index b671526e..00000000 --- a/doc/2/core-classes/document/publish/snippets/publish-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -document.publish(); diff --git a/doc/2/core-classes/document/refresh/index.md b/doc/2/core-classes/document/refresh/index.md deleted file mode 100644 index a9864524..00000000 --- a/doc/2/core-classes/document/refresh/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: refresh -description: Document:refresh ---- - -# refresh - -Creates a new `Document` object with the last version of this document stored in Kuzzle. - ---- - -## refresh([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Return a new `Document` object containing the last document version. - -## Usage - -<<< ./snippets/refresh-1.java diff --git a/doc/2/core-classes/document/refresh/snippets/refresh-1.java b/doc/2/core-classes/document/refresh/snippets/refresh-1.java deleted file mode 100644 index bd1b2eba..00000000 --- a/doc/2/core-classes/document/refresh/snippets/refresh-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -document.refresh(new ResponseListener() { - @Override - public void onSuccess(Document object) { - // called once the refresh action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/document/save/index.md b/doc/2/core-classes/document/save/index.md deleted file mode 100644 index eaef20b1..00000000 --- a/doc/2/core-classes/document/save/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: save -description: Document:save ---- - -# save - -Saves this document into Kuzzle. - -If this is a new document, this function will create it in Kuzzle and the `id` property will be made available. -Otherwise, this method will replace the latest version of the document in Kuzzle with the content of this current object. - ---- - -## save([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns this `Document` object to allow chaining. - ---- - -## Callback Response - -Return this `Document` object once the document has been saved. - -## Usage - -<<< ./snippets/save-1.java diff --git a/doc/2/core-classes/document/save/snippets/save-1.java b/doc/2/core-classes/document/save/snippets/save-1.java deleted file mode 100644 index 6706d959..00000000 --- a/doc/2/core-classes/document/save/snippets/save-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -document.save(new ResponseListener() { - @Override - public void onSuccess(Document object) { - // called once the save action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/document/set-content/index.md b/doc/2/core-classes/document/set-content/index.md deleted file mode 100644 index dee1b15e..00000000 --- a/doc/2/core-classes/document/set-content/index.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -code: true -type: page -title: setContent -description: Document:setContent ---- - -# setContent - -Replaces the current content with new data. -This is a helper function returning a reference to itself so that you can easily chain calls. - -:::info -Changes made by this function won't be applied until the `save` method is called -::: - ---- - -## setContent(data, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `data` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return Value - -Returns this `Document` object to allow chaining. - -## Usage - -<<< ./snippets/set-content-1.java diff --git a/doc/2/core-classes/document/set-content/snippets/set-content-1.java b/doc/2/core-classes/document/set-content/snippets/set-content-1.java deleted file mode 100644 index 024b2dbf..00000000 --- a/doc/2/core-classes/document/set-content/snippets/set-content-1.java +++ /dev/null @@ -1,4 +0,0 @@ - -JSONObject content = new JSONObject().put("content", "some content"); - -document.setContent(content, true); diff --git a/doc/2/core-classes/document/set-headers/index.md b/doc/2/core-classes/document/set-headers/index.md deleted file mode 100644 index 911d3ae8..00000000 --- a/doc/2/core-classes/document/set-headers/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -code: true -type: page -title: setHeaders -description: Document:setHeaders ---- - -# setHeaders - -This is a helper function returning itself, allowing to easily chain calls. - ---- - -## setHeaders(content, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `content` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return value - -Returns this `Document` object to allow chaining. - -## Usage - -<<< ./snippets/set-headers-1.java diff --git a/doc/2/core-classes/document/set-headers/snippets/set-headers-1.java b/doc/2/core-classes/document/set-headers/snippets/set-headers-1.java deleted file mode 100644 index 3651d23a..00000000 --- a/doc/2/core-classes/document/set-headers/snippets/set-headers-1.java +++ /dev/null @@ -1,4 +0,0 @@ - -JSONObject headers = new JSONObject().put("someContent", "someValue"); - -document.setHeaders(headers, true); diff --git a/doc/2/core-classes/document/subscribe/index.md b/doc/2/core-classes/document/subscribe/index.md deleted file mode 100644 index 40076ce1..00000000 --- a/doc/2/core-classes/document/subscribe/index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -code: true -type: page -title: subscribe -description: Document:subscribe ---- - -# subscribe - -Listens to changes occuring in this document. -Throws an error if this document has not yet been created in Kuzzle. - -The provided callback will be called everytime a [notification](/sdk/java/2/essentials/realtime-notifications) is received from Kuzzle. - ---- - -## subscribe([options], callback) - -| Arguments | Type | Description | -| ---------- | -------- | ---------------------------------------------------------------------------------- | -| `options` | object | Subscription configuration | -| `callback` | function | Callback that will be called each time a change has been detected on this document | - ---- - -## Options - -Options are directly passed to the [Room](/sdk/java/2/core-classes/room) object constructor. - ---- - -## Return Value - -Returns an object exposing the following method: - `onDone(callback)` - -The `callback` argument is called when the subscription ends, either successfully or with an error. - -## Usage - -<<< ./snippets/subscribe-1.java diff --git a/doc/2/core-classes/document/subscribe/snippets/subscribe-1.java b/doc/2/core-classes/document/subscribe/snippets/subscribe-1.java deleted file mode 100644 index 3a563eef..00000000 --- a/doc/2/core-classes/document/subscribe/snippets/subscribe-1.java +++ /dev/null @@ -1,23 +0,0 @@ - -Room room = document.subscribe(new ResponseListener() { - @Override - public void onSuccess(NotificationResponse object) { - // called each time a change occurs on this document - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }) - .onDone(new ResponseListener() { - @Override - public void onSuccess(Room response) { - // Handle subscription success - } - - @Override - public void onError(JSONObject error) { - // Handle subscription error - } - }); diff --git a/doc/2/core-classes/index.md b/doc/2/core-classes/index.md deleted file mode 100644 index a4eb0e59..00000000 --- a/doc/2/core-classes/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -code: false -type: branch -order: 10 -title: Core classes -description: Core classes ---- diff --git a/doc/2/core-classes/kuzzle/add-listener/index.md b/doc/2/core-classes/kuzzle/add-listener/index.md deleted file mode 100644 index 4d50a1e2..00000000 --- a/doc/2/core-classes/kuzzle/add-listener/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: addListener -description: Kuzzle:addListener ---- - -# addListener - -Adds a listener to an event. When an event is fired, listeners are called in the order that they are added. - ---- - -## addListener(event, listener) - -| Arguments | Type | Description | -| ---------- | -------- | -------------------------------------------------------------------------------- | -| `event` | string | One of the event described in the `Event Handling` section of this documentation | -| `listener` | function | The function to call each time one of the registered event is fired | - ---- - -## Return Value - -Returns the `Kuzzle` object to allow chaining. - -## Usage - -<<< ./snippets/add-listener-1.java diff --git a/doc/2/core-classes/kuzzle/add-listener/snippets/add-listener-1.java b/doc/2/core-classes/kuzzle/add-listener/snippets/add-listener-1.java deleted file mode 100644 index 27e9f82a..00000000 --- a/doc/2/core-classes/kuzzle/add-listener/snippets/add-listener-1.java +++ /dev/null @@ -1,8 +0,0 @@ - -EventListener eventListener = new EventListener() { - @Override - public void trigger(Object... args) { - // Actions to perform when receiving a 'subscribed' global event - } -}; -kuzzle.addListener(Event.connected, eventListener); diff --git a/doc/2/core-classes/kuzzle/check-token/index.md b/doc/2/core-classes/kuzzle/check-token/index.md deleted file mode 100644 index 762879bd..00000000 --- a/doc/2/core-classes/kuzzle/check-token/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: checkToken -description: Kuzzle:checkToken ---- - -# checkToken - -> Callback response if the token is valid: - -```json -{ - "expiresAt": 1454588077399, - "valid": true -} -``` - -> Callback response if the token is invalid: - -```json -{ - "valid": false, - "state": "" -} -``` - -Checks the validity of a JSON Web Token. - -:::info -This method is non-queuable, meaning that during offline mode, it will be discarded and the callback return an error. -::: - ---- - -## checkToken(token, callback) - -| Arguments | Type | Description | -| ---------- | -------- | ------------------------------ | -| `token` | string | The token to check | -| `callback` | function | Callback handling the response | - -**Note:** this method sends an unauthenticated API call to Kuzzle, meaning it ignores the JWT Token property, even if it has been set. - ---- - -## Callback Response - -Returns a JSON object with a `valid` boolean property. -If the token is valid, an `expiresAt` property is set with the expiration timestamp. If not, a `state` property is set explaining why the token is invalid. - -## Usage - -<<< ./snippets/check-token-1.java diff --git a/doc/2/core-classes/kuzzle/check-token/snippets/check-token-1.java b/doc/2/core-classes/kuzzle/check-token/snippets/check-token-1.java deleted file mode 100644 index d296c4c3..00000000 --- a/doc/2/core-classes/kuzzle/check-token/snippets/check-token-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.checkToken("some jwt token", new ResponseListener() { - @Override - public void onSuccess(TokenValidity tokenInfo) { - if (tokenInfo.isValid()) { - // tokenInfo.getExpiresAt() returns the expiration timestamp - } - else { - // tokenInfo.getState() returns the invalidity reason - } - } -}); diff --git a/doc/2/core-classes/kuzzle/collection/index.md b/doc/2/core-classes/kuzzle/collection/index.md deleted file mode 100644 index 70d28180..00000000 --- a/doc/2/core-classes/kuzzle/collection/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -code: true -type: page -title: collection -description: Kuzzle:collection ---- - -# collection - -Instantiates a new [Collection](/sdk/java/2/core-classes/collection) object. - ---- - -## collection(collection, [index]) - -| Arguments | Type | Description | -| ------------ | ------ | ------------------------------------------------------ | -| `collection` | string | The name of the collection you want to manipulate | -| `index` | string | The name of the index containing the collection | - -If no `index` is provided, the factory will take the default index set in the main Kuzzle SDK instance. If no default index has been set, an error is thrown. - -The `index` argument takes precedence over the default index. - ---- - -## Return Value - -Returns a [Collection](/sdk/java/2/core-classes/collection) object. - -## Usage - -<<< ./snippets/collection-1.java diff --git a/doc/2/core-classes/kuzzle/collection/snippets/collection-1.java b/doc/2/core-classes/kuzzle/collection/snippets/collection-1.java deleted file mode 100644 index a6ce6494..00000000 --- a/doc/2/core-classes/kuzzle/collection/snippets/collection-1.java +++ /dev/null @@ -1,6 +0,0 @@ - -Collection collection = kuzzle.collection("collection", "index"); - -// or using a default index: -kuzzle.setDefaultIndex("index"); -Collection collection = kuzzle.collection("collection"); diff --git a/doc/2/core-classes/kuzzle/connect/index.md b/doc/2/core-classes/kuzzle/connect/index.md deleted file mode 100644 index b161ca4e..00000000 --- a/doc/2/core-classes/kuzzle/connect/index.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -code: true -type: page -title: connect -description: Kuzzle:connect ---- - -# connect - -Connects to Kuzzle using the `host` parameter provided in the constructor. -Has no effect if `connect` is set to `auto`, unless `disconnect` has been called first. - ---- - -## Return value - -Returns the `Kuzzle` object to allow chaining. - ---- - -## Callback Response - -If a callback has been provided to the `Kuzzle` constructor, it will be called with the `Kuzzle` instance once connected to Kuzzle - -## Usage - -<<< ./snippets/connect-1.java diff --git a/doc/2/core-classes/kuzzle/connect/snippets/connect-1.java b/doc/2/core-classes/kuzzle/connect/snippets/connect-1.java deleted file mode 100644 index d2b41898..00000000 --- a/doc/2/core-classes/kuzzle/connect/snippets/connect-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.connect(); diff --git a/doc/2/core-classes/kuzzle/constructor/index.md b/doc/2/core-classes/kuzzle/constructor/index.md deleted file mode 100644 index 43984d87..00000000 --- a/doc/2/core-classes/kuzzle/constructor/index.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -code: true -type: page -title: Kuzzle -description: Entry point and main class for the entire SDK -order: 100 ---- - -# Constructor - -This is the main entry point to communicate with Kuzzle. Every other object inherits properties from the `Kuzzle` object. - ---- - -## Kuzzle(host, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------- | -| `host` | string | The server name (or the IP address) of a Kuzzle server installation | -| `options` | JSON object | Optional Kuzzle connection configuration | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ------------------- | ----------- | ------------------------------------------------------------------ | -------- | -| `autoQueue` | boolean | Automatically queue all requests during offline mode | `false` | -| `autoReconnect` | boolean | Automatically reconnect after a connection loss | `true` | -| `autoReplay` | boolean | Automatically replay queued requests on a `reconnected` event | `false` | -| `autoResubscribe` | boolean | Automatically renew all subscriptions on a `reconnected` event | `true` | -| `connect` | string | Manually or automatically connect to the Kuzzle instance | `auto` | -| `defaultIndex` | string | Set the default index to use | | -| `headers` | JSON object | Common headers for all sent documents | | -| `volatile` | JSON object | Common volatile data, will be sent to all future requests | | -| `offlineMode` | string | Offline mode configuration | `manual` | -| `port` | integer | Kuzzle network port | 7512 | -| `queueTTL` | integer | Time a queued request is kept during offline mode, in milliseconds | `120000` | -| `queueMaxSize` | integer | Number of maximum requests kept during offline mode | `500` | -| `replayInterval` | integer | Delay between each replayed requests, in milliseconds | `10` | -| `reconnectionDelay` | integer | number of milliseconds between reconnection attempts | `1000` | -| `ssl` | boolean | Switch Kuzzle connection to SSL mode | `false` | - -**Notes:** - -- the `offlineMode` option only accepts the `manual` and `auto` values - ---- - -## Properties - -| Property name | Type | Description | Writable? | -| -------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------- | :-------: | -| `autoQueue` | boolean | Automatically queue all requests during offline mode | Yes | -| `autoReconnect` | boolean | Automatically reconnect after a connection loss | No | -| `autoReplay` | boolean | Automatically replay queued requests on a `reconnected` event | Yes | -| `autoResubscribe` | boolean | Automatically renew all subscriptions on a `reconnected` event | No | -| `defaultIndex` | string | Kuzzle's default index to use | Yes | -| `headers` | JSON object | Common headers for all sent documents. | Yes | -| `host` | string | Target Kuzzle host name/address | No | -| `jwtToken` | string | Token used in requests for authentication. | Yes | -| `offlineQueue` | JSON object | Contains the queued requests during offline mode | No | -| `offlineQueueLoader` | function | Called before dequeuing requests after exiting offline mode, to add items at the beginning of the offline queue | Yes | -| `port` | integer | Kuzzle network port | No | -| `queueFilter` | function | Called during offline mode. Takes a request object as arguments and returns a boolean, indicating if a request can be queued | Yes | -| `queueMaxSize` | integer | Number of maximum requests kept during offline mode | Yes | -| `queueTTL` | integer | Time a queued request is kept during offline mode, in milliseconds | Yes | -| `replayInterval` | integer | Delay between each replayed requests | Yes | -| `reconnectionDelay` | integer | Number of milliseconds between reconnection attempts | No | -| `ssl` | boolean | Connect to Kuzzle using SSL | No | -| `volatile` | JSON object | Common volatile data, will be sent to all future requests | Yes | - -**Notes:** - -- if `connect` is set to `manual`, the `connect` method will have to be called manually -- the kuzzle instance will automatically queue all requests, and play them automatically once a first connection is established, regardless of the `connect` or offline mode option values. -- multiple methods allow passing specific `volatile` data. These `volatile` data will be merged with the global Kuzzle `volatile` object when sending the request, with the request specific `volatile` taking priority over the global ones. -- the `queueFilter` property is a function taking a JSON object as an argument. This object is the request sent to Kuzzle, following the [Kuzzle API](/core/1/api/essentials/query-syntax) format -- if `queueTTL` is set to `0`, requests are kept indefinitely -- The offline buffer acts like a first-in first-out (FIFO) queue, meaning that if the `queueMaxSize` limit is reached, older requests are discarded to make room for new requests -- if `queueMaxSize` is set to `0`, an unlimited number of requests is kept until the buffer is flushed -- the `offlineQueueLoader` must be set with a function, taking no argument, and returning an array of objects containing a `query` member with a Kuzzle query to be replayed, and an optional `cb` member with the corresponding callback to invoke with the query result -- updates to `host`, `port`, `autoReconnect`, `reconnectionDelay` and `sslConnection` properties will only take effect on next `connect` call - ---- - -## Callback response - -If the connection succeeds, resolves to the `Kuzzle` object itself. -If the `connect` option is set to `manual`, the callback will be called after the `connect` method is resolved. - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/kuzzle/constructor/snippets/constructor-1.java b/doc/2/core-classes/kuzzle/constructor/snippets/constructor-1.java deleted file mode 100644 index 4fe6ff7e..00000000 --- a/doc/2/core-classes/kuzzle/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,22 +0,0 @@ - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; - -Options options = new Options(); - -options.setDefaultIndex("some index") - .setAutoReconnect(true), - .setHeaders(new JSONObject().put("someheader", "value")) - .setPort(7512); - -Kuzzle kuzzle = new Kuzzle("localhost", options, new ResponseListener() { - @Override - public void onSuccess(Void object) { - // invoked once connected, object contains the kuzzle instance - } - - @Override - public void onError(JSONObject error) { - // Handle connection error - } -}); diff --git a/doc/2/core-classes/kuzzle/create-index/index.md b/doc/2/core-classes/kuzzle/create-index/index.md deleted file mode 100644 index af0648b2..00000000 --- a/doc/2/core-classes/kuzzle/create-index/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: createIndex -description: Kuzzle:createIndex ---- - -# createIndex - -Create a new empty index, with no associated mapping. - ---- - -## createIndex([index], [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------------------------------------------------------------------------------- | -| `index` | string | Optional index to query. If no set, defaults to [Kuzzle.defaultIndex](/sdk/java/2/core-classes/kuzzle#properties) | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the index creation status. - -## Usage - -<<< ./snippets/create-index-1.java - -> Callback response: - -```json -{ - "acknowledged": true, - "shards_acknowledged": true -} -``` diff --git a/doc/2/core-classes/kuzzle/create-index/snippets/create-index-1.java b/doc/2/core-classes/kuzzle/create-index/snippets/create-index-1.java deleted file mode 100644 index 13dc0831..00000000 --- a/doc/2/core-classes/kuzzle/create-index/snippets/create-index-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.createIndex("myIndex", new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // result var contains the creation status of myIndex. - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/create-my-credentials/index.md b/doc/2/core-classes/kuzzle/create-my-credentials/index.md deleted file mode 100644 index 57776eed..00000000 --- a/doc/2/core-classes/kuzzle/create-my-credentials/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -code: true -type: page -title: createMyCredentials -description: Kuzzle:createMyCredentials ---- - -# createMyCredentials - -Create the current user's credentials for the specified strategy. The credentials required will depend on the authentication plugin and strategy. - ---- - -## createMyCredentials(strategy, credentials, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------- | -| `strategy` | string | Strategy you want to create credentials for | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the created credentials. - -## Usage - -<<< ./snippets/create-my-credentials-1.java diff --git a/doc/2/core-classes/kuzzle/create-my-credentials/snippets/create-my-credentials-1.java b/doc/2/core-classes/kuzzle/create-my-credentials/snippets/create-my-credentials-1.java deleted file mode 100644 index 85ea1917..00000000 --- a/doc/2/core-classes/kuzzle/create-my-credentials/snippets/create-my-credentials-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "bar"); - -kuzzle.createMyCredentials("local", credentials, new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // result var contains the new credentials and the kuid of the user - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/delete-my-credentials/index.md b/doc/2/core-classes/kuzzle/delete-my-credentials/index.md deleted file mode 100644 index 2d60d5b9..00000000 --- a/doc/2/core-classes/kuzzle/delete-my-credentials/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: deleteMyCredentials -description: Kuzzle:deleteMyCredentials ---- - -# deleteMyCredentials - -Delete the current user's credentials for the specified `strategy`. - ---- - -## deleteMyCredentials(strategy, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------- | -| `strategy` | string | Strategy you want to delete credentials from | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the query status. - -## Usage - -<<< ./snippets/delete-my-credentials-1.java diff --git a/doc/2/core-classes/kuzzle/delete-my-credentials/snippets/delete-my-credentials-1.java b/doc/2/core-classes/kuzzle/delete-my-credentials/snippets/delete-my-credentials-1.java deleted file mode 100644 index 23ae2c7e..00000000 --- a/doc/2/core-classes/kuzzle/delete-my-credentials/snippets/delete-my-credentials-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.deleteMyCredentials("local", new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // result var contains the query status - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/disconnect/index.md b/doc/2/core-classes/kuzzle/disconnect/index.md deleted file mode 100644 index d4efaa32..00000000 --- a/doc/2/core-classes/kuzzle/disconnect/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -code: true -type: page -title: disconnect -description: Kuzzle:disconnect ---- - -# disconnect - -Closes the current connection, and frees all allocated resources. -Contrary to the `offline` state (when the network connection is unexpectedly lost), `disconnect()` invalidates the instance, which cannot be used until [connect()](/sdk/java/2/core-classes/kuzzle/connect) is explicitly called. -This action does not trigger a `disconnected` event since this event is triggered when an unexpected disconnection occur. - -## Usage - -<<< ./snippets/disconnect-1.java diff --git a/doc/2/core-classes/kuzzle/disconnect/snippets/disconnect-1.java b/doc/2/core-classes/kuzzle/disconnect/snippets/disconnect-1.java deleted file mode 100644 index 80a048ab..00000000 --- a/doc/2/core-classes/kuzzle/disconnect/snippets/disconnect-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.disconnect(); diff --git a/doc/2/core-classes/kuzzle/flush-queue/index.md b/doc/2/core-classes/kuzzle/flush-queue/index.md deleted file mode 100644 index c272949e..00000000 --- a/doc/2/core-classes/kuzzle/flush-queue/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: flushQueue -description: Kuzzle:flushQueue ---- - -# flushQueue - -Empties the offline queue without replaying it. - ---- - -## Return Value - -Returns the `Kuzzle` SDK instance to allow chaining. - -## Usage - -<<< ./snippets/flush-queue-1.java diff --git a/doc/2/core-classes/kuzzle/flush-queue/snippets/flush-queue-1.java b/doc/2/core-classes/kuzzle/flush-queue/snippets/flush-queue-1.java deleted file mode 100644 index 3c277c58..00000000 --- a/doc/2/core-classes/kuzzle/flush-queue/snippets/flush-queue-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.flushQueue(); diff --git a/doc/2/core-classes/kuzzle/get-all-statistics/index.md b/doc/2/core-classes/kuzzle/get-all-statistics/index.md deleted file mode 100644 index 200c22d5..00000000 --- a/doc/2/core-classes/kuzzle/get-all-statistics/index.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -code: true -type: page -title: getAllStatistics -description: Kuzzle:getAllStatistics ---- - -# getAllStatistics - -> Callback response example: - -```json -[ - { - "connections": { "socketio": 1 }, - "ongoingRequests": { "rest": 0, "socketio": 0 }, - "completedRequests": { "mqtt": 37, "socketio": 17 }, - "failedRequests": { "socketio": 1 }, - "timestamp": "1453110641308" - }, - { - "connections": { "socketio": 1 }, - "ongoingRequests": { "rest": 0, "socketio": 0 }, - "completedRequests": { "socketio": 34 }, - "failedRequests": { "socketio": 3 }, - "timestamp": "1453110642308" - }, - { - "connections": {}, - "ongoingRequests": { "rest": 0, "socketio": 0 }, - "completedRequests": { "socketio": 40 }, - "failedRequests": {}, - "timestamp": "1453110643308" - } -] -``` - -Kuzzle monitors active connections, and ongoing/completed/failed requests. -This method returns all available statistics from Kuzzle. - ---- - -## getAllStatistics([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -### Callback Response - -Returns an array of JSON objects that each contain a statistics frame. - -## Usage - -<<< ./snippets/get-all-statistics-1.java diff --git a/doc/2/core-classes/kuzzle/get-all-statistics/snippets/get-all-statistics-1.java b/doc/2/core-classes/kuzzle/get-all-statistics/snippets/get-all-statistics-1.java deleted file mode 100644 index e54c9609..00000000 --- a/doc/2/core-classes/kuzzle/get-all-statistics/snippets/get-all-statistics-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.getAllStatistics(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] frames) { - // loop through all returned frames - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}; diff --git a/doc/2/core-classes/kuzzle/get-auto-refresh/index.md b/doc/2/core-classes/kuzzle/get-auto-refresh/index.md deleted file mode 100644 index b939352f..00000000 --- a/doc/2/core-classes/kuzzle/get-auto-refresh/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: getAutoRefresh -description: Kuzzle:getAutoRefresh ---- - -# getAutoRefresh - -The `autoRefresh` flag, when set to true, will make Kuzzle perform a -[`refresh`](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/docs-refresh.html) request -immediately after each write request, causing documents to be immediately visible in a search. - -The `getAutoRefresh` function returns the current `autoRefresh` status for the given index. - -:::warning -A refresh operation comes with some performance costs. - -While forcing the autoRefresh can be convenient on a development or test environmnent, we recommend that you avoid -using it in production or at least carefully monitor its implications before using it. -::: - ---- - -#### getAutoRefresh([index], [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------------------------------------------------------------------------------- | -| `index` | string | Optional index to query. If no set, defaults to [Kuzzle.defaultIndex](/sdk/java/2/core-classes/kuzzle#properties) | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a boolean with the index `autoRefresh` status. - -## Usage - -<<< ./snippets/get-auto-refresh-1.java diff --git a/doc/2/core-classes/kuzzle/get-auto-refresh/snippets/get-auto-refresh-1.java b/doc/2/core-classes/kuzzle/get-auto-refresh/snippets/get-auto-refresh-1.java deleted file mode 100644 index d1264b20..00000000 --- a/doc/2/core-classes/kuzzle/get-auto-refresh/snippets/get-auto-refresh-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.getAutoRefresh("myIndex", new ResponseListener() { - @Override - public void onSuccess(Boolean autoRefresh) { - // autoRefresh var contains the autoRefresh status of myIndex. - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/get-jwt-token/index.md b/doc/2/core-classes/kuzzle/get-jwt-token/index.md deleted file mode 100644 index a2b37ff1..00000000 --- a/doc/2/core-classes/kuzzle/get-jwt-token/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: getJwtToken -description: Kuzzle:getJwtToken ---- - -# getJwtToken - -Get internal jwtToken used to request kuzzle. - ---- - -## Return Value - -Returns the stored JWT as a string value. - -## Usage - -<<< ./snippets/get-jwt-token-1.java diff --git a/doc/2/core-classes/kuzzle/get-jwt-token/snippets/get-jwt-token-1.java b/doc/2/core-classes/kuzzle/get-jwt-token/snippets/get-jwt-token-1.java deleted file mode 100644 index 748795f1..00000000 --- a/doc/2/core-classes/kuzzle/get-jwt-token/snippets/get-jwt-token-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -String jwtToken = kuzzle.getJwtToken(); diff --git a/doc/2/core-classes/kuzzle/get-my-credentials/index.md b/doc/2/core-classes/kuzzle/get-my-credentials/index.md deleted file mode 100644 index f32296b0..00000000 --- a/doc/2/core-classes/kuzzle/get-my-credentials/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: getMyCredentials -description: Kuzzle:getMyCredentials ---- - -# getMyCredentials - -Get [credential information](/core/1/guides/essentials/user-authentication#user-credentials) for the current user. - ---- - -## getMyCredentials(strategy, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `strategy` | string | Strategy you want to get credentials from | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the credentials for the provided authentication strategy. - -## Usage - -<<< ./snippets/get-my-credentials-1.java - -> Callback response - -```json -{ - "username": "foo", - "kuid": "" -} -``` diff --git a/doc/2/core-classes/kuzzle/get-my-credentials/snippets/get-my-credentials-1.java b/doc/2/core-classes/kuzzle/get-my-credentials/snippets/get-my-credentials-1.java deleted file mode 100644 index afe80354..00000000 --- a/doc/2/core-classes/kuzzle/get-my-credentials/snippets/get-my-credentials-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.getMyCredentials("local", new ResponseListener() { - @Override - public void onSuccess(JSONObject credentials) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/get-my-rights/index.md b/doc/2/core-classes/kuzzle/get-my-rights/index.md deleted file mode 100644 index c8fd5a9d..00000000 --- a/doc/2/core-classes/kuzzle/get-my-rights/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -code: true -type: page -title: getMyRights -description: Kuzzle:getMyRights ---- - -# getMyRights - -Gets the rights for the current user. - ---- - -## getMyRights([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of rights. - -## Usage - -<<< ./snippets/get-my-rights-1.java - -> Callback response - -```json -[ - { - "controller": "my-controller", - "action": "my-action", - "index": "*", - "collection": "*", - "value": "allowed" - }, - { - "controller": "another-controller", - "action": "*", - "index": "my-index", - "collection": "*", - "value": "conditional" - } -] -``` diff --git a/doc/2/core-classes/kuzzle/get-my-rights/snippets/get-my-rights-1.java b/doc/2/core-classes/kuzzle/get-my-rights/snippets/get-my-rights-1.java deleted file mode 100644 index e6e02008..00000000 --- a/doc/2/core-classes/kuzzle/get-my-rights/snippets/get-my-rights-1.java +++ /dev/null @@ -1,13 +0,0 @@ - - -kuzzle - .security - .getMyRights(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] rights) { - } - - @Override - public void onError(JSONObject error) { - } - }); diff --git a/doc/2/core-classes/kuzzle/get-server-info/index.md b/doc/2/core-classes/kuzzle/get-server-info/index.md deleted file mode 100644 index e86a5787..00000000 --- a/doc/2/core-classes/kuzzle/get-server-info/index.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -code: true -type: page -title: getServerInfo -description: Kuzzle:getServerInfo ---- - -# getServerInfo - -> Callback response example: - -```json -{ - "kuzzle": { - "api": { - "routes": { - "controller1": { - "action1": { - "controller": "controller1", - "action": "action1", - "http": { - "verb": "GET", - "url": "/action1/url" - } - }, - "action2": { - "controller": "controller1", - "action": "action2", - "http": { - "verb": "POST", - "url": "/action2/url" - } - }, - { - "...": "..." - } - }, - "pluginName/controller": { - "action": { - "controller": "pluginName/controller", - "action": "action", - "http": { - "verb": "GET", - "url": "/action/url" - } - }, - { - "...": " ..." - } - }, - { - "...": "..." - } - }, - "version": "" - }, - "memoryUsed": 12345, - "nodeVersion": "v6.9.5", - "plugins": {}, - "system": { - "cpus": [ - { - "cpu1": "informations" - }, - { - "...": "..." - } - ], - "memory": { - "free": 123456, - "total": 1234567 - } - }, - "uptime": "", - "version": "" - }, - "services": { - "internalCache": { - "kuzzle memory cache": "informations", - "...": "..." - }, - "memoryStorage": { - "API memory storage": "informations", - "...": "..." - }, - { - "...": "..." - } - } -} -``` - -Retrieves information about Kuzzle plugins and active services. - ---- - -## getServerInfo([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a JSON object containing server information. - -## Usage - -<<< ./snippets/get-server-info-1.java diff --git a/doc/2/core-classes/kuzzle/get-server-info/snippets/get-server-info-1.java b/doc/2/core-classes/kuzzle/get-server-info/snippets/get-server-info-1.java deleted file mode 100644 index f9a0f8ac..00000000 --- a/doc/2/core-classes/kuzzle/get-server-info/snippets/get-server-info-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.getServerInfo(new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // Handle success - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/get-statistics/index.md b/doc/2/core-classes/kuzzle/get-statistics/index.md deleted file mode 100644 index 1c365fa3..00000000 --- a/doc/2/core-classes/kuzzle/get-statistics/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: getStatistics -description: Kuzzle:getStatistics ---- - -# getStatistics - -> Without argument, retrieves the last statistic frame in an array: -> When providing a timestamp, retrieves all frames recorded after that timestamp: -> Kuzzle server monitors active connections, and ongoing/completed/failed requests. -> This method returns either the last statistics frame, or a set of frames starting from a provided timestamp. - ---- - -## getStatistics([timestamp], [options], callback) - -| Arguments | Type | Description | -| ----------- | ----------- | ---------------------------------------------------------------- | -| `timestamp` | Epoch time | Optional starting time from which the frames are to be retrieved | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - -**Note:** Kuzzle statistics are cleaned up regularly. If the timestamp is set too far in the past, then this method will return all available statistics. - ---- - -### Callback Response - -Returns an `array` containing one or more statistics frame (as JSON objects). - -## Usage - -<<< ./snippets/get-statistics-1.java - -<<< ./snippets/get-statistics-2.java - -> Callback response: - -```json -[ - { - "connections": { "socketio": 1 }, - "ongoingRequests": { "rest": 0, "socketio": 0 }, - "completedRequests": { "mqtt": 37, "socketio": 17 }, - "failedRequests": { "socketio": 1 }, - "timestamp": "1453110641308" - } -] -``` diff --git a/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-1.java b/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-1.java deleted file mode 100644 index 269a5471..00000000 --- a/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.getStatistics(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] statistics) { - // ... - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-2.java b/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-2.java deleted file mode 100644 index 0e852ace..00000000 --- a/doc/2/core-classes/kuzzle/get-statistics/snippets/get-statistics-2.java +++ /dev/null @@ -1,13 +0,0 @@ - -// Date can be either in ISO format or a timestamp (utc, in milliseconds) -kuzzle.getStatistics("2015-11-15T13:36:45.558Z", new ResponseListener() { - @Override - public void onSuccess(JSONObject[] statistics) { - // ... - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}; diff --git a/doc/2/core-classes/kuzzle/index.md b/doc/2/core-classes/kuzzle/index.md deleted file mode 100644 index 54c7fde2..00000000 --- a/doc/2/core-classes/kuzzle/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -code: true -type: branch -title: Kuzzle -description: Kuzzle documentation -order: 400 ---- diff --git a/doc/2/core-classes/kuzzle/list-collections/index.md b/doc/2/core-classes/kuzzle/list-collections/index.md deleted file mode 100644 index 0b01279b..00000000 --- a/doc/2/core-classes/kuzzle/list-collections/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -code: true -type: page -title: listCollections -description: Kuzzle:listCollections ---- - -# listCollections - -Returns the list of known collections contained in a specified index. - ---- - -## listCollections([index], [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------- | -| `index` | string | Index containing the collections to be listed | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `from` | integer | Determines the starting point of the pagination. By default, start at the beggining | `0` | -| `size` | integer | Determines the size of the returned result set. By default, no limit is applied | `undefined` | -| `type` | string | Get either `stored` collections or `realtime` ones. By default, list `all` collections | `all` | - -If no `index` argument is provided, the `defaultIndex` property is used. If no default index is found, this method throws an error. - ---- - -## Callback Response - -Returns an array of JSON objects containing the list of stored and/or realtime collections on the provided index. - -## Usage - -<<< ./snippets/list-collections-1.java - -> Callback response: - -```json -[ - { "name": "realtime_1", "type": "realtime" }, - { "name": "realtime_2", "type": "realtime" }, - { "name": "realtime_...", "type": "realtime" }, - { "name": "realtime_n", "type": "realtime" }, - { "name": "stored_1", "type": "stored" }, - { "name": "stored_2", "type": "stored" }, - { "name": "stored_...", "type": "stored" }, - { "name": "stored_n", "type": "stored" } -] -``` diff --git a/doc/2/core-classes/kuzzle/list-collections/snippets/list-collections-1.java b/doc/2/core-classes/kuzzle/list-collections/snippets/list-collections-1.java deleted file mode 100644 index 5f40b4bc..00000000 --- a/doc/2/core-classes/kuzzle/list-collections/snippets/list-collections-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.listCollections("index", new ResponseListener() { - @Override - public void onSuccess(JSONObject[] collections) { - // ... - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/list-indexes/index.md b/doc/2/core-classes/kuzzle/list-indexes/index.md deleted file mode 100644 index e117e35c..00000000 --- a/doc/2/core-classes/kuzzle/list-indexes/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: listIndexes -description: Kuzzle:listIndexes ---- - -# listIndexes - -Returns the list of indexes stored in Kuzzle. - ---- - -## listIndexes([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an `array` of index names. - -## Usage - -<<< ./snippets/list-indexes-1.java - -> Callback response: - -```json -["index", "another index", "..."] -``` diff --git a/doc/2/core-classes/kuzzle/list-indexes/snippets/list-indexes-1.java b/doc/2/core-classes/kuzzle/list-indexes/snippets/list-indexes-1.java deleted file mode 100644 index 9fa6a116..00000000 --- a/doc/2/core-classes/kuzzle/list-indexes/snippets/list-indexes-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.listIndexes(new ResponseListener() { - @Override - public void onSuccess(String[] result) { - // ... - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/login/index.md b/doc/2/core-classes/kuzzle/login/index.md deleted file mode 100644 index 4180a4b7..00000000 --- a/doc/2/core-classes/kuzzle/login/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: login -description: Kuzzle:login ---- - -# login - -Login a user using a specified strategy and their credentials. - -If the Kuzzle response contains a JWT Token, the Kuzzle SDK token is set and the `loginAttempt` event is fired immediately with the following object: -`{ success: true }` -This is the case, for instance, with the `local` authentication strategy. - -If the request succeeds but there is no token, then it means that the chosen strategy is a two-steps authentication method, such as the OAUTH strategy. In that case, the `loginAttempt` event is **not** fired. To complete the login, the `setJwtToken` method must be called either with a token or with an appropriate Kuzzle response. - -If the login attempt fails, the `loginAttempt` event is fired with the following response: -`{ success: false, error: 'error message' }` - -:::info -This method is non-queuable, meaning that during offline mode, it will be discarded and the callback will be called with an error. -::: - ---- - -## login(strategy, [credentials], [expiresIn], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------------------ | -| `strategy` | string | Authentication strategy (local, facebook, github, ...) | -| `credentials` | JSON object | Optional login credentials, depending on the strategy | -| `expiresIn` | _varies_ | Login expiration time | -| `callback` | function | Optional callback handling the response | - -**Note:** If the `expiresIn` argument is not set, the default token expiration value will be taken from the Kuzzle server configuration. - -By default, Kuzzle comes with the [kuzzle-plugin-auth-passport-local](https://github.com/kuzzleio/kuzzle-plugin-auth-passport-local) plugin, which provides the `local` authentication strategy. -This strategy requires a `username` and `password` as `credentials` - ---- - -## Callback Response - -Returns a JSON object containing the Kuzzle response. - -## Usage - -<<< ./snippets/login-1.java diff --git a/doc/2/core-classes/kuzzle/login/snippets/login-1.java b/doc/2/core-classes/kuzzle/login/snippets/login-1.java deleted file mode 100644 index db475b1a..00000000 --- a/doc/2/core-classes/kuzzle/login/snippets/login-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject credentials = new JSONObject() - .put("username", "John Doe") - .put("password", "my secret password"); - -kuzzle.login("local", credentials, 30000, new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // ... - } - - @Override - public void onError() { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/logout/index.md b/doc/2/core-classes/kuzzle/logout/index.md deleted file mode 100644 index 6bf51b09..00000000 --- a/doc/2/core-classes/kuzzle/logout/index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -code: true -type: page -title: logout -description: Kuzzle:logout ---- - -# logout - -Logs the user out. - -:::info -This method is non-queuable, meaning that during offline mode, it will be discarded and the callback will be called with an error. -::: - ---- - -## logout([callback]) - -| Arguments | Type | Description | -| ---------- | -------- | --------------------------------------- | -| `callback` | function | Optional callback handling the response | - -This method empties the `jwtToken` property - ---- - -## Return value - -Returns the `Kuzzle` SDK object to allow chaining. - ---- - -## Callback Response - -Returns the `Kuzzle` SDK object once the logout process is complete, either successfully or not. -The `Kuzzle` SDK object will unset the `jwtToken` property if the user is successfully logged out. - -## Usage - -<<< ./snippets/logout-1.java diff --git a/doc/2/core-classes/kuzzle/logout/snippets/logout-1.java b/doc/2/core-classes/kuzzle/logout/snippets/logout-1.java deleted file mode 100644 index df71fa54..00000000 --- a/doc/2/core-classes/kuzzle/logout/snippets/logout-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.logout(new ResponseListener() { - @Override - public void onSuccess(Void result) { - // ... - } - - @Override - public void onError() { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/memory-storage/index.md b/doc/2/core-classes/kuzzle/memory-storage/index.md deleted file mode 100644 index 8f040194..00000000 --- a/doc/2/core-classes/kuzzle/memory-storage/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -code: true -type: page -title: memoryStorage -description: Kuzzle:memoryStorage ---- - -## memoryStorage - -A [MemoryStorage](/sdk/java/2/core-classes/memory-storage) singleton. diff --git a/doc/2/core-classes/kuzzle/now/index.md b/doc/2/core-classes/kuzzle/now/index.md deleted file mode 100644 index 670e315e..00000000 --- a/doc/2/core-classes/kuzzle/now/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: now -description: Kuzzle:now ---- - -# now - -Retrieves the current Kuzzle time. - ---- - -## now([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an `integer` containing the current Kuzzle time, encoded as an UTC Epoch time in milliseconds. - -## Usage - -<<< ./snippets/now-1.java - -> Callback response: - -```json -1447151167622 -``` diff --git a/doc/2/core-classes/kuzzle/now/snippets/now-1.java b/doc/2/core-classes/kuzzle/now/snippets/now-1.java deleted file mode 100644 index 2e94afb5..00000000 --- a/doc/2/core-classes/kuzzle/now/snippets/now-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.now(new ResponseListener() { - @Override - public void onSuccess(Date object) { - // 'object' contains the Kuzzle timestamp (utc, in milliseconds) - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/query/index.md b/doc/2/core-classes/kuzzle/query/index.md deleted file mode 100644 index 6debb90e..00000000 --- a/doc/2/core-classes/kuzzle/query/index.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -code: true -type: page -title: query -description: Kuzzle:query ---- - -## query - -Base method used to send queries to Kuzzle, following the [API Documentation](/core/1/api). - -:::warning -This is a low-level method, exposed to allow advanced SDK users to bypass high-level methods. -Refer to Kuzzle's API Reference [here](/core/1/api) -::: - ---- - -## query(queryArgs, query, [options], [callback]) - -| Argument | Type | Description | -| ----------- | ----------- | -------------------- | -| `queryArgs` | JSON object | Query base arguments | -| `query` | JSON object | Query to execute | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback | - ---- - -## queryArgs - -`queryArgs` is a JSON object allowing Kuzzle to route your query to the right API method: - -| Option | Type | Description | Required? | -| ------------ | ------ | --------------------------------------- | --------- | -| `controller` | string | API Controller argument | required | -| `action` | string | API Controller action | required | -| `index` | string | Index concerned by the action | optional | -| `collection` | string | Data collection concerned by the action | optional | - ---- - -## query - -## `query` is a JSON object containing arguments specific to the query, such as a `body` property, a JWT hash, a document `_id`, or generic query options (such as `from` or `size` for [search queries](/core/1/api/controllers/document/search)) - -## Options - -| Option | Type | Description | Default | -| ---------- | ----------- | ------------------------------------------------------------- | ------- | -| `volatile` | JSON object | Additional information passed to notifications to other users | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - ---- - -## Callback Response - -Returns a `JSON object` containing the raw Kuzzle response. - -## Usage - -<<< ./snippets/query-1.java - -> Callback response: - -```json -{ - "error": null, - "result": { - "action": "action", - "controller": "controller", - "requestId": "bf87b930-7c02-11e5-ab10-dfa9e9fd2e07", - "other properties": "depends of the query made" - } -} -``` diff --git a/doc/2/core-classes/kuzzle/query/snippets/query-1.java b/doc/2/core-classes/kuzzle/query/snippets/query-1.java deleted file mode 100644 index 6e407d5e..00000000 --- a/doc/2/core-classes/kuzzle/query/snippets/query-1.java +++ /dev/null @@ -1,22 +0,0 @@ - -QueryArgs args = new QueryArgs(); -args.controller = "controller"; -args.action = "action"; - -JSONObject query = new JSONObject() - .put("body", new JSONObject() - .put("foo", "bar") - ) - .put("other", "argument"); - -kuzzle.query(args, query, new OnQueryDoneListener() { - @Override - public void onSuccess(JSONObject object) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/kuzzle/refresh-index/index.md b/doc/2/core-classes/kuzzle/refresh-index/index.md deleted file mode 100644 index a92465f7..00000000 --- a/doc/2/core-classes/kuzzle/refresh-index/index.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -code: true -type: page -title: refreshIndex -description: Kuzzle:refreshIndex ---- - -# refreshIndex - -When writing or deleting documents in Kuzzle, the update needs to be indexed before being reflected -in the search index. -By default, this operation can take up to 1 second. - -Given an index, the `refresh` action forces a [`refresh`](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/docs-refresh.html), -on it, making the documents visible to search immediately. - -:::warning -A refresh operation comes with some performance costs. - -From the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docs-refresh.html): - -> "While a refresh is much lighter than a commit, it still has a performance cost. A manual refresh can be useful when writing tests, but don’t do a manual refresh every time you index a document in production; it will hurt your performance. Instead, your application needs to be aware of the near real-time nature of Elasticsearch and make allowances for it." -::: - ---- - -## refreshIndex([index], [options], [callback]) - -| Argument | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `index` | string | _Optional_. The index to refresh. If not set, defaults to [kuzzle.defaultIndex](/sdk/java/2/core-classes/kuzzle#properties). | -| `options` | JSON object | Optional parameters | -| `callback` | function | _Optional_. Callback handling the response. | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - ---- - -## Callback Response - -Returns a JSON structure matching the response from Elasticsearch. - -## Usage - -<<< ./snippets/refresh-index-1.java diff --git a/doc/2/core-classes/kuzzle/refresh-index/snippets/refresh-index-1.java b/doc/2/core-classes/kuzzle/refresh-index/snippets/refresh-index-1.java deleted file mode 100644 index a3f53613..00000000 --- a/doc/2/core-classes/kuzzle/refresh-index/snippets/refresh-index-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.refreshIndex("myIndex"); diff --git a/doc/2/core-classes/kuzzle/remove-all-listeners/index.md b/doc/2/core-classes/kuzzle/remove-all-listeners/index.md deleted file mode 100644 index ac32ec98..00000000 --- a/doc/2/core-classes/kuzzle/remove-all-listeners/index.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -code: true -type: page -title: removeAllListeners -description: Kuzzle:removeAllListeners ---- - -# removeAllListeners - -Removes all listeners, either from a specific event or from all events - ---- - -## removeAllListeners([event]) - -| Arguments | Type | Description | -| --------- | ------ | -------------------------------------------------------------------------------- | -| `event` | string | One of the event described in the `Event Handling` section of this documentation | - ---- - -## Return Value - -Returns the `Kuzzle` object to allow chaining. - -## Usage - -<<< ./snippets/remove-all-listeners-1.java diff --git a/doc/2/core-classes/kuzzle/remove-all-listeners/snippets/remove-all-listeners-1.java b/doc/2/core-classes/kuzzle/remove-all-listeners/snippets/remove-all-listeners-1.java deleted file mode 100644 index 1f1c54c2..00000000 --- a/doc/2/core-classes/kuzzle/remove-all-listeners/snippets/remove-all-listeners-1.java +++ /dev/null @@ -1,6 +0,0 @@ - -// Removes all listeners on the "unsubscribed" global event -kuzzle.removeAllListeners(Event.disconnected); - -// Removes all listeners on all global events -kuzzle.removeAllListeners(); diff --git a/doc/2/core-classes/kuzzle/remove-listener/index.md b/doc/2/core-classes/kuzzle/remove-listener/index.md deleted file mode 100644 index 55b43059..00000000 --- a/doc/2/core-classes/kuzzle/remove-listener/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: removeListener -description: Kuzzle:removeListener ---- - -# removeListener - -Remove a listener from an event. - ---- - -## removeListener(event, callback) - -| Arguments | Type | Description | -| ---------- | --------------- | --------------------------------------------------------------------------------- | -| `event` | string | One of the events described in the `Event Handling` section of this documentation | -| `callback` | function/object | the callback | - ---- - -## Return Value - -Returns the `Kuzzle` object to allow chaining. - -## Usage - -<<< ./snippets/remove-listener-1.java diff --git a/doc/2/core-classes/kuzzle/remove-listener/snippets/remove-listener-1.java b/doc/2/core-classes/kuzzle/remove-listener/snippets/remove-listener-1.java deleted file mode 100644 index cd1aa99d..00000000 --- a/doc/2/core-classes/kuzzle/remove-listener/snippets/remove-listener-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.removeListener(Event.disconnected, eventListener); diff --git a/doc/2/core-classes/kuzzle/replay-queue/index.md b/doc/2/core-classes/kuzzle/replay-queue/index.md deleted file mode 100644 index 40fd9632..00000000 --- a/doc/2/core-classes/kuzzle/replay-queue/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: replayQueue -description: Kuzzle:replayQueue ---- - -# replayQueue - -Replays the requests queued during offline mode. Works only if the SDK is not in a `disconnected` state, and if the `autoReplay` option is set to `false`. - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - -## Usage - -<<< ./snippets/replay-queue-1.java diff --git a/doc/2/core-classes/kuzzle/replay-queue/snippets/replay-queue-1.java b/doc/2/core-classes/kuzzle/replay-queue/snippets/replay-queue-1.java deleted file mode 100644 index 5f4f4ed7..00000000 --- a/doc/2/core-classes/kuzzle/replay-queue/snippets/replay-queue-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.replayQueue(); diff --git a/doc/2/core-classes/kuzzle/security/index.md b/doc/2/core-classes/kuzzle/security/index.md deleted file mode 100644 index cb913ffa..00000000 --- a/doc/2/core-classes/kuzzle/security/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -code: true -type: page -title: security -description: Kuzzle:security ---- - -# security - -A [Security](/sdk/java/2/core-classes/security) singleton. diff --git a/doc/2/core-classes/kuzzle/set-auto-refresh/index.md b/doc/2/core-classes/kuzzle/set-auto-refresh/index.md deleted file mode 100644 index 722e87f1..00000000 --- a/doc/2/core-classes/kuzzle/set-auto-refresh/index.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -code: true -type: page -title: setAutoRefresh -description: Kuzzle:setAutoRefresh ---- - -# setAutoRefresh - -The `autoRefresh` flag, when set to true, will make Kuzzle perform a -[`refresh`](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/docs-refresh.html) request -immediately after each write request, causing documents to be immediately visible in a search. - -Given an index, the `setAutoRefresh` function updates its `autoRefresh` status. - -:::warning -A refresh operation comes with some performance costs. - - -While forcing the autoRefresh can be convenient on a development or test environmnent, we recommend that you avoid -using it in production or at least carefully monitor its implications before using it. -::: - ---- - -## setAutoRefresh([index], autoRefresh, [options], [callback]) - -| Argument | Type | Description | -| ------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `index` | string | _Optional_ The index to set the `autoRefresh` for. If not set, defaults to [kuzzle.defaultIndex](/sdk/java/2/core-classes/kuzzle#properties). | -| `autoRefresh` | boolean | The value to set for the `autoRefresh` setting. | -| `options` | JSON object | Optional parameters | -| `callback` | function | _Optional_ Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - ---- - -## Callback Response - -Returns a boolean with the new `autoRefresh` status. - -## Usage - -<<< ./snippets/set-auto-refresh-1.java diff --git a/doc/2/core-classes/kuzzle/set-auto-refresh/snippets/set-auto-refresh-1.java b/doc/2/core-classes/kuzzle/set-auto-refresh/snippets/set-auto-refresh-1.java deleted file mode 100644 index 1adaa881..00000000 --- a/doc/2/core-classes/kuzzle/set-auto-refresh/snippets/set-auto-refresh-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.setAutoRefresh("myIndex", true); diff --git a/doc/2/core-classes/kuzzle/set-default-index/index.md b/doc/2/core-classes/kuzzle/set-default-index/index.md deleted file mode 100644 index c69c219c..00000000 --- a/doc/2/core-classes/kuzzle/set-default-index/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -code: true -type: page -title: setDefaultIndex -description: Kuzzle:setDefaultIndex ---- - -# setDefaultIndex - -Set the default index. Has the same effect than the `defaultIndex` constructor option. - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. diff --git a/doc/2/core-classes/kuzzle/set-headers/index.md b/doc/2/core-classes/kuzzle/set-headers/index.md deleted file mode 100644 index baff9fb6..00000000 --- a/doc/2/core-classes/kuzzle/set-headers/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -code: true -type: page -title: setHeaders -description: Kuzzle:setHeaders ---- - -# setHeaders - -This is a helper function returning itself, allowing to easily chain calls. - ---- - -## setHeaders(content, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `content` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return value - -Returns the `Kuzzle` object to allow chaining. - -## Usage - -<<< ./snippets/set-headers-1.java diff --git a/doc/2/core-classes/kuzzle/set-headers/snippets/set-headers-1.java b/doc/2/core-classes/kuzzle/set-headers/snippets/set-headers-1.java deleted file mode 100644 index 74fe0517..00000000 --- a/doc/2/core-classes/kuzzle/set-headers/snippets/set-headers-1.java +++ /dev/null @@ -1,4 +0,0 @@ - -JSONObject headers = new JSONObject().put("someContent", "someValue"); - -kuzzle.setHeaders(headers, true); diff --git a/doc/2/core-classes/kuzzle/set-jwt-token/index.md b/doc/2/core-classes/kuzzle/set-jwt-token/index.md deleted file mode 100644 index b92610bd..00000000 --- a/doc/2/core-classes/kuzzle/set-jwt-token/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -code: true -type: page -title: setJwtToken -description: Kuzzle:setJwtToken ---- - -# setJwtToken - -Sets the internal JWT token which will be used when making requests to Kuzzle. - -If the provided token is valid, a `loginAttempt` event is fired with the following object: -`{ success: true }` - -If not, the `loginAttempt` event is fired with the following response: -`{ success: false, error: 'error message' }` - ---- - -## setJwtToken(jwtToken) - -| Arguments | Type | Description | -| ---------- | ------ | ----------------------------------- | -| `jwtToken` | string | Previously generated JSON Web Token | - ---- - -## setJwtToken(kuzzleResponse) - -| Arguments | Type | Description | -| ---------------- | ----------- | ----------------------------------------------------------- | -| `kuzzleResponse` | JSON object | Final Kuzzle response from a 2-steps authentication process | - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - -## Usage - -<<< ./snippets/set-jwt-token-1.java diff --git a/doc/2/core-classes/kuzzle/set-jwt-token/snippets/set-jwt-token-1.java b/doc/2/core-classes/kuzzle/set-jwt-token/snippets/set-jwt-token-1.java deleted file mode 100644 index d87640d2..00000000 --- a/doc/2/core-classes/kuzzle/set-jwt-token/snippets/set-jwt-token-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -// Directly with a JWT Token -kuzzle.setJwtToken("some jwt token"); - -/* - Or with a Kuzzle response. - For instance, the final OAUTH2 response is obtained with a redirection from Kuzzle, - and it can be provided to this method directly. - - Here, "authenticationResponse" is an instance of JSONObject - */ -kuzzle.setJwtToken(authenticationResponse) diff --git a/doc/2/core-classes/kuzzle/start-queuing/index.md b/doc/2/core-classes/kuzzle/start-queuing/index.md deleted file mode 100644 index c9a3d5f0..00000000 --- a/doc/2/core-classes/kuzzle/start-queuing/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: startQueuing -description: Kuzzle:startQueuing ---- - -# startQueuing - -Starts the requests queuing. Works only in offline mode, and if the [autoQueue](/sdk/java/2/core-classes/kuzzle#properties) option is set to `false`. - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - -## Usage - -<<< ./snippets/start-queuing-1.java diff --git a/doc/2/core-classes/kuzzle/start-queuing/snippets/start-queuing-1.java b/doc/2/core-classes/kuzzle/start-queuing/snippets/start-queuing-1.java deleted file mode 100644 index 938df064..00000000 --- a/doc/2/core-classes/kuzzle/start-queuing/snippets/start-queuing-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.startQueuing(); diff --git a/doc/2/core-classes/kuzzle/stop-queuing/index.md b/doc/2/core-classes/kuzzle/stop-queuing/index.md deleted file mode 100644 index c9099ff0..00000000 --- a/doc/2/core-classes/kuzzle/stop-queuing/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: stopQueuing -description: Kuzzle:stopQueuing ---- - -# stopQueuing - -Stops the requests queuing. Works only in offline mode, and if the [autoQueue](/sdk/java/2/core-classes/kuzzle#properties) option is set to `false`. - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - -## Usage - -<<< ./snippets/stop-queuing-1.java diff --git a/doc/2/core-classes/kuzzle/stop-queuing/snippets/stop-queuing-1.java b/doc/2/core-classes/kuzzle/stop-queuing/snippets/stop-queuing-1.java deleted file mode 100644 index f98144ee..00000000 --- a/doc/2/core-classes/kuzzle/stop-queuing/snippets/stop-queuing-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.stopQueuing(); diff --git a/doc/2/core-classes/kuzzle/unset-jwt-token/index.md b/doc/2/core-classes/kuzzle/unset-jwt-token/index.md deleted file mode 100644 index 7c892003..00000000 --- a/doc/2/core-classes/kuzzle/unset-jwt-token/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: unsetJwtToken -description: Kuzzle:unsetJwtToken ---- - -# unsetJwtToken - -Unsets the internal JSON Web Token used for authentication, and stops all existing subscriptions. - ---- - -## Return Value - -Returns the `Kuzzle` SDK object to allow chaining. - -## Usage - -<<< ./snippets/unset-jwt-token-1.java diff --git a/doc/2/core-classes/kuzzle/unset-jwt-token/snippets/unset-jwt-token-1.java b/doc/2/core-classes/kuzzle/unset-jwt-token/snippets/unset-jwt-token-1.java deleted file mode 100644 index d4ab38c4..00000000 --- a/doc/2/core-classes/kuzzle/unset-jwt-token/snippets/unset-jwt-token-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -kuzzle.unsetJwtToken(); diff --git a/doc/2/core-classes/kuzzle/update-my-credentials/index.md b/doc/2/core-classes/kuzzle/update-my-credentials/index.md deleted file mode 100644 index 9479d6fe..00000000 --- a/doc/2/core-classes/kuzzle/update-my-credentials/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -code: true -type: page -title: updateMyCredentials -description: Kuzzle:updateMyCredentials ---- - -# updateMyCredentials - -Update current user credentials for the specified `strategy`. The credentials to send depend on the authentication plugin and the strategy. - ---- - -## updateMyCredentials(strategy, credentials, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `strategy` | string | Strategy you want to create credentials in | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback response - -Returns an object reflecting the updated credentials. - -## Usage - -<<< ./snippets/update-my-credentials-1.java diff --git a/doc/2/core-classes/kuzzle/update-my-credentials/snippets/update-my-credentials-1.java b/doc/2/core-classes/kuzzle/update-my-credentials/snippets/update-my-credentials-1.java deleted file mode 100644 index 4e55cf5f..00000000 --- a/doc/2/core-classes/kuzzle/update-my-credentials/snippets/update-my-credentials-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "bar"); - -kuzzle.updateMyCredentials("local", credentials, new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - // result var contains the updated credentials and the kuid of the user - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/update-self/index.md b/doc/2/core-classes/kuzzle/update-self/index.md deleted file mode 100644 index 64f078f7..00000000 --- a/doc/2/core-classes/kuzzle/update-self/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: updateSelf -description: Kuzzle:updateSelf ---- - -# updateSelf - ---- - -## updateSelf(content, [options], [callback]) - -Performs a partial update on the current user. - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------- | -| `content` | JSON Object | A plain javascript object representing the user | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `Kuzzle` SDK object to allow chaining. - ---- - -## Callback Response - -Returns the updated user object. - -## Usage - -<<< ./snippets/update-self-1.java diff --git a/doc/2/core-classes/kuzzle/update-self/snippets/update-self-1.java b/doc/2/core-classes/kuzzle/update-self/snippets/update-self-1.java deleted file mode 100644 index d562c35a..00000000 --- a/doc/2/core-classes/kuzzle/update-self/snippets/update-self-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -JSONObject newContent = new JSONObject() - .put("firstname", "My Name Is") - .put("lastname", "Jonas"); - -kuzzle - .updateSelf(newContent, new ResponseListener() { - @Override - public void onSuccess(JSONObject user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/kuzzle/validate-my-credentials/index.md b/doc/2/core-classes/kuzzle/validate-my-credentials/index.md deleted file mode 100644 index 9c9895e4..00000000 --- a/doc/2/core-classes/kuzzle/validate-my-credentials/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -code: true -type: page -title: validateMyCredentials -description: Kuzzle:validateMyCredentials ---- - -# validateMyCredentials - -Update current user's credentials for the specified `strategy`. The credentials to send depend on the authentication plugin and the strategy. - ---- - -## validateMyCredentials(strategy, credentials, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `strategy` | string | Strategy you want to create credentials in | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns true or false. - -## Usage - -<<< ./snippets/validate-my-credentials-1.java diff --git a/doc/2/core-classes/kuzzle/validate-my-credentials/snippets/validate-my-credentials-1.java b/doc/2/core-classes/kuzzle/validate-my-credentials/snippets/validate-my-credentials-1.java deleted file mode 100644 index ac12b76d..00000000 --- a/doc/2/core-classes/kuzzle/validate-my-credentials/snippets/validate-my-credentials-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "bar"); - -kuzzle.validateMyCredentials("local", credentials, new ResponseListener() { - @Override - public void onSuccess(Boolean result) { - // result var contains either true or false - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/kuzzle/who-am-i/index.md b/doc/2/core-classes/kuzzle/who-am-i/index.md deleted file mode 100644 index 40993e9c..00000000 --- a/doc/2/core-classes/kuzzle/who-am-i/index.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -code: true -type: page -title: whoAmI -description: Kuzzle:whoAmI ---- - -# whoAmI - -Returns informations about the user who is currently loggedin. - ---- - -## whoAmI(callback) - -| Arguments | Type | Description | -| ---------- | -------- | ------------------------------ | -| `callback` | function | Callback handling the response | - ---- - -## Callback Response - -Returns an instantiated [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/who-am-i-1.java diff --git a/doc/2/core-classes/kuzzle/who-am-i/snippets/who-am-i-1.java b/doc/2/core-classes/kuzzle/who-am-i/snippets/who-am-i-1.java deleted file mode 100644 index 5791fefe..00000000 --- a/doc/2/core-classes/kuzzle/who-am-i/snippets/who-am-i-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.whoAmI(new ResponseListener() { - @Override - public void onSuccess(User myself) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/memory-storage/append/index.md b/doc/2/core-classes/memory-storage/append/index.md deleted file mode 100644 index b659612f..00000000 --- a/doc/2/core-classes/memory-storage/append/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: append -description: MemoryStorage:append ---- - -# append - -Appends a value to a key. If the key does not exist, it is created. - -[[_Redis documentation_]](https://redis.io/commands/append) - ---- - -## append(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to append to the key | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Return an integer containing the new length of the key's value. - -## Usage - -<<< ./snippets/append-1.java - -> Callback response: - -```json -5 -``` diff --git a/doc/2/core-classes/memory-storage/append/snippets/append-1.java b/doc/2/core-classes/memory-storage/append/snippets/append-1.java deleted file mode 100644 index cc1f2f90..00000000 --- a/doc/2/core-classes/memory-storage/append/snippets/append-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.append("key", "value", new ResponseListener() { - @Override - public void onSuccess(int newLength) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/bitcount/index.md b/doc/2/core-classes/memory-storage/bitcount/index.md deleted file mode 100644 index 821f1306..00000000 --- a/doc/2/core-classes/memory-storage/bitcount/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: bitcount -description: MemoryStorage:bitcount ---- - -# bitcount - -Counts the number of set bits (population counting) in a string. - -[[_Redis documentation_]](https://redis.io/commands/bitcount) - ---- - -## bitcount(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `end` | int | Ending offset | `-1` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `start` | int | Starting offset | `0` | - ---- - -## Callback Response - -Return an integer containing the count of set bits. - -## Usage - -<<< ./snippets/bitcount-1.java - -> Callback response: - -```json -21 -``` diff --git a/doc/2/core-classes/memory-storage/bitcount/snippets/bitcount-1.java b/doc/2/core-classes/memory-storage/bitcount/snippets/bitcount-1.java deleted file mode 100644 index 63e750ab..00000000 --- a/doc/2/core-classes/memory-storage/bitcount/snippets/bitcount-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.bitcount("key", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/bitop/index.md b/doc/2/core-classes/memory-storage/bitop/index.md deleted file mode 100644 index 9c506a4c..00000000 --- a/doc/2/core-classes/memory-storage/bitop/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: bitop -description: MemoryStorage:bitop ---- - -# bitop - -Performs a bitwise operation between multiple keys (containing string values) and stores the result in the destination key. - -[[_Redis documentation_]](https://redis.io/commands/bitop) - ---- - -## bitop(key, operation, keys, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | --------------------------------------------------------------------------- | -| `key` | string | Destination key identifier | -| `operation` | string | Bitwise operation to perform.
Allowed values: `AND`, `OR`, `XOR`, `NOT` | -| `keys` | array | list of source keys on which the bitwise operation will be applied | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the length of the new key's value. - -## Usage - -<<< ./snippets/bitop-1.java - -> Callback response: - -```json -42 -``` diff --git a/doc/2/core-classes/memory-storage/bitop/snippets/bitop-1.java b/doc/2/core-classes/memory-storage/bitop/snippets/bitop-1.java deleted file mode 100644 index 553bb0c9..00000000 --- a/doc/2/core-classes/memory-storage/bitop/snippets/bitop-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] sourceKeys = {"srckey1", "srckey2", "..."}; - -kuzzle.memoryStorage.bitop("key", "AND", sourceKeys, new ResponseListener() { - @Override - public void onSuccess(int length) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/bitpos/index.md b/doc/2/core-classes/memory-storage/bitpos/index.md deleted file mode 100644 index c00f83e8..00000000 --- a/doc/2/core-classes/memory-storage/bitpos/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: bitpos -description: MemoryStorage:bitpos ---- - -# bitpos - -Returns the position of the first bit set to 1 or 0 in a string, or in a substring. - -[[_Redis documentation_]](https://redis.io/commands/bitpos) - ---- - -## bitpos(key, bit, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `bit` | int | Bit to search.
Allowed values: `0`, `1` | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `end` | int | Ending offset | `-1` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `start` | int | Starting offset | `0` | - ---- - -## Callback Response - -Returns an integer containing the first position of the searched bit in the string value. - -## Usage - -<<< ./snippets/bitpos-1.java - -> Callback response: - -```json -0 -``` diff --git a/doc/2/core-classes/memory-storage/bitpos/snippets/bitpos-1.java b/doc/2/core-classes/memory-storage/bitpos/snippets/bitpos-1.java deleted file mode 100644 index b3530be9..00000000 --- a/doc/2/core-classes/memory-storage/bitpos/snippets/bitpos-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.bitpos("key", 0, new ResponseListener() { - @Override - public void onSuccess(int position) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/constructor/index.md b/doc/2/core-classes/memory-storage/constructor/index.md deleted file mode 100644 index 01e3d8b5..00000000 --- a/doc/2/core-classes/memory-storage/constructor/index.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -code: true -type: page -title: constructor -description: MemoryStorage:constructor -order: 1 ---- - -# Constructor - -Kuzzle's memory storage is a data store separate from the database layer. -It uses Redis internally, and most of its underlying functions are exposed by Kuzzle. - ---- - -## MemoryStorage(Kuzzle) - -| Arguments | Type | Description | -| --------- | ------ | ------------------------------------------------------------------------ | -| `Kuzzle` | object | An instantiated [Kuzzle](/sdk/java/2/core-classes/kuzzle) SDK object | - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/memory-storage/constructor/snippets/constructor-1.java b/doc/2/core-classes/memory-storage/constructor/snippets/constructor-1.java deleted file mode 100644 index 6981c059..00000000 --- a/doc/2/core-classes/memory-storage/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,6 +0,0 @@ - -// using the static instance -MemoryStorage memoryStorage = kuzzle.memoryStorage; - -// or instantiating a new MemoryStorage object -MemoryStorage memoryStorage = new MemoryStorage(kuzzle); diff --git a/doc/2/core-classes/memory-storage/dbsize/index.md b/doc/2/core-classes/memory-storage/dbsize/index.md deleted file mode 100644 index 0eb8a05e..00000000 --- a/doc/2/core-classes/memory-storage/dbsize/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: dbsize -description: MemoryStorage:dbsize ---- - -# dbsize - -Returns the number of keys in the application database. - -[[_Redis documentation_]](https://redis.io/commands/dbsize) - ---- - -## dbsize([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of keys in the application database. - -## Usage - -<<< ./snippets/dbsize-1.java - -> Callback response: - -```json -12 -``` diff --git a/doc/2/core-classes/memory-storage/dbsize/snippets/dbsize-1.java b/doc/2/core-classes/memory-storage/dbsize/snippets/dbsize-1.java deleted file mode 100644 index b9ce0ece..00000000 --- a/doc/2/core-classes/memory-storage/dbsize/snippets/dbsize-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.dbsize(new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/decr/index.md b/doc/2/core-classes/memory-storage/decr/index.md deleted file mode 100644 index 6ff01cf7..00000000 --- a/doc/2/core-classes/memory-storage/decr/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: decr -description: MemoryStorage:decr ---- - -# decr - -Decrements the number stored at `key` by 1. If the key does not exist, it is set to 0 before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/decr) - ---- - -## decr(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated key value. - -## Usage - -<<< ./snippets/decr-1.java - -> Callback response: - -```json --1 -``` diff --git a/doc/2/core-classes/memory-storage/decr/snippets/decr-1.java b/doc/2/core-classes/memory-storage/decr/snippets/decr-1.java deleted file mode 100644 index 75ea5d99..00000000 --- a/doc/2/core-classes/memory-storage/decr/snippets/decr-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.decr("key", new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/decrby/index.md b/doc/2/core-classes/memory-storage/decrby/index.md deleted file mode 100644 index 8660e4c6..00000000 --- a/doc/2/core-classes/memory-storage/decrby/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: decrby -description: MemoryStorage:decrby ---- - -# decrby - -Decrements the number stored at `key` by a provided integer value. If the key does not exist, it is set to 0 before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/decrby) - ---- - -## decrby(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | int | Decrement value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated key value. - -## Usage - -<<< ./snippets/decrby-1.java - -> Callback response: - -```json -57 -``` diff --git a/doc/2/core-classes/memory-storage/decrby/snippets/decrby-1.java b/doc/2/core-classes/memory-storage/decrby/snippets/decrby-1.java deleted file mode 100644 index cafa6531..00000000 --- a/doc/2/core-classes/memory-storage/decrby/snippets/decrby-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.decrby("key", 42, new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/del/index.md b/doc/2/core-classes/memory-storage/del/index.md deleted file mode 100644 index 79412408..00000000 --- a/doc/2/core-classes/memory-storage/del/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: del -description: MemoryStorage:del ---- - -# del - -Deletes a list of keys. - -[[_Redis documentation_]](https://redis.io/commands/del) - ---- - -## del(keys, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------- | -| `keys` | array | List of keys to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Return an integer containing the number of deleted keys. - -## Usage - -<<< ./snippets/del-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/del/snippets/del-1.java b/doc/2/core-classes/memory-storage/del/snippets/del-1.java deleted file mode 100644 index 2d794978..00000000 --- a/doc/2/core-classes/memory-storage/del/snippets/del-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = {"key1", "key2", "..."}; - -kuzzle.memoryStorage.del(keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/exists/index.md b/doc/2/core-classes/memory-storage/exists/index.md deleted file mode 100644 index 06f5b620..00000000 --- a/doc/2/core-classes/memory-storage/exists/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: exists -description: MemoryStorage:exists ---- - -# exists - -Checks if the specified keys exist in the database. - -[[_Redis documentation_]](https://redis.io/commands/exists) - ---- - -## exists(keys, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------- | -| `keys` | array | List of keys to check for existence | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of existing keys amongst the provided list. - -## Usage - -<<< ./snippets/exists-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/exists/snippets/exists-1.java b/doc/2/core-classes/memory-storage/exists/snippets/exists-1.java deleted file mode 100644 index adc33cdb..00000000 --- a/doc/2/core-classes/memory-storage/exists/snippets/exists-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = {"key1", "key2", "..."}; - -kuzzle.memoryStorage.exists(keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/expire/index.md b/doc/2/core-classes/memory-storage/expire/index.md deleted file mode 100644 index aecf35af..00000000 --- a/doc/2/core-classes/memory-storage/expire/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: expire -description: MemoryStorage:expire ---- - -# expire - -Sets a timeout (in seconds) on a key. After the timeout has expired, the key will automatically be deleted. - -[[_Redis documentation_]](https://redis.io/commands/expire) - ---- - -## expire(key, seconds, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------ | -| `key` | string | Key identifier | -| `seconds` | int | Time to live, in seconds | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/expire-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/expire/snippets/expire-1.java b/doc/2/core-classes/memory-storage/expire/snippets/expire-1.java deleted file mode 100644 index c4d856bf..00000000 --- a/doc/2/core-classes/memory-storage/expire/snippets/expire-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.expire("key", 42, new ResponseListener() { - @Override - public void onSuccess(int status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/expireat/index.md b/doc/2/core-classes/memory-storage/expireat/index.md deleted file mode 100644 index 7f65f5de..00000000 --- a/doc/2/core-classes/memory-storage/expireat/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: expireat -description: MemoryStorage:expireat ---- - -# expireat - -Sets an expiration timestamp on a key. After the timestamp has been reached, the key will automatically be deleted. -The `timestamp` parameter accepts an [Epoch time](https://en.wikipedia.org/wiki/Unix_time) value. - -[[_Redis documentation_]](https://redis.io/commands/expireat) - ---- - -## expireat(key, timestamp, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | -------------------- | -| `key` | string | Key identifier | -| `timestamp` | int | Expiration timestamp | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/expireat-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/expireat/snippets/expireat-1.java b/doc/2/core-classes/memory-storage/expireat/snippets/expireat-1.java deleted file mode 100644 index efc2d90c..00000000 --- a/doc/2/core-classes/memory-storage/expireat/snippets/expireat-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.expireat("key", 1488372354, new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/flushdb/index.md b/doc/2/core-classes/memory-storage/flushdb/index.md deleted file mode 100644 index 4afac997..00000000 --- a/doc/2/core-classes/memory-storage/flushdb/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: flushdb -description: MemoryStorage:flushdb ---- - -# flushdb - -Deletes all the keys of the database dedicated to client applications (the reserved space for Kuzzle is unaffected). - -[[_Redis documentation_]](https://redis.io/commands/flushdb) - ---- - -## flushdb([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/flushdb-1.java diff --git a/doc/2/core-classes/memory-storage/flushdb/snippets/flushdb-1.java b/doc/2/core-classes/memory-storage/flushdb/snippets/flushdb-1.java deleted file mode 100644 index 84aad814..00000000 --- a/doc/2/core-classes/memory-storage/flushdb/snippets/flushdb-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.flushdb(new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/geoadd/index.md b/doc/2/core-classes/memory-storage/geoadd/index.md deleted file mode 100644 index f6969d46..00000000 --- a/doc/2/core-classes/memory-storage/geoadd/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: geoadd -description: MemoryStorage:geoadd ---- - -# geoadd - -Adds geospatial points to the specified key. - -[[_Redis documentation_]](https://redis.io/commands/geoadd) - ---- - -## geoadd(key, points, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `key` | string | Destination key identifier | -| `points` | array of objects | List of geospatial points to add. Each point is described by a JSON object containing the following properties:
`lon` (longitude, `float`), `lat` (latitude, `float`), `name` (point identifier, `string`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of points added to the key. - -## Usage - -<<< ./snippets/geoadd-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/geoadd/snippets/geoadd-1.java b/doc/2/core-classes/memory-storage/geoadd/snippets/geoadd-1.java deleted file mode 100644 index 1518772c..00000000 --- a/doc/2/core-classes/memory-storage/geoadd/snippets/geoadd-1.java +++ /dev/null @@ -1,22 +0,0 @@ - -JSONObject[] points = new JSONObject[]{ - new JSONObject() - .put("lon", 13.361389) - .put("lat", 38.115556) - .put("name", "Palermo"), - new JSONObject() - .put("lon", 15.087269) - .put("lat", 37.502669) - .put("name", "Catania") -}; - -kuzzle.memoryStorage.geoadd("key", points, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/geodist/index.md b/doc/2/core-classes/memory-storage/geodist/index.md deleted file mode 100644 index 4929ef11..00000000 --- a/doc/2/core-classes/memory-storage/geodist/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: geodist -description: MemoryStorage:geodist ---- - -# geodist - -Returns the distance between two geospatial members of a key (see [geoadd](/sdk/java/2/core-classes/memory-storage/geoadd)). -The returned distance is expressed in meters by default. - -[[_Redis documentation_]](https://redis.io/commands/geodist) - ---- - -## geodist(key, member1, member2, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------- | -| `key` | string | Key identifier | -| `member1` | string | Name of the first geospatial point | -| `member2` | string | Name of the second geospatial point | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `unit` | string | Distance unit.
Allowed values: `m`, `km`, `mi`, `ft` | `m` | - ---- - -## Callback Response - -Returns the calculated distance between the two provided geospatial points. - -## Usage - -<<< ./snippets/geodist-1.java - -> Callback response: - -```json -166274.1516 -``` diff --git a/doc/2/core-classes/memory-storage/geodist/snippets/geodist-1.java b/doc/2/core-classes/memory-storage/geodist/snippets/geodist-1.java deleted file mode 100644 index b92bbc96..00000000 --- a/doc/2/core-classes/memory-storage/geodist/snippets/geodist-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.geodist("key", "Palermo", "Catania", new ResponseListener() { - @Override - public void onSuccess(double distance) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/geohash/index.md b/doc/2/core-classes/memory-storage/geohash/index.md deleted file mode 100644 index 71725fc0..00000000 --- a/doc/2/core-classes/memory-storage/geohash/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: geohash -description: MemoryStorage:geohash ---- - -# geohash - -Returns a valid [geohash](https://en.wikipedia.org/wiki/Geohash) for the provided key's members (see [geoadd](/sdk/java/2/core-classes/memory-storage/geoadd)). - -[[_Redis documentation_]](https://redis.io/commands/geohash) - ---- - -## geohash(key, members, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------------- | -| `key` | string | Key identifier | -| `members` | array | List of geospatial points contained in the key | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of geohashes, in the same order than the provided members list. - -## Usage - -<<< ./snippets/geohash-1.java - -> Callback response: - -```json -["sqc8b49rny0", "sqdtr74hyu0"] -``` diff --git a/doc/2/core-classes/memory-storage/geohash/snippets/geohash-1.java b/doc/2/core-classes/memory-storage/geohash/snippets/geohash-1.java deleted file mode 100644 index 2e61ffce..00000000 --- a/doc/2/core-classes/memory-storage/geohash/snippets/geohash-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] members = {"Palermo", "Catania"}; - -kuzzle.memoryStorage.geohash("key", members, new ResponseListener() { - @Override - public void onSuccess(String[] hashes) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/geopos/index.md b/doc/2/core-classes/memory-storage/geopos/index.md deleted file mode 100644 index 95ccffc9..00000000 --- a/doc/2/core-classes/memory-storage/geopos/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: geopos -description: MemoryStorage:geopos ---- - -# geopos - -Returns the positions (longitude, latitude) of the provided key's members (see [geoadd](/sdk/java/2/core-classes/memory-storage/geoadd)). - -[[_Redis documentation_]](https://redis.io/commands/geopos) - ---- - -## geopos(key, members, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------------- | -| `key` | string | Key identifier | -| `members` | array | List of geospatial points contained in the key | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of longitude-latitude pairs, in the same order as the provided members list. - -## Usage - -<<< ./snippets/geopos-1.java - -> Callback response: - -```json -[[13.361389, 38.115556], [15.087269, 37.502669]] -``` diff --git a/doc/2/core-classes/memory-storage/geopos/snippets/geopos-1.java b/doc/2/core-classes/memory-storage/geopos/snippets/geopos-1.java deleted file mode 100644 index 7006869c..00000000 --- a/doc/2/core-classes/memory-storage/geopos/snippets/geopos-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] members = {"Palermo", "Catania"}; - -kuzzle.memoryStorage.geopos("key", members, new ResponseListener() { - @Override - public void onSuccess(Double[][] positions) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/georadius/index.md b/doc/2/core-classes/memory-storage/georadius/index.md deleted file mode 100644 index 7769625f..00000000 --- a/doc/2/core-classes/memory-storage/georadius/index.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -code: true -type: page -title: georadius -description: MemoryStorage:georadius ---- - -# georadius - -> Callback response, with no option provided: - -```json -[{ "name": "Palermo" }, { "name": "Catania" }] -``` - -> Callback response, with the "withcoord" option: - -```json -[ - { "name": "Palermo", "coordinates": [13.361389338970184, 38.1155563954963] }, - { "name": "Catania", "coordinates": [15.087267458438873, 37.50266842333162] } -] -``` - -> Callback response, with the "withdist" option: - -```json -[ - { "name": "Palermo", "distance": 190.4424 }, - { "name": "Catania", "distance": 56.4413 } -] -``` - -Returns the members (added with [geoadd](/sdk/java/2/core-classes/memory-storage/geoadd)) of a given key inside the provided geospatial radius. - -[[_Redis documentation_]](https://redis.io/commands/georadius) - ---- - -## georadius(key, longitude, latitude, distance, unit, [options], callback) - -| Arguments | Type | Description | -| ----------- | ----------- | ------------------------------------- | -| `key` | string | Key identifier | -| `longitude` | double | Longitude of the center of the radius | -| `latitude` | double | Latitude of the center of the radius | -| `distance` | double | Maximum distance from the center | -| `unit` | string | Distance unit | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ------- | -| `count` | int | Limit the result set to `count` members | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `sort` | string | Return items from the nearest to the farthest to the center (`ASC`) or vice versa (`DESC`) | `null` | -| `withcoord` | boolean | Also return the longitude and latitude coordinates of the matching items | `false` | -| `withdist` | boolean | Also return the distance of the returned items from the specified center, in the same unit than the one provided with `unit` | `false` | - ---- - -## Callback Response - -Returns an array of names for points that are inside the provided radius. - -## Usage - -<<< ./snippets/georadius-1.java diff --git a/doc/2/core-classes/memory-storage/georadius/snippets/georadius-1.java b/doc/2/core-classes/memory-storage/georadius/snippets/georadius-1.java deleted file mode 100644 index c5a3b092..00000000 --- a/doc/2/core-classes/memory-storage/georadius/snippets/georadius-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.georadius("key", 15, 37, 200, "km", new ResponseListener() { - @Override - public void onSuccess(JSONObject[] points) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/georadiusbymember/index.md b/doc/2/core-classes/memory-storage/georadiusbymember/index.md deleted file mode 100644 index 98a4cc1b..00000000 --- a/doc/2/core-classes/memory-storage/georadiusbymember/index.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -code: true -type: page -title: georadiusbymember -description: MemoryStorage:georadiusbymember ---- - -# georadiusbymember - -> Callback response, with the "withcoord" option: - -```json -[ - { "name": "Palermo", "coordinates": [13.361389338970184, 38.1155563954963] }, - { "name": "Catania", "coordinates": [15.087267458438873, 37.50266842333162] } -] -``` - -> Callback response, with the "withdist" option: - -```json -[ - { "name": "Palermo", "distance": 190.4424 }, - { "name": "Catania", "distance": 56.4413 } -] -``` - -Returns the members (added with [geoadd](/sdk/java/2/core-classes/memory-storage/geoadd)) of a given key inside the provided geospatial radius, centered around one of a key's member. -[[_Redis documentation_]](https://redis.io/commands/georadiusbymember) - ---- - -## georadiusbymember(key, member, distance, unit, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------------------- | -| `key` | string | Key identifier | -| `member` | string | Name of the point to use as the center of the radius | -| `distance` | double | Maximum distance from the center | -| `unit` | string | Distance unit | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ------- | -| `count` | int | Limit the result set to `count` members | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `sort` | string | Return items from the nearest to the farthest to the center (`ASC`) or vice versa (`DESC`) | `null` | -| `withcoord` | boolean | Also return the longitude and latitude coordinates of the matching items | `false` | -| `withdist` | boolean | Also return the distance of the returned items from the specified center, in the same unit than the one provided with `unit` | `false` | - ---- - -## Callback Response - -Returns an array of names for points that are inside the provided radius. - -## Usage - -<<< ./snippets/georadiusbymember-1.java - -> Callback response: - -```json -[{ "name": "Palermo" }, { "name": "Catania" }] -``` diff --git a/doc/2/core-classes/memory-storage/georadiusbymember/snippets/georadiusbymember-1.java b/doc/2/core-classes/memory-storage/georadiusbymember/snippets/georadiusbymember-1.java deleted file mode 100644 index 92800702..00000000 --- a/doc/2/core-classes/memory-storage/georadiusbymember/snippets/georadiusbymember-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.georadiusbymember("key", "Palermo", 200, "km", new ResponseListener() { - @Override - public void onSuccess(JSONObject[] points) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/get/index.md b/doc/2/core-classes/memory-storage/get/index.md deleted file mode 100644 index 83e3c259..00000000 --- a/doc/2/core-classes/memory-storage/get/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: get -description: MemoryStorage:get ---- - -# get - -Returns the value of a key, or null if the key doesn’t exist. - -[[_Redis documentation_]](https://redis.io/commands/get) - ---- - -## get(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the key's value. - -## Usage - -<<< ./snippets/get-1.java - -> Callback response: - -```json -"value" -``` diff --git a/doc/2/core-classes/memory-storage/get/snippets/get-1.java b/doc/2/core-classes/memory-storage/get/snippets/get-1.java deleted file mode 100644 index 5276938d..00000000 --- a/doc/2/core-classes/memory-storage/get/snippets/get-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.get("key", new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/getbit/index.md b/doc/2/core-classes/memory-storage/getbit/index.md deleted file mode 100644 index b3b365e5..00000000 --- a/doc/2/core-classes/memory-storage/getbit/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: getbit -description: MemoryStorage:getbit ---- - -# getbit - -Returns the bit value at `offset`, in the string value stored in a key. - -[[_Redis documentation_]](https://redis.io/commands/getbit) - ---- - -## getbit(key, offset, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------- | -| `key` | string | Key identifier | -| `offset` | int | Offset position in the key's value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the bit value at the provided offset. - -## Usage - -<<< ./snippets/getbit-1.java - -> Callback response: - -```json -1 -``` diff --git a/doc/2/core-classes/memory-storage/getbit/snippets/getbit-1.java b/doc/2/core-classes/memory-storage/getbit/snippets/getbit-1.java deleted file mode 100644 index baa80a5f..00000000 --- a/doc/2/core-classes/memory-storage/getbit/snippets/getbit-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.getbit("key", 10, new ResponseListener() { - @Override - public void onSuccess(int bit) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/getrange/index.md b/doc/2/core-classes/memory-storage/getrange/index.md deleted file mode 100644 index 3a5881aa..00000000 --- a/doc/2/core-classes/memory-storage/getrange/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: getrange -description: MemoryStorage:getrange ---- - -# getrange - -Returns a substring of a key's value (index starts at position `0`). - -[[_Redis documentation_]](https://redis.io/commands/getrange) - ---- - -## getrange(key, start, end, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `start` | int | Starting index | -| `end` | int | Ending index | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a substring of the key's value. - -## Usage - -<<< ./snippets/getrange-1.java - -> Callback response: - -```json -"lue" -``` diff --git a/doc/2/core-classes/memory-storage/getrange/snippets/getrange-1.java b/doc/2/core-classes/memory-storage/getrange/snippets/getrange-1.java deleted file mode 100644 index 1fff31f6..00000000 --- a/doc/2/core-classes/memory-storage/getrange/snippets/getrange-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.getrange("key", 2, 4, new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/getset/index.md b/doc/2/core-classes/memory-storage/getset/index.md deleted file mode 100644 index 72b34b5a..00000000 --- a/doc/2/core-classes/memory-storage/getset/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: getset -description: MemoryStorage:getset ---- - -# getset - -Sets a new value for a key and returns its previous value. - -[[_Redis documentation_]](https://redis.io/commands/getset) - ---- - -## getset(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | string | Key's new value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the key's previous value. - -## Usage - -<<< ./snippets/getset-1.java - -> Callback response: - -```json -"value" -``` diff --git a/doc/2/core-classes/memory-storage/getset/snippets/getset-1.java b/doc/2/core-classes/memory-storage/getset/snippets/getset-1.java deleted file mode 100644 index 8af9bfb0..00000000 --- a/doc/2/core-classes/memory-storage/getset/snippets/getset-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.getset("key", "new value", new ResponseListener() { - @Override - public void onSuccess(String oldValue) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hdel/index.md b/doc/2/core-classes/memory-storage/hdel/index.md deleted file mode 100644 index f94901c7..00000000 --- a/doc/2/core-classes/memory-storage/hdel/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: hdel -description: MemoryStorage:hdel ---- - -# hdel - -Removes fields from a hash. - -[[_Redis documentation_]](https://redis.io/commands/hdel) - ---- - -## hdel(key, fields, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------- | -| `key` | string | Key identifier | -| `fields` | array | List of field names to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the number of removed fields. - -## Usage - -<<< ./snippets/hdel-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/hdel/snippets/hdel-1.java b/doc/2/core-classes/memory-storage/hdel/snippets/hdel-1.java deleted file mode 100644 index 8d389fad..00000000 --- a/doc/2/core-classes/memory-storage/hdel/snippets/hdel-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] fields = {"field1", "field2", "..."}; - -kuzzle.memoryStorage.hdel("key", fields, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hexists/index.md b/doc/2/core-classes/memory-storage/hexists/index.md deleted file mode 100644 index 19b85b8e..00000000 --- a/doc/2/core-classes/memory-storage/hexists/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: hexists -description: MemoryStorage:hexists ---- - -# hexists - -Checks if a field exists in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hexists) - ---- - -## hexists(key, field, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `field` | string | Field name | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -A boolean value specifying if the field exists or not. - -## Usage - -<<< ./snippets/hexists-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/hexists/snippets/hexists-1.java b/doc/2/core-classes/memory-storage/hexists/snippets/hexists-1.java deleted file mode 100644 index d17b3476..00000000 --- a/doc/2/core-classes/memory-storage/hexists/snippets/hexists-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hexists("key", "field1", new ResponseListener() { - @Override - public void onSuccess(Boolean exists) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hget/index.md b/doc/2/core-classes/memory-storage/hget/index.md deleted file mode 100644 index 0b828851..00000000 --- a/doc/2/core-classes/memory-storage/hget/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: hget -description: MemoryStorage:hget ---- - -# hget - -Returns the field’s value of a hash. - -[[_Redis documentation_]](https://redis.io/commands/hget) - ---- - -## hget(key, field, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `field` | string | Field name | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the requested field's value. - -## Usage - -<<< ./snippets/hget-1.java - -> Callback response: - -```json -"foo" -``` diff --git a/doc/2/core-classes/memory-storage/hget/snippets/hget-1.java b/doc/2/core-classes/memory-storage/hget/snippets/hget-1.java deleted file mode 100644 index c10baa00..00000000 --- a/doc/2/core-classes/memory-storage/hget/snippets/hget-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hget("key", "field1", new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hgetall/index.md b/doc/2/core-classes/memory-storage/hgetall/index.md deleted file mode 100644 index dd1eee7c..00000000 --- a/doc/2/core-classes/memory-storage/hgetall/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: hgetall -description: MemoryStorage:hgetall ---- - -# hgetall - -Returns all fields and values of a hash. - -[[_Redis documentation_]](https://redis.io/commands/hgetall) - ---- - -## hgetall(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a JSON object containing the fields and values of a hash. - -## Usage - -<<< ./snippets/hgetall-1.java - -> Callback response: - -```json -{ - "field1": "value", - "field2": "value", - "...": "..." -} -``` diff --git a/doc/2/core-classes/memory-storage/hgetall/snippets/hgetall-1.java b/doc/2/core-classes/memory-storage/hgetall/snippets/hgetall-1.java deleted file mode 100644 index f027e1cf..00000000 --- a/doc/2/core-classes/memory-storage/hgetall/snippets/hgetall-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hgetall("key", new ResponseListener() { - @Override - public void onSuccess(JSONObject hash) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hincrby/index.md b/doc/2/core-classes/memory-storage/hincrby/index.md deleted file mode 100644 index 62f82202..00000000 --- a/doc/2/core-classes/memory-storage/hincrby/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: hincrby -description: MemoryStorage:hincrby ---- - -# hincrby - -Increments the number stored in a hash field by the provided integer value. - -[[_Redis documentation_]](https://redis.io/commands/hincrby) - ---- - -## hincrby(key, field, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------- | -| `key` | string | Key identifier | -| `field` | string | Hash field to increment | -| `value` | int | Increment value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the newly incremented value. - -## Usage - -<<< ./snippets/hincrby-1.java - -> Callback response: - -```json -45 -``` diff --git a/doc/2/core-classes/memory-storage/hincrby/snippets/hincrby-1.java b/doc/2/core-classes/memory-storage/hincrby/snippets/hincrby-1.java deleted file mode 100644 index 22ca764a..00000000 --- a/doc/2/core-classes/memory-storage/hincrby/snippets/hincrby-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hincrby("key", "field", 42, new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hincrbyfloat/index.md b/doc/2/core-classes/memory-storage/hincrbyfloat/index.md deleted file mode 100644 index 1afa2f1b..00000000 --- a/doc/2/core-classes/memory-storage/hincrbyfloat/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: hincrbyfloat -description: MemoryStorage:hincrbyfloat ---- - -# hincrbyfloat - -Increments the number stored in a hash field by the provided float value. - -[[_Redis documentation_]](https://redis.io/commands/hincrbyfloat) - ---- - -## hincrbyfloat(key, field, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------- | -| `key` | string | Key identifier | -| `field` | string | Hash field to increment | -| `value` | double | Increment value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the newly incremented value, as a floating point number. - -## Usage - -<<< ./snippets/hincrbyfloat-1.java - -> Callback response: - -```json -48.14159 -``` diff --git a/doc/2/core-classes/memory-storage/hincrbyfloat/snippets/hincrbyfloat-1.java b/doc/2/core-classes/memory-storage/hincrbyfloat/snippets/hincrbyfloat-1.java deleted file mode 100644 index 4f3a0745..00000000 --- a/doc/2/core-classes/memory-storage/hincrbyfloat/snippets/hincrbyfloat-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hincrbyfloat("key", "field", 3.14159, new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hkeys/index.md b/doc/2/core-classes/memory-storage/hkeys/index.md deleted file mode 100644 index ef9210c5..00000000 --- a/doc/2/core-classes/memory-storage/hkeys/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: hkeys -description: MemoryStorage:hkeys ---- - -# hkeys - -Returns all field names contained in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hkeys) - ---- - -## hkeys(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of field names. - -## Usage - -<<< ./snippets/hkeys-1.java - -> Callback response: - -```json -["field1", "field2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/hkeys/snippets/hkeys-1.java b/doc/2/core-classes/memory-storage/hkeys/snippets/hkeys-1.java deleted file mode 100644 index 75d69ed6..00000000 --- a/doc/2/core-classes/memory-storage/hkeys/snippets/hkeys-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hkeys("key", new ResponseListener() { - @Override - public void onSuccess(String[] fields) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hlen/index.md b/doc/2/core-classes/memory-storage/hlen/index.md deleted file mode 100644 index 06013547..00000000 --- a/doc/2/core-classes/memory-storage/hlen/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: hlen -description: MemoryStorage:hlen ---- - -# hlen - -Returns the number of fields contained in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hlen) - ---- - -## hlen(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of fields in the hash. - -## Usage - -<<< ./snippets/hlen-1.java - -> Callback response: - -```json -13 -``` diff --git a/doc/2/core-classes/memory-storage/hlen/snippets/hlen-1.java b/doc/2/core-classes/memory-storage/hlen/snippets/hlen-1.java deleted file mode 100644 index e4ce5135..00000000 --- a/doc/2/core-classes/memory-storage/hlen/snippets/hlen-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hlen("key", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hmget/index.md b/doc/2/core-classes/memory-storage/hmget/index.md deleted file mode 100644 index a624abe0..00000000 --- a/doc/2/core-classes/memory-storage/hmget/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: hmget -description: MemoryStorage:hmget ---- - -# hmget - -Returns the values of the specified hash’s fields. - -[[_Redis documentation_]](https://redis.io/commands/hmget) - ---- - -## hmget(key, fields, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------- | -| `key` | string | Key identifier | -| `fields` | array | List of fields to examine | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array containing the specified fields values. - -## Usage - -<<< ./snippets/hmget-1.java - -> Callback response: - -```json -["field1's value", "field2's value", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/hmget/snippets/hmget-1.java b/doc/2/core-classes/memory-storage/hmget/snippets/hmget-1.java deleted file mode 100644 index 54892193..00000000 --- a/doc/2/core-classes/memory-storage/hmget/snippets/hmget-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] fields = {"field1", "field2"}; - -kuzzle.memoryStorage.hmget("key", fields, new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hmset/index.md b/doc/2/core-classes/memory-storage/hmset/index.md deleted file mode 100644 index f8d0a8cf..00000000 --- a/doc/2/core-classes/memory-storage/hmset/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: hmset -description: MemoryStorage:hmset ---- - -# hmset - -Sets multiple fields at once in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hmset) - ---- - -## hmset(key, entries, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `key` | string | Key identifier | -| `entries` | array | List of fields to add, with their value. Each entry is described by a JSON object containing the following properties:
`field` (field name), `value` (field's value) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/hmset-1.java diff --git a/doc/2/core-classes/memory-storage/hmset/snippets/hmset-1.java b/doc/2/core-classes/memory-storage/hmset/snippets/hmset-1.java deleted file mode 100644 index d0937992..00000000 --- a/doc/2/core-classes/memory-storage/hmset/snippets/hmset-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("field", "field1").put("value", "foo"), - new JSONObject().put("field", "field2").put("value", "bar"), - new JSONObject().put("field", "...").put("value", "...") -}; - -kuzzle.memoryStorage.hmset("key", entries, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hscan/index.md b/doc/2/core-classes/memory-storage/hscan/index.md deleted file mode 100644 index 57036174..00000000 --- a/doc/2/core-classes/memory-storage/hscan/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: hscan -description: MemoryStorage:hscan ---- - -# hscan - -Identical to [scan](/sdk/java/2/core-classes/memory-storage/scan), except that `hscan` iterates over the fields contained in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hscan) - ---- - -## hscan(key, cursor, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `cursor` | int | Page number (iteration starts with a cursor value of `0`, and ends when the next cursor position is `0`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------- | ------- | -| `count` | int | Return the _approximate_ `count` number of items per result page | `10` | -| `match` | string | Search only for field names matching the provided pattern | `*` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object containing 2 entries: - -- the cursor position for the next page of results (a next position of `0` indicates the end of the scan) -- an array of field names and values - -## Usage - -<<< ./snippets/hscan-1.java - -> Callback response: - -```json -{ - "cursor": 18, - "values": ["field1", "field1 value", "field2", "field2 value"] -} -``` diff --git a/doc/2/core-classes/memory-storage/hscan/snippets/hscan-1.java b/doc/2/core-classes/memory-storage/hscan/snippets/hscan-1.java deleted file mode 100644 index 9e1ea9a5..00000000 --- a/doc/2/core-classes/memory-storage/hscan/snippets/hscan-1.java +++ /dev/null @@ -1,10 +0,0 @@ - -kuzzle.memoryStorage.hscan("key", 0, new ResponseListener() { - @Override - public void onSuccess(JSONObject page) { - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hset/index.md b/doc/2/core-classes/memory-storage/hset/index.md deleted file mode 100644 index 1e98396f..00000000 --- a/doc/2/core-classes/memory-storage/hset/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: hset -description: MemoryStorage:hset ---- - -# hset - -Sets a field and its value in a hash. If the key does not exist, a new key holding a hash is created. If the field already exists, its value is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/hset) - ---- - -## hset(key, field, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------- | -| `key` | string | Key identifier | -| `field` | string | Field name to insert or to update | -| `value` | string | Associated field value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/hset-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/hset/snippets/hset-1.java b/doc/2/core-classes/memory-storage/hset/snippets/hset-1.java deleted file mode 100644 index a8370971..00000000 --- a/doc/2/core-classes/memory-storage/hset/snippets/hset-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hset("key", "field", "value", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hsetnx/index.md b/doc/2/core-classes/memory-storage/hsetnx/index.md deleted file mode 100644 index 6703e7ed..00000000 --- a/doc/2/core-classes/memory-storage/hsetnx/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: hsetnx -description: MemoryStorage:hsetnx ---- - -# hsetnx - -Sets a field and its value in a hash, only if the field does not already exist. - -[[_Redis documentation_]](https://redis.io/commands/hsetnx) - ---- - -## hsetnx(key, field, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------- | -| `key` | string | Key identifier | -| `field` | string | Field name to insert or to update | -| `value` | string | Associated field value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/hsetnx-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/hsetnx/snippets/hsetnx-1.java b/doc/2/core-classes/memory-storage/hsetnx/snippets/hsetnx-1.java deleted file mode 100644 index 081637ad..00000000 --- a/doc/2/core-classes/memory-storage/hsetnx/snippets/hsetnx-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hsetnx("key", "field", "value", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hstrlen/index.md b/doc/2/core-classes/memory-storage/hstrlen/index.md deleted file mode 100644 index 04dee2a2..00000000 --- a/doc/2/core-classes/memory-storage/hstrlen/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: hstrlen -description: MemoryStorage:hstrlen ---- - -# hstrlen - -Returns the string length of a field’s value in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hstrlen) - ---- - -## hstrlen(key, field, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `field` | string | Hash field name | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the string length of a field's value. - -## Usage - -<<< ./snippets/hstrlen-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/hstrlen/snippets/hstrlen-1.java b/doc/2/core-classes/memory-storage/hstrlen/snippets/hstrlen-1.java deleted file mode 100644 index 50066706..00000000 --- a/doc/2/core-classes/memory-storage/hstrlen/snippets/hstrlen-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hstrlen("key", "field", new ResponseListener() { - @Override - public void onSuccess(int length) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/hvals/index.md b/doc/2/core-classes/memory-storage/hvals/index.md deleted file mode 100644 index 6367c0f0..00000000 --- a/doc/2/core-classes/memory-storage/hvals/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: hvals -description: MemoryStorage:hvals ---- - -# hvals - -Returns all values contained in a hash. - -[[_Redis documentation_]](https://redis.io/commands/hvals) - ---- - -## hvals(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array containing the values of a hash. - -## Usage - -<<< ./snippets/hvals-1.java - -> Callback response: - -```json -["field1's value", "field2's value", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/hvals/snippets/hvals-1.java b/doc/2/core-classes/memory-storage/hvals/snippets/hvals-1.java deleted file mode 100644 index dd80e126..00000000 --- a/doc/2/core-classes/memory-storage/hvals/snippets/hvals-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.hvals("key", new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/incr/index.md b/doc/2/core-classes/memory-storage/incr/index.md deleted file mode 100644 index ac70eb95..00000000 --- a/doc/2/core-classes/memory-storage/incr/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: incr -description: MemoryStorage:incr ---- - -# incr - -Increments the number stored at `key` by 1. If the key does not exist, it is set to 0 before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/incr) - ---- - -## incr(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated key value. - -## Usage - -<<< ./snippets/incr-1.java - -> Callback response: - -```json -42 -``` diff --git a/doc/2/core-classes/memory-storage/incr/snippets/incr-1.java b/doc/2/core-classes/memory-storage/incr/snippets/incr-1.java deleted file mode 100644 index fb046046..00000000 --- a/doc/2/core-classes/memory-storage/incr/snippets/incr-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.incr("key", new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/incrby/index.md b/doc/2/core-classes/memory-storage/incrby/index.md deleted file mode 100644 index 53b5dd58..00000000 --- a/doc/2/core-classes/memory-storage/incrby/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: incrby -description: MemoryStorage:incrby ---- - -# incrby - -Increments the number stored at `key` by the provided integer value. If the key does not exist, it is set to 0 before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/incrby) - ---- - -## incrby(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | int | Increment value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated key value. - -## Usage - -<<< ./snippets/incrby-1.java - -> Callback response: - -```json -39 -``` diff --git a/doc/2/core-classes/memory-storage/incrby/snippets/incrby-1.java b/doc/2/core-classes/memory-storage/incrby/snippets/incrby-1.java deleted file mode 100644 index 172fd4f8..00000000 --- a/doc/2/core-classes/memory-storage/incrby/snippets/incrby-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.incrby("key", -3, new ResponseListener() { - @Override - public void onSuccess(int value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/incrbyfloat/index.md b/doc/2/core-classes/memory-storage/incrbyfloat/index.md deleted file mode 100644 index f6a3812b..00000000 --- a/doc/2/core-classes/memory-storage/incrbyfloat/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: incrbyfloat -description: MemoryStorage:incrbyfloat ---- - -# incrbyfloat - -Increments the number stored at `key` by the provided float value. If the key does not exist, it is set to 0 before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/incrbyfloat) - ---- - -## incrbyfloat(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | double | Increment value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a floating point number that contains the updated key value. - -## Usage - -<<< ./snippets/incrbyfloat-1.java - -> Callback response: - -```json -38.85841 -``` diff --git a/doc/2/core-classes/memory-storage/incrbyfloat/snippets/incrbyfloat-1.java b/doc/2/core-classes/memory-storage/incrbyfloat/snippets/incrbyfloat-1.java deleted file mode 100644 index cef5c52c..00000000 --- a/doc/2/core-classes/memory-storage/incrbyfloat/snippets/incrbyfloat-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.incrbyfloat("key", -3.14159, new ResponseListener() { - @Override - public void onSuccess(double value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/index.md b/doc/2/core-classes/memory-storage/index.md deleted file mode 100644 index ee4efe41..00000000 --- a/doc/2/core-classes/memory-storage/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: MemoryStorage -description: MemoryStorage documentation ---- diff --git a/doc/2/core-classes/memory-storage/keys/index.md b/doc/2/core-classes/memory-storage/keys/index.md deleted file mode 100644 index 5c0ec55c..00000000 --- a/doc/2/core-classes/memory-storage/keys/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: keys -description: MemoryStorage:keys ---- - -# keys - -Returns all keys matching the provided pattern. - -[[_Redis documentation_]](https://redis.io/commands/keys) - ---- - -## keys(pattern, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------- | -| `pattern` | string | Pattern used to filter the returned key names | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of key names matching the provided pattern. - -## Usage - -<<< ./snippets/keys-1.java - -> Callback response: - -```json -["foo", "foobar", "foofighters"] -``` diff --git a/doc/2/core-classes/memory-storage/keys/snippets/keys-1.java b/doc/2/core-classes/memory-storage/keys/snippets/keys-1.java deleted file mode 100644 index 2bf4ed77..00000000 --- a/doc/2/core-classes/memory-storage/keys/snippets/keys-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.keys("foo*", new ResponseListener() { - @Override - public void onSuccess(String[] keys) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lindex/index.md b/doc/2/core-classes/memory-storage/lindex/index.md deleted file mode 100644 index f2ca3b46..00000000 --- a/doc/2/core-classes/memory-storage/lindex/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: lindex -description: MemoryStorage:lindex ---- - -# lindex - -Returns the element at the provided index in a list. - -[[_Redis documentation_]](https://redis.io/commands/lindex) - ---- - -## lindex(key, index, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------- | -| `key` | string | Key identifier | -| `index` | int | Element position in the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a string containing the retrieved element's value. - -## Usage - -<<< ./snippets/lindex-1.java - -> Callback response: - -```json -"foo" -``` diff --git a/doc/2/core-classes/memory-storage/lindex/snippets/lindex-1.java b/doc/2/core-classes/memory-storage/lindex/snippets/lindex-1.java deleted file mode 100644 index 863e6b17..00000000 --- a/doc/2/core-classes/memory-storage/lindex/snippets/lindex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lindex("key", 3, new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/linsert/index.md b/doc/2/core-classes/memory-storage/linsert/index.md deleted file mode 100644 index 8faaa795..00000000 --- a/doc/2/core-classes/memory-storage/linsert/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: linsert -description: MemoryStorage:linsert ---- - -# linsert - -Inserts a value in a list, either before or after the reference pivot value. - -[[_Redis documentation_]](https://redis.io/commands/linsert) - ---- - -## linsert(key, position, pivot, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `position` | string | Indicates if the new value is to be inserted before or after the pivot value.
Allowed values: `before`, `after` | -| `pivot` | string | Pivot value used as a point of reference in the list | -| `value` | string | The value to insert | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated number of items in the list. - -## Usage - -<<< ./snippets/linsert-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/linsert/snippets/linsert-1.java b/doc/2/core-classes/memory-storage/linsert/snippets/linsert-1.java deleted file mode 100644 index bf3fa46e..00000000 --- a/doc/2/core-classes/memory-storage/linsert/snippets/linsert-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.linsert("key", "after", "foo", "bar", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/llen/index.md b/doc/2/core-classes/memory-storage/llen/index.md deleted file mode 100644 index 9636d997..00000000 --- a/doc/2/core-classes/memory-storage/llen/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: llen -description: MemoryStorage:llen ---- - -# llen - -Counts the number of items in a list. - -[[_Redis documentation_]](https://redis.io/commands/llen) - ---- - -## llen(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of items of a list. - -## Usage - -<<< ./snippets/llen-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/llen/snippets/llen-1.java b/doc/2/core-classes/memory-storage/llen/snippets/llen-1.java deleted file mode 100644 index 42acb4ee..00000000 --- a/doc/2/core-classes/memory-storage/llen/snippets/llen-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.llen("key", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lpop/index.md b/doc/2/core-classes/memory-storage/lpop/index.md deleted file mode 100644 index 8fa4c5b8..00000000 --- a/doc/2/core-classes/memory-storage/lpop/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: lpop -description: MemoryStorage:lpop ---- - -# lpop - -Removes and returns the first element of a list. - -[[_Redis documentation_]](https://redis.io/commands/lpop) - ---- - -## lpop(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the value of the removed item. - -## Usage - -<<< ./snippets/lpop-1.java - -> Callback response: - -```json -"foo" -``` diff --git a/doc/2/core-classes/memory-storage/lpop/snippets/lpop-1.java b/doc/2/core-classes/memory-storage/lpop/snippets/lpop-1.java deleted file mode 100644 index d3889f55..00000000 --- a/doc/2/core-classes/memory-storage/lpop/snippets/lpop-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lpop("key", new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lpush/index.md b/doc/2/core-classes/memory-storage/lpush/index.md deleted file mode 100644 index e736aa46..00000000 --- a/doc/2/core-classes/memory-storage/lpush/index.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -code: true -type: page -title: lpush -description: MemoryStorage:lpush ---- - -# lpush - -Prepends the specified values to a list. If the key does not exist, it is created holding an empty list before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/lpush) - ---- - -## lpush(key, values, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------ | -| `key` | string | Key identifier | -| `values` | array | Values to add at the beginning of the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated number of items in the list. - -## Usage - -<<< ./snippets/lpush-1.java - -> Callback response: - -```json -6 -``` diff --git a/doc/2/core-classes/memory-storage/lpush/snippets/lpush-1.java b/doc/2/core-classes/memory-storage/lpush/snippets/lpush-1.java deleted file mode 100644 index 00257b45..00000000 --- a/doc/2/core-classes/memory-storage/lpush/snippets/lpush-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] items = new String[]{"foo", "bar", "baz"}; - -kuzzle.memoryStorage.lpush("key", items, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lpushx/index.md b/doc/2/core-classes/memory-storage/lpushx/index.md deleted file mode 100644 index 166f0fc5..00000000 --- a/doc/2/core-classes/memory-storage/lpushx/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: lpushx -description: MemoryStorage:lpushx ---- - -# lpushx - -Prepends the specified value to a list, only if the key already exists and if it holds a list. - -[[_Redis documentation_]](https://redis.io/commands/lpushx) - ---- - -## lpushx(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `key` | string | Key identifier | -| `value` | array | Value to add at the beginning of the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated number of items in the list. - -## Usage - -<<< ./snippets/lpushx-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/lpushx/snippets/lpushx-1.java b/doc/2/core-classes/memory-storage/lpushx/snippets/lpushx-1.java deleted file mode 100644 index 6e5ef524..00000000 --- a/doc/2/core-classes/memory-storage/lpushx/snippets/lpushx-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lpushx("key", "foo", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lrange/index.md b/doc/2/core-classes/memory-storage/lrange/index.md deleted file mode 100644 index ac5ce2e8..00000000 --- a/doc/2/core-classes/memory-storage/lrange/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: lrange -description: MemoryStorage:lrange ---- - -# lrange - -Returns the list elements between the start and stop positions (inclusive). - -[[_Redis documentation_]](https://redis.io/commands/lrange) - ---- - -## lrange(key, start, stop, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `start` | int | Start position | -| `stop` | int | End position | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of retrieved values. - -## Usage - -<<< ./snippets/lrange-1.java - -> Callback response: - -```json -["foo", "bar"] -``` diff --git a/doc/2/core-classes/memory-storage/lrange/snippets/lrange-1.java b/doc/2/core-classes/memory-storage/lrange/snippets/lrange-1.java deleted file mode 100644 index 62ce39ce..00000000 --- a/doc/2/core-classes/memory-storage/lrange/snippets/lrange-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lrange("key", 0, 1, new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lrem/index.md b/doc/2/core-classes/memory-storage/lrem/index.md deleted file mode 100644 index 384a0010..00000000 --- a/doc/2/core-classes/memory-storage/lrem/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: lrem -description: MemoryStorage:lrem ---- - -# lrem - -Removes the first `count` occurences of elements equal to `value` from a list. - -[[_Redis documentation_]](https://redis.io/commands/lrem) - ---- - -## lrem(key, count, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `count` | int | Number of occurences of the value to remove | -| `value` | string | Value to be removed from the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of removed elements. - -## Usage - -<<< ./snippets/lrem-1.java - -> Callback response: - -```json -1 -``` diff --git a/doc/2/core-classes/memory-storage/lrem/snippets/lrem-1.java b/doc/2/core-classes/memory-storage/lrem/snippets/lrem-1.java deleted file mode 100644 index 126c95af..00000000 --- a/doc/2/core-classes/memory-storage/lrem/snippets/lrem-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lrem("key", 1, "foo", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/lset/index.md b/doc/2/core-classes/memory-storage/lset/index.md deleted file mode 100644 index 940a24b4..00000000 --- a/doc/2/core-classes/memory-storage/lset/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: lset -description: MemoryStorage:lset ---- - -# lset - -Sets the list element at `index` with the provided value. - -[[_Redis documentation_]](https://redis.io/commands/lset) - ---- - -## lset(key, index, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------ | -| `key` | string | Key identifier | -| `index` | int | Position of the list to update | -| `value` | string | New value at the provided list index | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/lset-1.java diff --git a/doc/2/core-classes/memory-storage/lset/snippets/lset-1.java b/doc/2/core-classes/memory-storage/lset/snippets/lset-1.java deleted file mode 100644 index 3c8020d0..00000000 --- a/doc/2/core-classes/memory-storage/lset/snippets/lset-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.lset("key", 2, "bar", new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/ltrim/index.md b/doc/2/core-classes/memory-storage/ltrim/index.md deleted file mode 100644 index 084161f3..00000000 --- a/doc/2/core-classes/memory-storage/ltrim/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: ltrim -description: MemoryStorage:ltrim ---- - -# ltrim - -Trims an existing list so that it will contain only the specified range of elements specified. - -[[_Redis documentation_]](https://redis.io/commands/ltrim) - ---- - -## ltrim(key, start, stop, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------- | -| `key` | string | Key identifier | -| `start` | int | Starting position of the range of items to keep (inclusive) | -| `stop` | int | Ending position of the range of items to keep (inclusive) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/ltrim-1.java diff --git a/doc/2/core-classes/memory-storage/ltrim/snippets/ltrim-1.java b/doc/2/core-classes/memory-storage/ltrim/snippets/ltrim-1.java deleted file mode 100644 index cbda48b4..00000000 --- a/doc/2/core-classes/memory-storage/ltrim/snippets/ltrim-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.ltrim("key", 1, 2, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/mget/index.md b/doc/2/core-classes/memory-storage/mget/index.md deleted file mode 100644 index b7d97bf7..00000000 --- a/doc/2/core-classes/memory-storage/mget/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: mget -description: MemoryStorage:mget ---- - -# mget - -Returns the values of the provided keys. - -[[_Redis documentation_]](https://redis.io/commands/mget) - ---- - -## mget(keys, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------ | -| `keys` | string | List of keys to retrieve | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of the specified keys' values. - -## Usage - -<<< ./snippets/mget-1.java - -> Callback response: - -```json -["key1's value", "key2's value", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/mget/snippets/mget-1.java b/doc/2/core-classes/memory-storage/mget/snippets/mget-1.java deleted file mode 100644 index 497aafec..00000000 --- a/doc/2/core-classes/memory-storage/mget/snippets/mget-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.mget(keys, new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/mset/index.md b/doc/2/core-classes/memory-storage/mset/index.md deleted file mode 100644 index a002cb0c..00000000 --- a/doc/2/core-classes/memory-storage/mset/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: mset -description: MemoryStorage:mset ---- - -# mset - -Sets the provided keys to their respective values. If a key does not exist, it is created. Otherwise, the key’s value is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/mset) - ---- - -## mset(entries, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `entries` | array | List of objects each containing the key identifier to add with its associated value.
Properties: `key` (key identifier), `value` (associated value) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/mset-1.java diff --git a/doc/2/core-classes/memory-storage/mset/snippets/mset-1.java b/doc/2/core-classes/memory-storage/mset/snippets/mset-1.java deleted file mode 100644 index c62533d2..00000000 --- a/doc/2/core-classes/memory-storage/mset/snippets/mset-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("key", "key1").put("value", "foo"), - new JSONObject().put("key", "key2").put("value", "bar"), - new JSONObject().put("key", "...").put("value", "...") -}; - -kuzzle.memoryStorage.mset(entries, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/msetnx/index.md b/doc/2/core-classes/memory-storage/msetnx/index.md deleted file mode 100644 index 5bcdda01..00000000 --- a/doc/2/core-classes/memory-storage/msetnx/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: msetnx -description: MemoryStorage:msetnx ---- - -# msetnx - -Sets the provided keys to their respective values, only if they do not exist. If a key exists, then the whole operation is aborted and no key is set. - -[[_Redis documentation_]](https://redis.io/commands/msetnx) - ---- - -## msetnx(entries, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `entries` | array | List of objects each containing the key identifier to add with its associated value.
Properties: `key` (key identifier), `value` (associated value) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/msetnx-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/msetnx/snippets/msetnx-1.java b/doc/2/core-classes/memory-storage/msetnx/snippets/msetnx-1.java deleted file mode 100644 index f86429ac..00000000 --- a/doc/2/core-classes/memory-storage/msetnx/snippets/msetnx-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -JSONObject[] entries = new JSONObject[]{ - new JSONObject().put("key", "key1").put("value", "foo"), - new JSONObject().put("key", "key2").put("value", "bar"), - new JSONObject().put("key", "...").put("value", "...") -}; - -kuzzle.memoryStorage.msetnx(entries, new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/object/index.md b/doc/2/core-classes/memory-storage/object/index.md deleted file mode 100644 index 88887b11..00000000 --- a/doc/2/core-classes/memory-storage/object/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: object -description: MemoryStorage:object ---- - -# object - -Inspects the low-level properties of a key. - -[[_Redis documentation_]](https://redis.io/commands/object) - ---- - -## object(key, subcommand, [options], callback) - -| Arguments | Type | Description | -| ------------ | ----------- | ------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `subcommand` | string | Name of the low-level property to inspect.
Allowed values: `refcount`, `encoding`, `idletime` | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the value of the inspected property. - -## Usage - -<<< ./snippets/object-1.java - -> Callback response: - -```json -"raw" -``` diff --git a/doc/2/core-classes/memory-storage/object/snippets/object-1.java b/doc/2/core-classes/memory-storage/object/snippets/object-1.java deleted file mode 100644 index ac0bf4eb..00000000 --- a/doc/2/core-classes/memory-storage/object/snippets/object-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.object("key", "encoding", new ResponseListener() { - @Override - public void onSuccess(String property) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/persist/index.md b/doc/2/core-classes/memory-storage/persist/index.md deleted file mode 100644 index f1a808b2..00000000 --- a/doc/2/core-classes/memory-storage/persist/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: persist -description: MemoryStorage:persist ---- - -# persist - -Removes the expiration delay or timestamp from a key, making it persistent. - -[[_Redis documentation_]](https://redis.io/commands/persist) - ---- - -## persist(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/persist-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/persist/snippets/persist-1.java b/doc/2/core-classes/memory-storage/persist/snippets/persist-1.java deleted file mode 100644 index cee6b5b9..00000000 --- a/doc/2/core-classes/memory-storage/persist/snippets/persist-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.persist("key", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pexpire/index.md b/doc/2/core-classes/memory-storage/pexpire/index.md deleted file mode 100644 index 6f9e55af..00000000 --- a/doc/2/core-classes/memory-storage/pexpire/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: pexpire -description: MemoryStorage:pexpire ---- - -# pexpire - -Sets a timeout (in milliseconds) on a key. After the timeout has expired, the key will automatically be deleted. - -[[_Redis documentation_]](https://redis.io/commands/pexpire) - ---- - -## pexpire(key, ttl, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------- | -| `key` | string | Key identifier | -| `ttl` | int | Time to live of the key, in milliseconds | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/pexpire-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/pexpire/snippets/pexpire-1.java b/doc/2/core-classes/memory-storage/pexpire/snippets/pexpire-1.java deleted file mode 100644 index b66ebe6d..00000000 --- a/doc/2/core-classes/memory-storage/pexpire/snippets/pexpire-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.pexpire("key", 42000, new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pexpireat/index.md b/doc/2/core-classes/memory-storage/pexpireat/index.md deleted file mode 100644 index bcd138b8..00000000 --- a/doc/2/core-classes/memory-storage/pexpireat/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: pexpireat -description: MemoryStorage:pexpireat ---- - -# pexpireat - -Sets an expiration timestamp on a key. After the timestamp has been reached, the key will automatically be deleted. -The `timestamp` parameter accepts an [Epoch time](https://en.wikipedia.org/wiki/Unix_time) value, in milliseconds. - -[[_Redis documentation_]](https://redis.io/commands/pexpireat) - ---- - -## pexpireat(key, timestamp, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `timestamp` | int | Key's expiration timestamp, in milliseconds | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/pexpireat-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/pexpireat/snippets/pexpireat-1.java b/doc/2/core-classes/memory-storage/pexpireat/snippets/pexpireat-1.java deleted file mode 100644 index 960ede21..00000000 --- a/doc/2/core-classes/memory-storage/pexpireat/snippets/pexpireat-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.pexpireat("key", 1488540242465, new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pfadd/index.md b/doc/2/core-classes/memory-storage/pfadd/index.md deleted file mode 100644 index 0e0b48fc..00000000 --- a/doc/2/core-classes/memory-storage/pfadd/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: pfadd -description: MemoryStorage:pfadd ---- - -# pfadd - -Adds elements to an [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) data structure. - -[[_Redis documentation_]](https://redis.io/commands/pfadd) - ---- - -## pfadd(key, elements, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------- | -| `key` | string | Key identifier | -| `elements` | array | Elements to add to the HyperLogLog structure | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/pfadd-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/pfadd/snippets/pfadd-1.java b/doc/2/core-classes/memory-storage/pfadd/snippets/pfadd-1.java deleted file mode 100644 index ee922fad..00000000 --- a/doc/2/core-classes/memory-storage/pfadd/snippets/pfadd-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] elements = new String[]{"foo", "bar", "baz"}; - -kuzzle.memoryStorage.pfadd("key", elements, new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pfcount/index.md b/doc/2/core-classes/memory-storage/pfcount/index.md deleted file mode 100644 index 5753bbae..00000000 --- a/doc/2/core-classes/memory-storage/pfcount/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: pfcount -description: MemoryStorage:pfcount ---- - -# pfcount - -Returns the probabilistic cardinality of a [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) data structure, or of the merged HyperLogLog structures if more than 1 is provided (see [pfadd](/sdk/java/2/core-classes/memory-storage/pfadd)). - -[[_Redis documentation_]](https://redis.io/commands/pfcount) - ---- - -## pfcount(keys, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------- | -| `keys` | string | List of HyperLogLog key identifiers | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the aggregated probabilistic cardinality of HyperLogLog structures. - -## Usage - -<<< ./snippets/pfcount-1.java - -> Callback response: - -```json -42 -``` diff --git a/doc/2/core-classes/memory-storage/pfcount/snippets/pfcount-1.java b/doc/2/core-classes/memory-storage/pfcount/snippets/pfcount-1.java deleted file mode 100644 index bd76126b..00000000 --- a/doc/2/core-classes/memory-storage/pfcount/snippets/pfcount-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.pfcount(keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pfmerge/index.md b/doc/2/core-classes/memory-storage/pfmerge/index.md deleted file mode 100644 index ca30bf81..00000000 --- a/doc/2/core-classes/memory-storage/pfmerge/index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -code: true -type: page -title: pfmerge -description: MemoryStorage:pfmerge ---- - -# pfmerge - -Merges multiple [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) data structures into an unique HyperLogLog structure stored at `key`, approximating the cardinality of the union of the source structures. - -[[_Redis documentation_]](https://redis.io/commands/pfmerge) - ---- - -## pfmerge(key, sources, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------ | -| `key` | string | Destination key identifier | -| `sources` | string | List of HyperLogLog source key identifiers | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/pfmerge-1.java diff --git a/doc/2/core-classes/memory-storage/pfmerge/snippets/pfmerge-1.java b/doc/2/core-classes/memory-storage/pfmerge/snippets/pfmerge-1.java deleted file mode 100644 index 55b1539a..00000000 --- a/doc/2/core-classes/memory-storage/pfmerge/snippets/pfmerge-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.pfmerge('key', keys, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/ping/index.md b/doc/2/core-classes/memory-storage/ping/index.md deleted file mode 100644 index 735a0c50..00000000 --- a/doc/2/core-classes/memory-storage/ping/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: ping -description: MemoryStorage:ping ---- - -# ping - -Pings the memory storage database. - -[[_Redis documentation_]](https://redis.io/commands/ping) - ---- - -## ping([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a simple "PONG" string. - -## Usage - -<<< ./snippets/ping-1.java - -> Callback response: - -```json -"PONG" -``` diff --git a/doc/2/core-classes/memory-storage/ping/snippets/ping-1.java b/doc/2/core-classes/memory-storage/ping/snippets/ping-1.java deleted file mode 100644 index 20ccdfa4..00000000 --- a/doc/2/core-classes/memory-storage/ping/snippets/ping-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.ping(new ResponseListener() { - @Override - public void onSuccess(String response) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/psetex/index.md b/doc/2/core-classes/memory-storage/psetex/index.md deleted file mode 100644 index ce04eb02..00000000 --- a/doc/2/core-classes/memory-storage/psetex/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: psetex -description: MemoryStorage:psetex ---- - -# psetex - -Sets a key with the provided value, and an expiration delay expressed in milliseconds. If the key does not exist, it is created beforehand. - -[[_Redis documentation_]](https://redis.io/commands/psetex) - ---- - -## psetex(key, value, ttl, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to set | -| `ttl` | int | Time to live of the key, in milliseconds | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/psetex-1.java diff --git a/doc/2/core-classes/memory-storage/psetex/snippets/psetex-1.java b/doc/2/core-classes/memory-storage/psetex/snippets/psetex-1.java deleted file mode 100644 index 34a2098c..00000000 --- a/doc/2/core-classes/memory-storage/psetex/snippets/psetex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.psetex("key", "value", 42000, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/pttl/index.md b/doc/2/core-classes/memory-storage/pttl/index.md deleted file mode 100644 index b7436955..00000000 --- a/doc/2/core-classes/memory-storage/pttl/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: pttl -description: MemoryStorage:pttl ---- - -# pttl - -Returns the remaining time to live of a key, in milliseconds. - -[[_Redis documentation_]](https://redis.io/commands/pttl) - ---- - -## pttl(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the remaining time to live of the key, in milliseconds. - -## Usage - -<<< ./snippets/pttl-1.java - -> Callback response: - -```json -43159 -``` diff --git a/doc/2/core-classes/memory-storage/pttl/snippets/pttl-1.java b/doc/2/core-classes/memory-storage/pttl/snippets/pttl-1.java deleted file mode 100644 index e20fd472..00000000 --- a/doc/2/core-classes/memory-storage/pttl/snippets/pttl-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.pttl("key", new ResponseListener() { - @Override - public void onSuccess(int ttl) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/randomkey/index.md b/doc/2/core-classes/memory-storage/randomkey/index.md deleted file mode 100644 index cf025845..00000000 --- a/doc/2/core-classes/memory-storage/randomkey/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: randomkey -description: MemoryStorage:randomkey ---- - -# randomkey - -Returns a random key from the memory storage. - -[[_Redis documentation_]](https://redis.io/commands/randomkey) - ---- - -## randomkey([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns one of the stored key names, at random. - -## Usage - -<<< ./snippets/randomkey-1.java - -> Callback response: - -```json -"key2" -``` diff --git a/doc/2/core-classes/memory-storage/randomkey/snippets/randomkey-1.java b/doc/2/core-classes/memory-storage/randomkey/snippets/randomkey-1.java deleted file mode 100644 index 5fbe9692..00000000 --- a/doc/2/core-classes/memory-storage/randomkey/snippets/randomkey-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.randomkey(new ResponseListener() { - @Override - public void onSuccess(String key) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/rename/index.md b/doc/2/core-classes/memory-storage/rename/index.md deleted file mode 100644 index afe8664f..00000000 --- a/doc/2/core-classes/memory-storage/rename/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: rename -description: MemoryStorage:rename ---- - -# rename - -Renames a key to `newkey`. If `newkey` already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/rename) - ---- - -## rename(key, newkey, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `newkey` | string | New key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/rename-1.java diff --git a/doc/2/core-classes/memory-storage/rename/snippets/rename-1.java b/doc/2/core-classes/memory-storage/rename/snippets/rename-1.java deleted file mode 100644 index dc5e7896..00000000 --- a/doc/2/core-classes/memory-storage/rename/snippets/rename-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.rename("key", "newId", new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/renamenx/index.md b/doc/2/core-classes/memory-storage/renamenx/index.md deleted file mode 100644 index b6879e84..00000000 --- a/doc/2/core-classes/memory-storage/renamenx/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: renamenx -description: MemoryStorage:renamenx ---- - -# renamenx - -Renames a key to `newkey`, only if `newkey` does not already exist. - -[[_Redis documentation_]](https://redis.io/commands/renamenx) - ---- - -## renamenx(key, newkey, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `newkey` | string | New key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/renamenx-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/renamenx/snippets/renamenx-1.java b/doc/2/core-classes/memory-storage/renamenx/snippets/renamenx-1.java deleted file mode 100644 index 4da35cd2..00000000 --- a/doc/2/core-classes/memory-storage/renamenx/snippets/renamenx-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.renamenx("key", "newId", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/rpop/index.md b/doc/2/core-classes/memory-storage/rpop/index.md deleted file mode 100644 index 661678ef..00000000 --- a/doc/2/core-classes/memory-storage/rpop/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: rpop -description: MemoryStorage:rpop ---- - -# rpop - -Removes and returns the last element of a list. - -[[_Redis documentation_]](https://redis.io/commands/rpop) - ---- - -## rpop(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the value of the removed item. - -## Usage - -<<< ./snippets/rpop-1.java - -> Callback response: - -```json -"foo" -``` diff --git a/doc/2/core-classes/memory-storage/rpop/snippets/rpop-1.java b/doc/2/core-classes/memory-storage/rpop/snippets/rpop-1.java deleted file mode 100644 index c36e5f63..00000000 --- a/doc/2/core-classes/memory-storage/rpop/snippets/rpop-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.rpop("key", new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/rpoplpush/index.md b/doc/2/core-classes/memory-storage/rpoplpush/index.md deleted file mode 100644 index 5177ec5b..00000000 --- a/doc/2/core-classes/memory-storage/rpoplpush/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: rpoplpush -description: MemoryStorage:rpoplpush ---- - -# rpoplpush - -Removes the last element of the list at `source` and pushes it back at the start of the list at `destination`. - -[[_Redis documentation_]](https://redis.io/commands/rpoplpush) - ---- - -## rpoplpush(source, destination, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | -------------------------- | -| `source` | string | Source key identifier | -| `destination` | string | Destination key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns the value of the removed and pushed item. - -## Usage - -<<< ./snippets/rpoplpush-1.java - -> Callback response: - -```json -"foo" -``` diff --git a/doc/2/core-classes/memory-storage/rpoplpush/snippets/rpoplpush-1.java b/doc/2/core-classes/memory-storage/rpoplpush/snippets/rpoplpush-1.java deleted file mode 100644 index f1f49aa7..00000000 --- a/doc/2/core-classes/memory-storage/rpoplpush/snippets/rpoplpush-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.rpoplpush("sourceKey", "destKey", new ResponseListener() { - @Override - public void onSuccess(String value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/rpush/index.md b/doc/2/core-classes/memory-storage/rpush/index.md deleted file mode 100644 index 1cf04d5a..00000000 --- a/doc/2/core-classes/memory-storage/rpush/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: rpush -description: MemoryStorage:rpush ---- - -# rpush - -Appends the specified values at the end of a list. If the key does not exist, it is created holding an empty list before performing the operation. - -[[_Redis documentation_]](https://redis.io/commands/rpush) - ---- - -## rpush(key, values, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------ | -| `key` | string | Key identifier | -| `values` | array | Values to add at the end of the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated number of items in the list. - -## Usage - -<<< ./snippets/rpush-1.java - -> Callback response: - -```json -6 -``` diff --git a/doc/2/core-classes/memory-storage/rpush/snippets/rpush-1.java b/doc/2/core-classes/memory-storage/rpush/snippets/rpush-1.java deleted file mode 100644 index a5a53aac..00000000 --- a/doc/2/core-classes/memory-storage/rpush/snippets/rpush-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] items = new String[]{"foo", "bar", "baz"}; - -kuzzle.memoryStorage.rpush("key", items, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/rpushx/index.md b/doc/2/core-classes/memory-storage/rpushx/index.md deleted file mode 100644 index 34fb353e..00000000 --- a/doc/2/core-classes/memory-storage/rpushx/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: rpushx -description: MemoryStorage:rpushx ---- - -# rpushx - -Appends the specified value at the end of a list, only if the key already exists and if it holds a list. - -[[_Redis documentation_]](https://redis.io/commands/rpushx) - ---- - -## rpushx(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to add at the end of the list | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the updated number of items in the list. - -## Usage - -<<< ./snippets/rpushx-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/rpushx/snippets/rpushx-1.java b/doc/2/core-classes/memory-storage/rpushx/snippets/rpushx-1.java deleted file mode 100644 index 50f20def..00000000 --- a/doc/2/core-classes/memory-storage/rpushx/snippets/rpushx-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.rpushx("key", "foo", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sadd/index.md b/doc/2/core-classes/memory-storage/sadd/index.md deleted file mode 100644 index 0f6dfadd..00000000 --- a/doc/2/core-classes/memory-storage/sadd/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: sadd -description: MemoryStorage:sadd ---- - -# sadd - -Adds members to a set of unique values stored at `key`. If the `key` does not exist, it is created beforehand. - -[[_Redis documentation_]](https://redis.io/commands/sadd) - ---- - -## sadd(key, members, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `members` | array | Members to add to the list of unique values | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of added elements to the set. - -## Usage - -<<< ./snippets/sadd-1.java - -> Callback response: - -```json -6 -``` diff --git a/doc/2/core-classes/memory-storage/sadd/snippets/sadd-1.java b/doc/2/core-classes/memory-storage/sadd/snippets/sadd-1.java deleted file mode 100644 index fc24e362..00000000 --- a/doc/2/core-classes/memory-storage/sadd/snippets/sadd-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] items = new String[]{"foo", "bar", "baz"}; - -kuzzle.memoryStorage.sadd("key", items, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/scan/index.md b/doc/2/core-classes/memory-storage/scan/index.md deleted file mode 100644 index a797cd76..00000000 --- a/doc/2/core-classes/memory-storage/scan/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -code: true -type: page -title: scan -description: MemoryStorage:scan ---- - -# scan - -Iterates incrementally over the set of keys in the database using a cursor. - -An iteration starts when the cursor is set to `0`. -To get the next page of results, simply re-send the identical request with the updated cursor position provided in the result set. -The scan terminates when the next position cursor returned by the server is `0`. - -[[_Redis documentation_]](https://redis.io/commands/scan) - ---- - -## scan(cursor, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------- | -| `cursor` | int | Page number (iteration starts with a cursor value of `0`, and ends when the next cursor position is `0`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------- | ------- | -| `count` | int | Return the _approximate_ `count` number of items per result page | `10` | -| `match` | string | Search only for field names matching the provided pattern | `*` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a JSON object containing 2 entries: - -- the cursor position for the next page of results (a next position of `0` indicates the end of the scan) -- a list of fetched keys - -## Usage - -<<< ./snippets/scan-1.java - -> Callback response: - -```json -{ - "cursor": 18, - "values": ["key1", "key2", "..."] -} -``` diff --git a/doc/2/core-classes/memory-storage/scan/snippets/scan-1.java b/doc/2/core-classes/memory-storage/scan/snippets/scan-1.java deleted file mode 100644 index d9665783..00000000 --- a/doc/2/core-classes/memory-storage/scan/snippets/scan-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.scan(0, new ResponseListener() { - @Override - public void onSuccess(JSONObject page) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/scard/index.md b/doc/2/core-classes/memory-storage/scard/index.md deleted file mode 100644 index c41f7f70..00000000 --- a/doc/2/core-classes/memory-storage/scard/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: scard -description: MemoryStorage:scard ---- - -# scard - -Returns the number of members stored in a set of unique values. - -[[_Redis documentation_]](https://redis.io/commands/scard) - ---- - -## scard(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of items in the set. - -## Usage - -<<< ./snippets/scard-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/scard/snippets/scard-1.java b/doc/2/core-classes/memory-storage/scard/snippets/scard-1.java deleted file mode 100644 index 4b4e0e48..00000000 --- a/doc/2/core-classes/memory-storage/scard/snippets/scard-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.scard("key", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sdiff/index.md b/doc/2/core-classes/memory-storage/sdiff/index.md deleted file mode 100644 index b145e8a8..00000000 --- a/doc/2/core-classes/memory-storage/sdiff/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: sdiff -description: MemoryStorage:sdiff ---- - -# sdiff - -Returns the difference between the set of unique values stored at `key` and the other provided sets. - -[[_Redis documentation_]](https://redis.io/commands/sdiff) - ---- - -## sdiff(key, keys, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------- | -| `key` | string | Key identifier to compare | -| `keys` | array | list of set keys to compare with the set stored at `key` | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of differences. - -## Usage - -<<< ./snippets/sdiff-1.java - -> Callback response: - -```json -["diff value1", "diff value2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/sdiff/snippets/sdiff-1.java b/doc/2/core-classes/memory-storage/sdiff/snippets/sdiff-1.java deleted file mode 100644 index c6ee97c9..00000000 --- a/doc/2/core-classes/memory-storage/sdiff/snippets/sdiff-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sdiff("key", keys, new ResponseListener() { - @Override - public void onSuccess(String[] diffs) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sdiffstore/index.md b/doc/2/core-classes/memory-storage/sdiffstore/index.md deleted file mode 100644 index c5a399d5..00000000 --- a/doc/2/core-classes/memory-storage/sdiffstore/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -code: true -type: page -title: sdiffstore -description: MemoryStorage:sdiffstore ---- - -# sdiffstore - -Computes the difference between the set of unique values stored at `key` and the other provided sets, and stores the result in the key stored at `destination`. - -If the `destination` key already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/sdiffstore) - ---- - -## sdiffstore(key, keys, destination, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | -------------------------------------------------------- | -| `key` | string | Key identifier to compare | -| `keys` | array | list of set keys to compare with the set stored at `key` | -| `destination` | string | Destination key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of stored elements. - -## Usage - -<<< ./snippets/sdiffstore-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/sdiffstore/snippets/sdiffstore-1.java b/doc/2/core-classes/memory-storage/sdiffstore/snippets/sdiffstore-1.java deleted file mode 100644 index f18b297b..00000000 --- a/doc/2/core-classes/memory-storage/sdiffstore/snippets/sdiffstore-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sdiffstore("key", keys, "destination", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/set/index.md b/doc/2/core-classes/memory-storage/set/index.md deleted file mode 100644 index 1e6b5d59..00000000 --- a/doc/2/core-classes/memory-storage/set/index.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -code: true -type: page -title: set -description: MemoryStorage:set ---- - -# set - -Creates a key holding the provided value, or overwrites it if it already exists. - -[[_Redis documentation_]](https://redis.io/commands/set) - ---- - -## set(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to store | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------------------- | ------- | -| `ex` | int | Time to live of the key, in seconds | `0` | -| `nx` | boolean | Set the key only if it does not already exist | `false` | -| `px` | int | Time to live of the key, in milliseconds | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `xx` | boolean | Set the key only if it already exists | `false` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/set-1.java diff --git a/doc/2/core-classes/memory-storage/set/snippets/set-1.java b/doc/2/core-classes/memory-storage/set/snippets/set-1.java deleted file mode 100644 index 7635c8ea..00000000 --- a/doc/2/core-classes/memory-storage/set/snippets/set-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.set("key", "value", new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/setex/index.md b/doc/2/core-classes/memory-storage/setex/index.md deleted file mode 100644 index 219a6534..00000000 --- a/doc/2/core-classes/memory-storage/setex/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: setex -description: MemoryStorage:setex ---- - -# setex - -Sets a key with the provided value, and an expiration delay expressed in seconds. If the key does not exist, it is created beforehand. - -[[_Redis documentation_]](https://redis.io/commands/setex) - ---- - -## setex(key, value, ttl, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to set | -| `ttl` | int | Time to live of the key, in seconds | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns null if successful. - -## Usage - -<<< ./snippets/setex-1.java diff --git a/doc/2/core-classes/memory-storage/setex/snippets/setex-1.java b/doc/2/core-classes/memory-storage/setex/snippets/setex-1.java deleted file mode 100644 index 33415acf..00000000 --- a/doc/2/core-classes/memory-storage/setex/snippets/setex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.setex("key", "value", 42, new ResponseListener() { - @Override - public void onSuccess(Void v) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/setnx/index.md b/doc/2/core-classes/memory-storage/setnx/index.md deleted file mode 100644 index cdfbaaad..00000000 --- a/doc/2/core-classes/memory-storage/setnx/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: setnx -description: MemoryStorage:setnx ---- - -# setnx - -Sets a value on a key, only if it does not already exist. - -[[_Redis documentation_]](https://redis.io/commands/setnx) - ---- - -## setnx(key, value, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `value` | string | Value to store | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/setnx-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/setnx/snippets/setnx-1.java b/doc/2/core-classes/memory-storage/setnx/snippets/setnx-1.java deleted file mode 100644 index 9de04ac1..00000000 --- a/doc/2/core-classes/memory-storage/setnx/snippets/setnx-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.setnx("key", "value", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sinter/index.md b/doc/2/core-classes/memory-storage/sinter/index.md deleted file mode 100644 index 121ebbff..00000000 --- a/doc/2/core-classes/memory-storage/sinter/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: sinter -description: MemoryStorage:sinter ---- - -# sinter - -Returns the intersection of the provided sets of unique values. - -[[_Redis documentation_]](https://redis.io/commands/sinter) - ---- - -## sinter(keys, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------ | -| `keys` | string | List of sets of unique values to intersect | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of values in the computed intersection. - -## Usage - -<<< ./snippets/sinter-1.java - -> Callback response: - -```json -["intersection value1", "intersection value2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/sinter/snippets/sinter-1.java b/doc/2/core-classes/memory-storage/sinter/snippets/sinter-1.java deleted file mode 100644 index bc7fa696..00000000 --- a/doc/2/core-classes/memory-storage/sinter/snippets/sinter-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sinter(keys, new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sinterstore/index.md b/doc/2/core-classes/memory-storage/sinterstore/index.md deleted file mode 100644 index 36086043..00000000 --- a/doc/2/core-classes/memory-storage/sinterstore/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: sinterstore -description: MemoryStorage:sinterstore ---- - -# sinterstore - -Computes the intersection of the provided sets of unique values and stores the result in the `destination` key. - -If the destination key already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/sinterstore) - ---- - -## sinterstore(destination, keys, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `destination` | string | Destination key identifier | -| `keys` | array | List of sets of unique values to intersect | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of elements in the stored intersection. - -## Usage - -<<< ./snippets/sinterstore-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/sinterstore/snippets/sinterstore-1.java b/doc/2/core-classes/memory-storage/sinterstore/snippets/sinterstore-1.java deleted file mode 100644 index 4c1b9b7e..00000000 --- a/doc/2/core-classes/memory-storage/sinterstore/snippets/sinterstore-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sinterstore("destination", keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sismember/index.md b/doc/2/core-classes/memory-storage/sismember/index.md deleted file mode 100644 index 424f6513..00000000 --- a/doc/2/core-classes/memory-storage/sismember/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: sismember -description: MemoryStorage:sismember ---- - -# sismember - -Checks if `member` is a member of the set of unique values stored at `key`. - -[[_Redis documentation_]](https://redis.io/commands/sismember) - ---- - -## sismember(key, member, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------- | -| `key` | string | Key identifier | -| `member` | string | Value tested against the set of unique values | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a boolean specifying if `member` is a member of the set or not. - -## Usage - -<<< ./snippets/sismember-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/sismember/snippets/sismember-1.java b/doc/2/core-classes/memory-storage/sismember/snippets/sismember-1.java deleted file mode 100644 index 97297bc8..00000000 --- a/doc/2/core-classes/memory-storage/sismember/snippets/sismember-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.sismember("key", "member", new ResponseListener() { - @Override - public void onSuccess(Boolean isMember) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/smembers/index.md b/doc/2/core-classes/memory-storage/smembers/index.md deleted file mode 100644 index fce322ea..00000000 --- a/doc/2/core-classes/memory-storage/smembers/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: smembers -description: MemoryStorage:smembers ---- - -# smembers - -Returns the members of a set of unique values. - -[[_Redis documentation_]](https://redis.io/commands/smembers) - ---- - -## smembers(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of values held by the provided set. - -## Usage - -<<< ./snippets/smembers-1.java - -> Callback response: - -```json -["member1", "member2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/smembers/snippets/smembers-1.java b/doc/2/core-classes/memory-storage/smembers/snippets/smembers-1.java deleted file mode 100644 index 4a15f88f..00000000 --- a/doc/2/core-classes/memory-storage/smembers/snippets/smembers-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.smembers("key", new ResponseListener() { - @Override - public void onSuccess(String[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/smove/index.md b/doc/2/core-classes/memory-storage/smove/index.md deleted file mode 100644 index dad1c1f6..00000000 --- a/doc/2/core-classes/memory-storage/smove/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: smove -description: MemoryStorage:smove ---- - -# smove - -Moves a member from a set of unique values to another. - -[[_Redis documentation_]](https://redis.io/commands/smove) - ---- - -## smove(key, destination, member, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | -------------------------- | -| `key` | string | Source key identifier | -| `destination` | string | Destination key identifier | -| `member` | string | Member to be moved | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a boolean specifying if the operation was successful or not. - -## Usage - -<<< ./snippets/smove-1.java - -> Callback response: - -```json -true -``` diff --git a/doc/2/core-classes/memory-storage/smove/snippets/smove-1.java b/doc/2/core-classes/memory-storage/smove/snippets/smove-1.java deleted file mode 100644 index b6843e40..00000000 --- a/doc/2/core-classes/memory-storage/smove/snippets/smove-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.smove("key", "destination", "member", new ResponseListener() { - @Override - public void onSuccess(Boolean status) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sort/index.md b/doc/2/core-classes/memory-storage/sort/index.md deleted file mode 100644 index 9b85788c..00000000 --- a/doc/2/core-classes/memory-storage/sort/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: sort -description: MemoryStorage:sort ---- - -# sort - -Sorts and returns elements contained in a list, a set of unique values or a sorted set. -By default, sorting is numeric and elements are compared by their value interpreted as double precision floating point number. - -:::info -While Kuzzle's API supports the "store" option for this command, Kuzzle SDK methods do not. To sort and store in the same process, use the [query method](/sdk/java/2/core-classes/kuzzle/query) -::: - -[[_Redis documentation_]](https://redis.io/commands/sort) - -### sort(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `alpha` | boolean | Perform an alphanumerical sort instead of a numeric one | `false` | -| `by` | string | Instead of sorting the values stored at `key`, use them to complete the provided key pattern, and return the sorted list of values stored in those keys. | `null` | -| `direction` | string | Sort in ascendant (`ASC`) or descendant (`DESC`) order | `ASC` | -| `get` | array | Sort the values stored at `key` but, instead of returning these directly, return the values contained in external keys, using the provided array of patterns completed by the sorted values | `null` | -| `limit` | array | Limit the result set to a range of matching elements (similar to _SELECT LIMIT offset, count_ in SQL).
Format: `[, ]` | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - -### Callback Response - -Returns an array of sorted values. - -## Usage - -<<< ./snippets/sort-1.java - -> Callback response: - -```json -["sorted element1", "sorted element2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/sort/snippets/sort-1.java b/doc/2/core-classes/memory-storage/sort/snippets/sort-1.java deleted file mode 100644 index aa250a94..00000000 --- a/doc/2/core-classes/memory-storage/sort/snippets/sort-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.sort("key", new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/spop/index.md b/doc/2/core-classes/memory-storage/spop/index.md deleted file mode 100644 index 81a204ac..00000000 --- a/doc/2/core-classes/memory-storage/spop/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: spop -description: MemoryStorage:spop ---- - -# spop - -Removes and returns one or more elements at random from a set of unique values. - -[[_Redis documentation_]](https://redis.io/commands/spop) - ---- - -## spop(key, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `count` | int | Number of elements to remove | `1` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of removed elements. - -## Usage - -<<< ./snippets/spop-1.java - -> Callback response: - -```json -["removed element"] -``` diff --git a/doc/2/core-classes/memory-storage/spop/snippets/spop-1.java b/doc/2/core-classes/memory-storage/spop/snippets/spop-1.java deleted file mode 100644 index db7a18b7..00000000 --- a/doc/2/core-classes/memory-storage/spop/snippets/spop-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.spop("key", new ResponseListener() { - @Override - public void onSuccess(String[] elements) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/srandmember/index.md b/doc/2/core-classes/memory-storage/srandmember/index.md deleted file mode 100644 index 1ead4ac9..00000000 --- a/doc/2/core-classes/memory-storage/srandmember/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: srandmember -description: MemoryStorage:srandmember ---- - -# srandmember - -Returns one or more members of a set of unique values, at random. -If `count` is provided and is positive, the returned values are unique. If `count` is negative, a set member can be returned multiple times. - -[[_Redis documentation_]](https://redis.io/commands/srandmember) - ---- - -## srandmember(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `count` | int | Number of members to return. If set with a positive value, the returned values are unique. If `count` is negative, a set member can be returned multiple times | `1` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of members of a set of unique values. - -## Usage - -<<< ./snippets/srandmember-1.java - -> Callback response: - -```json -["member1", "member2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/srandmember/snippets/srandmember-1.java b/doc/2/core-classes/memory-storage/srandmember/snippets/srandmember-1.java deleted file mode 100644 index fa4ffc3d..00000000 --- a/doc/2/core-classes/memory-storage/srandmember/snippets/srandmember-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.srandmember("key", new ResponseListener() { - @Override - public void onSuccess(String[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/srem/index.md b/doc/2/core-classes/memory-storage/srem/index.md deleted file mode 100644 index bdeb17a3..00000000 --- a/doc/2/core-classes/memory-storage/srem/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: srem -description: MemoryStorage:srem ---- - -# srem - -Removes members from a set of unique values. - -[[_Redis documentation_]](https://redis.io/commands/srem) - ---- - -## srem(key, members, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------- | -| `key` | string | Key identifier | -| `members` | array | List of members to remove from the set | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of removed elements. - -## Usage - -<<< ./snippets/srem-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/srem/snippets/srem-1.java b/doc/2/core-classes/memory-storage/srem/snippets/srem-1.java deleted file mode 100644 index f6b312b7..00000000 --- a/doc/2/core-classes/memory-storage/srem/snippets/srem-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] members = new String[]{"member1", "member2", "..."}; - -kuzzle.memoryStorage.srem("key", members, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sscan/index.md b/doc/2/core-classes/memory-storage/sscan/index.md deleted file mode 100644 index dc51561a..00000000 --- a/doc/2/core-classes/memory-storage/sscan/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: sscan -description: MemoryStorage:sscan ---- - -# sscan - -Identical to [scan](/sdk/java/2/core-classes/memory-storage/scan), except that `sscan` iterates the members held by a set of unique values. - -[[_Redis documentation_]](https://redis.io/commands/sscan) - ---- - -## sscan(key, cursor, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `cursor` | int | Page number (iteration starts with a cursor value of `0`, and ends when the next cursor position is `0`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------- | ------- | -| `count` | int | Return the _approximate_ `count` number of items per result page | `10` | -| `match` | string | Search only for member values matching the provided pattern | `*` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a JSON array containing 2 entries: - -- the cursor position for the next page of results (a next position of `0` indicates the end of the scan) -- an array of members - -## Usage - -<<< ./snippets/sscan-1.java - -> Callback response: - -```json -{ - "cursor": 18, - "values": ["member1", "member2", "..."] -} -``` diff --git a/doc/2/core-classes/memory-storage/sscan/snippets/sscan-1.java b/doc/2/core-classes/memory-storage/sscan/snippets/sscan-1.java deleted file mode 100644 index 37160c59..00000000 --- a/doc/2/core-classes/memory-storage/sscan/snippets/sscan-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.sscan("key", 0, new ResponseListener() { - @Override - public void onSuccess(JSONObject page) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/strlen/index.md b/doc/2/core-classes/memory-storage/strlen/index.md deleted file mode 100644 index ebdf7ca1..00000000 --- a/doc/2/core-classes/memory-storage/strlen/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: strlen -description: MemoryStorage:strlen ---- - -# strlen - -Returns the length of a value stored at `key`. - -[[_Redis documentation_]](https://redis.io/commands/strlen) - ---- - -## strlen(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the length of a value. - -## Usage - -<<< ./snippets/strlen-1.java - -> Callback response: - -```json -13 -``` diff --git a/doc/2/core-classes/memory-storage/strlen/snippets/strlen-1.java b/doc/2/core-classes/memory-storage/strlen/snippets/strlen-1.java deleted file mode 100644 index 89461479..00000000 --- a/doc/2/core-classes/memory-storage/strlen/snippets/strlen-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.strlen("key", new ResponseListener() { - @Override - public void onSuccess(int length) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sunion/index.md b/doc/2/core-classes/memory-storage/sunion/index.md deleted file mode 100644 index 198e1964..00000000 --- a/doc/2/core-classes/memory-storage/sunion/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: sunion -description: MemoryStorage:sunion ---- - -# sunion - -Returns the union of the provided sets of unique values. - -[[_Redis documentation_]](https://redis.io/commands/sunion) - ---- - -## sunion(keys, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------- | -| `keys` | string | List of sets of unique values | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of values in the computed union. - -## Usage - -<<< ./snippets/sunion-1.java - -> Callback response: - -```json -["union value1", "union value2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/sunion/snippets/sunion-1.java b/doc/2/core-classes/memory-storage/sunion/snippets/sunion-1.java deleted file mode 100644 index c3a11422..00000000 --- a/doc/2/core-classes/memory-storage/sunion/snippets/sunion-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sunion(keys, new ResponseListener() { - @Override - public void onSuccess(String[] values) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/sunionstore/index.md b/doc/2/core-classes/memory-storage/sunionstore/index.md deleted file mode 100644 index 43c5d45d..00000000 --- a/doc/2/core-classes/memory-storage/sunionstore/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: sunionstore -description: MemoryStorage:sunionstore ---- - -# sunionstore - -Computes the union of the provided sets of unique values and stores the result in the `destination` key. - -If the destination key already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/sunionstore) - ---- - -## sunionstore(destination, keys, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `destination` | string | Destination key identifier | -| `keys` | string | List of sets of unique values to intersect | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of elements in the stored union. - -## Usage - -<<< ./snippets/sunionstore-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/sunionstore/snippets/sunionstore-1.java b/doc/2/core-classes/memory-storage/sunionstore/snippets/sunionstore-1.java deleted file mode 100644 index cefa5da2..00000000 --- a/doc/2/core-classes/memory-storage/sunionstore/snippets/sunionstore-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.sunionstore("destination", keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/time/index.md b/doc/2/core-classes/memory-storage/time/index.md deleted file mode 100644 index f5161a7b..00000000 --- a/doc/2/core-classes/memory-storage/time/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: time -description: MemoryStorage:time ---- - -# time - -Returns the current server time. - -[[_Redis documentation_]](https://redis.io/commands/time) - ---- - -## time([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array containing the following two items, in this order: - -- a timestamp in [Epoch time](https://en.wikipedia.org/wiki/Unix_time) -- the number of microseconds already elapsed in the current second - -## Usage - -<<< ./snippets/time-1.java - -> Callback response: - -```json -[1488791347, 494938] -``` diff --git a/doc/2/core-classes/memory-storage/time/snippets/time-1.java b/doc/2/core-classes/memory-storage/time/snippets/time-1.java deleted file mode 100644 index edf39d51..00000000 --- a/doc/2/core-classes/memory-storage/time/snippets/time-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.time(new ResponseListener() { - @Override - public void onSuccess(Long[] result) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/touch/index.md b/doc/2/core-classes/memory-storage/touch/index.md deleted file mode 100644 index 401ea608..00000000 --- a/doc/2/core-classes/memory-storage/touch/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -code: true -type: page -title: touch -description: MemoryStorage:touch ---- - -# touch - -Alters the last access time of one or multiple keys. A key is ignored if it does not exist. - -[[_Redis documentation_]](https://redis.io/commands/touch) - ---- - -## touch(keys, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------- | -| `keys` | array | List of keys to alter | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of altered keys. - -## Usage - -<<< ./snippets/touch-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/touch/snippets/touch-1.java b/doc/2/core-classes/memory-storage/touch/snippets/touch-1.java deleted file mode 100644 index e5cf6365..00000000 --- a/doc/2/core-classes/memory-storage/touch/snippets/touch-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.touch(keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/ttl/index.md b/doc/2/core-classes/memory-storage/ttl/index.md deleted file mode 100644 index 8b87d34e..00000000 --- a/doc/2/core-classes/memory-storage/ttl/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: ttl -description: MemoryStorage:ttl ---- - -# ttl - -Returns the remaining time to live of a key, in seconds, or a negative value if the key does not exist or if it is persistent. - -[[_Redis documentation_]](https://redis.io/commands/ttl) - ---- - -## ttl(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the remaining time to live of the key, in seconds. - -## Usage - -<<< ./snippets/ttl-1.java - -> Callback response: - -```json -42 -``` diff --git a/doc/2/core-classes/memory-storage/ttl/snippets/ttl-1.java b/doc/2/core-classes/memory-storage/ttl/snippets/ttl-1.java deleted file mode 100644 index e934326d..00000000 --- a/doc/2/core-classes/memory-storage/ttl/snippets/ttl-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.ttl("key", new ResponseListener() { - @Override - public void onSuccess(int ttl) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/type/index.md b/doc/2/core-classes/memory-storage/type/index.md deleted file mode 100644 index cd556f8a..00000000 --- a/doc/2/core-classes/memory-storage/type/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: type -description: MemoryStorage:type ---- - -# type - -Returns the type of the value held by a key. - -[[_Redis documentation_]](https://redis.io/commands/type) - ---- - -## type(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns one of the following values: `hash`, `list`, `set`, `string`, `zset`. - -## Usage - -<<< ./snippets/type-1.java - -> Callback response: - -```json -"zset" -``` diff --git a/doc/2/core-classes/memory-storage/type/snippets/type-1.java b/doc/2/core-classes/memory-storage/type/snippets/type-1.java deleted file mode 100644 index 87414a34..00000000 --- a/doc/2/core-classes/memory-storage/type/snippets/type-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.type("key", new ResponseListener() { - @Override - public void onSuccess(String type) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zadd/index.md b/doc/2/core-classes/memory-storage/zadd/index.md deleted file mode 100644 index 12d4c733..00000000 --- a/doc/2/core-classes/memory-storage/zadd/index.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -code: true -type: page -title: zadd -description: MemoryStorage:zadd ---- - -# zadd - -Adds the specified elements to the sorted set stored at `key`. If the key does not exist, it is created, holding an empty sorted set. If it already exists and does not hold a sorted set, an error is returned. - -Scores are expressed as floating point numbers. - -If a member to insert is already in the sorted set, its score is updated and the member is reinserted at the right position in the set. - -[[_Redis documentation_]](https://redis.io/commands/zadd) - ---- - -## zadd(key, elements, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `elements` | array | List of JSON objects detailing the element to add to the sorted set.
Properties: `score` (element's score, `double`), `member` (element's value, `string`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `ch` | boolean | Instead of returning the number of added allements, return the total number of changes performed (including updates) | `false` | -| `incr` | boolean | Instead of adding elements, increment the existing member with the provided `score` value. Only one score+element pair can be specified if this option is set | `false` | -| `nx` | boolean | Only add new elements, do not update existing ones | `false` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `xx` | boolean | Never add new elements, update only exiting ones | `false` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of elements added to the sorted set. - -## Usage - -<<< ./snippets/zadd-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/zadd/snippets/zadd-1.java b/doc/2/core-classes/memory-storage/zadd/snippets/zadd-1.java deleted file mode 100644 index 4ef2d10e..00000000 --- a/doc/2/core-classes/memory-storage/zadd/snippets/zadd-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject[] elements = new JSONObject[]{ - new JSONObject().put("score", 1).put("member", "foo"), - new JSONObject().put("score", 2).put("member", "bar"), - new JSONObject().put("score", 3).put("member", "baz") -}; - -kuzzle.memoryStorage.zadd("key", elements new ResponseListener() { - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zcard/index.md b/doc/2/core-classes/memory-storage/zcard/index.md deleted file mode 100644 index 44a72dc2..00000000 --- a/doc/2/core-classes/memory-storage/zcard/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: zcard -description: MemoryStorage:zcard ---- - -# zcard - -Returns the number of elements held by a sorted set. - -[[_Redis documentation_]](https://redis.io/commands/zcard) - ---- - -## zcard(key, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of elements in a sorted set. - -## Usage - -<<< ./snippets/zcard-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/zcard/snippets/zcard-1.java b/doc/2/core-classes/memory-storage/zcard/snippets/zcard-1.java deleted file mode 100644 index adfc20f5..00000000 --- a/doc/2/core-classes/memory-storage/zcard/snippets/zcard-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zcard("key", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zcount/index.md b/doc/2/core-classes/memory-storage/zcount/index.md deleted file mode 100644 index 650b9a44..00000000 --- a/doc/2/core-classes/memory-storage/zcount/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -code: true -type: page -title: zcount -description: MemoryStorage:zcount ---- - -# zcount - -Returns the number of elements held by a sorted set with a score between the provided `min` and `max` values. - -By default, the provided min and max values are inclusive. This behavior can be changed using the syntax described in the Redis [ZRANGEBYSCORE](https://redis.io/commands/zrangebyscore) documentation. - -[[_Redis documentation_]](https://redis.io/commands/zcount) - ---- - -## zcount(key, min, max, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------ | -| `key` | string | Key identifier | -| `min` | int | Minimum score (inclusive by default) | -| `max` | int | Maximum score (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of elements in the provided score range. - -## Usage - -<<< ./snippets/zcount-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/zcount/snippets/zcount-1.java b/doc/2/core-classes/memory-storage/zcount/snippets/zcount-1.java deleted file mode 100644 index f5fe72bc..00000000 --- a/doc/2/core-classes/memory-storage/zcount/snippets/zcount-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zcount("key", 2, 3, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zincrby/index.md b/doc/2/core-classes/memory-storage/zincrby/index.md deleted file mode 100644 index 1a632b48..00000000 --- a/doc/2/core-classes/memory-storage/zincrby/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: zincrby -description: MemoryStorage:zincrby ---- - -# zincrby - -Increments the score of a `member` in a sorted set by the provided `value`. - -[[_Redis documentation_]](https://redis.io/commands/zincrby) - ---- - -## zincrby(key, member, increment, [options], [callback]) - -| Arguments | Type | Description | -| ----------- | ----------- | --------------------------- | -| `key` | string | Key identifier | -| `member` | string | Member element to increment | -| `increment` | double | Increment value | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns a double containing the updated member's score in the sorted set. - -## Usage - -<<< ./snippets/zincrby-1.java - -> Callback response: - -```json -4.14159 -``` diff --git a/doc/2/core-classes/memory-storage/zincrby/snippets/zincrby-1.java b/doc/2/core-classes/memory-storage/zincrby/snippets/zincrby-1.java deleted file mode 100644 index 5830ab5c..00000000 --- a/doc/2/core-classes/memory-storage/zincrby/snippets/zincrby-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zincrby("key", "foo", 3.14159, new ResponseListener() { - @Override - public void onSuccess(double value) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zinterstore/index.md b/doc/2/core-classes/memory-storage/zinterstore/index.md deleted file mode 100644 index 7012e550..00000000 --- a/doc/2/core-classes/memory-storage/zinterstore/index.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -code: true -type: page -title: zinterstore -description: MemoryStorage:zinterstore ---- - -# zinterstore - -Computes the intersection of the provided sorted sets and stores the result in the `destination` key. - -If the destination key already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/zinterstore) - ---- - -## zinterstore(destination, keys, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | -------------------------------- | -| `destination` | string | Destination key identifier | -| `keys` | string | List of sorted sets to intersect | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------- | ------- | ----------------------------------------------------------------------------------------------------------- | ------- | -| `aggregate` | string | Specify how members' scores are aggregated during the intersection.
Allowed values: `min`, `max`, `sum` | `sum` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `weights` | array | Specify a multiplication factor for each input sorted set | `[1]` | - ---- - -## Callback Response - -Returns an integer containing the number of members in the stored intersection. - -## Usage - -<<< ./snippets/zinterstore-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/zinterstore/snippets/zinterstore-1.java b/doc/2/core-classes/memory-storage/zinterstore/snippets/zinterstore-1.java deleted file mode 100644 index 0eab45cd..00000000 --- a/doc/2/core-classes/memory-storage/zinterstore/snippets/zinterstore-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.zinterstore("destination", keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zlexcount/index.md b/doc/2/core-classes/memory-storage/zlexcount/index.md deleted file mode 100644 index 4befc45f..00000000 --- a/doc/2/core-classes/memory-storage/zlexcount/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: zlexcount -description: MemoryStorage:zlexcount ---- - -# zlexcount - -Counts elements in a sorted set where all members have equal score, using lexicographical ordering. The `min` and `max` values are inclusive by default. To change this behavior, please check the syntax detailed in the [Redis documentation](https://redis.io/commands/zrangebylex). - -[[_Redis documentation_]](https://redis.io/commands/zlexcount) - ---- - -## zlexcount(key, min, max, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `min` | string | Minimum member value (inclusive by default) | -| `max` | string | Maximum member value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the number of elements in the provided lexicographical value range. - -## Usage - -<<< ./snippets/zlexcount-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/zlexcount/snippets/zlexcount-1.java b/doc/2/core-classes/memory-storage/zlexcount/snippets/zlexcount-1.java deleted file mode 100644 index cb5f22b8..00000000 --- a/doc/2/core-classes/memory-storage/zlexcount/snippets/zlexcount-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zlexcount("key", "[b", "[f", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrange/index.md b/doc/2/core-classes/memory-storage/zrange/index.md deleted file mode 100644 index 69d15261..00000000 --- a/doc/2/core-classes/memory-storage/zrange/index.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -code: true -type: page -title: zrange -description: MemoryStorage:zrange ---- - -# zrange - -Returns elements from a sorted set depending on their position in the set, from a `start` position index to a `stop` position index (inclusives). -First position starts at `0`. - -[[_Redis documentation_]](https://redis.io/commands/zrange) - ---- - -## zrange(key, start, stop, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------- | -| `key` | string | Key identifier | -| `start` | int | Start position in the set (index starts at position `0`) | -| `stop` | int | End position in the set | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of objects, each containing the following properties: - -- `member`: member value in the sorted set -- `score`: member associated score - -## Usage - -<<< ./snippets/zrange-1.java - -> Callback response: - -```json -[ - { "member": "foo", "score": 1 }, - { "member": "bar", "score": 2 }, - { "member": "baz", "score": 3 } -] -``` diff --git a/doc/2/core-classes/memory-storage/zrange/snippets/zrange-1.java b/doc/2/core-classes/memory-storage/zrange/snippets/zrange-1.java deleted file mode 100644 index 94bd9aaf..00000000 --- a/doc/2/core-classes/memory-storage/zrange/snippets/zrange-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrange("key", 0, -1, new ResponseListener() { - @Override - public void onSuccess(JSONObject[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrangebylex/index.md b/doc/2/core-classes/memory-storage/zrangebylex/index.md deleted file mode 100644 index 3f8c2b5f..00000000 --- a/doc/2/core-classes/memory-storage/zrangebylex/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: zrangebylex -description: MemoryStorage:zrangebylex ---- - -# zrangebylex - -Returns elements in a sorted set where all members have equal score, using lexicographical ordering. The `min` and `max` values are inclusive by default. To change this behavior, please check the full documentation. - -[[_Redis documentation_]](https://redis.io/commands/zrangebylex) - ---- - -## zrangebylex(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `min` | string | Minimum member value (inclusive by default) | -| `max` | string | Maximum member value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `limit` | array | Limit the result set to a range of matching elements (similar to _SELECT LIMIT offset, count_ in SQL).
Format: `[, ]` | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of matching members. - -## Usage - -<<< ./snippets/zrangebylex-1.java - -> Callback response: - -```json -["member1", "member2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/zrangebylex/snippets/zrangebylex-1.java b/doc/2/core-classes/memory-storage/zrangebylex/snippets/zrangebylex-1.java deleted file mode 100644 index 90cfa2b4..00000000 --- a/doc/2/core-classes/memory-storage/zrangebylex/snippets/zrangebylex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrangebylex("key", "-", "(g", new ResponseListener() { - @Override - public void onSuccess(String[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrangebyscore/index.md b/doc/2/core-classes/memory-storage/zrangebyscore/index.md deleted file mode 100644 index f32eb128..00000000 --- a/doc/2/core-classes/memory-storage/zrangebyscore/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: zrangebyscore -description: MemoryStorage:zrangebyscore ---- - -# zrangebyscore - -Returns all the elements in the sorted set at key with a score between `min` and `max` (inclusive). The elements are considered to be ordered from low to high scores. - -[[_Redis documentation_]](https://redis.io/commands/zrangebyscore) - ---- - -## zrangebyscore(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------ | -| `key` | string | Key identifier | -| `min` | double | Minimum score value (inclusive by default) | -| `max` | double | Maximum score value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `limit` | array | Limit the result set to a range of matching elements (similar to _SELECT LIMIT offset, count_ in SQL).
Format: `[, ]` | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of matching members. - -## Usage - -<<< ./snippets/zrangebyscore-1.java - -> Callback response: - -```json -[ - { "member": "foo", "score": 1 }, - { "member": "bar", "score": 2 }, - { "member": "baz", "score": 3 } -] -``` diff --git a/doc/2/core-classes/memory-storage/zrangebyscore/snippets/zrangebyscore-1.java b/doc/2/core-classes/memory-storage/zrangebyscore/snippets/zrangebyscore-1.java deleted file mode 100644 index 5ae0e564..00000000 --- a/doc/2/core-classes/memory-storage/zrangebyscore/snippets/zrangebyscore-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrangebyscore("key", 2, 3, new ResponseListener() { - @Override - public void onSuccess(JSONObject[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrank/index.md b/doc/2/core-classes/memory-storage/zrank/index.md deleted file mode 100644 index 017913d9..00000000 --- a/doc/2/core-classes/memory-storage/zrank/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: zrank -description: MemoryStorage:zrank ---- - -# zrank - -Returns the position of an element in a sorted set, with scores in ascending order. The index returned is 0-based (the lowest score member has an index of 0). - -[[_Redis documentation_]](https://redis.io/commands/zrank) - ---- - -## zrank(key, member, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------ | -| `key` | string | Key identifier | -| `member` | string | Member of the sorted set | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the member's position in the sorted set. - -## Usage - -<<< ./snippets/zrank-1.java - -> Callback response: - -```json -0 -``` diff --git a/doc/2/core-classes/memory-storage/zrank/snippets/zrank-1.java b/doc/2/core-classes/memory-storage/zrank/snippets/zrank-1.java deleted file mode 100644 index cb688cc1..00000000 --- a/doc/2/core-classes/memory-storage/zrank/snippets/zrank-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrank("key", "member", new ResponseListener() { - @Override - public void onSuccess(int position) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrem/index.md b/doc/2/core-classes/memory-storage/zrem/index.md deleted file mode 100644 index a1b2220c..00000000 --- a/doc/2/core-classes/memory-storage/zrem/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: zrem -description: MemoryStorage:zrem ---- - -# zrem - -Removes members from a sorted set. - -[[_Redis documentation_]](https://redis.io/commands/zrem) - ---- - -## zrem(key, members, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------- | -| `key` | string | Key identifier | -| `members` | array | List of members to remove | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of members removed from the sorted set. - -## Usage - -<<< ./snippets/zrem-1.java - -> Callback response: - -```json -3 -``` diff --git a/doc/2/core-classes/memory-storage/zrem/snippets/zrem-1.java b/doc/2/core-classes/memory-storage/zrem/snippets/zrem-1.java deleted file mode 100644 index 11918285..00000000 --- a/doc/2/core-classes/memory-storage/zrem/snippets/zrem-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] members = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.zrem("key", members, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zremrangebylex/index.md b/doc/2/core-classes/memory-storage/zremrangebylex/index.md deleted file mode 100644 index c4fb65d5..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebylex/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: zremrangebylex -description: MemoryStorage:zremrangebylex ---- - -# zremrangebylex - -Removes members from a sorted set where all elements have the same score, using lexicographical ordering. The `min` and `max` interval are inclusive, see the [Redis documentation](https://redis.io/commands/zrangebylex) to change this behavior. - -[[_Redis documentation_]](https://redis.io/commands/zremrangebylex) - ---- - -## zremrangebylex(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `min` | string | Minimum member value (inclusive by default) | -| `max` | string | Maximum member value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of removed members from the sorted set. - -## Usage - -<<< ./snippets/zremrangebylex-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/zremrangebylex/snippets/zremrangebylex-1.java b/doc/2/core-classes/memory-storage/zremrangebylex/snippets/zremrangebylex-1.java deleted file mode 100644 index f11dbb98..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebylex/snippets/zremrangebylex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zremrangebylex("key", "[b", "(f", new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zremrangebyrank/index.md b/doc/2/core-classes/memory-storage/zremrangebyrank/index.md deleted file mode 100644 index 5631f7cf..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebyrank/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -code: true -type: page -title: zremrangebyrank -description: MemoryStorage:zremrangebyrank ---- - -# zremrangebyrank - -Removes members from a sorted set with their position in the set between `start` and `stop` (inclusive). - -Positions are 0-based, meaning the first member of the set has a position of 0. - -[[_Redis documentation_]](https://redis.io/commands/zremrangebyrank) - ---- - -## zremrangebyrank(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------------- | -| `key` | string | Key identifier | -| `min` | int | Minimum position index (inclusive by default) | -| `max` | int | Maximum position index (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of removed members from the sorted set. - -## Usage - -<<< ./snippets/zremrangebyrank-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/zremrangebyrank/snippets/zremrangebyrank-1.java b/doc/2/core-classes/memory-storage/zremrangebyrank/snippets/zremrangebyrank-1.java deleted file mode 100644 index 1be4c978..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebyrank/snippets/zremrangebyrank-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zremrangebyrank("key", 1, 2, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zremrangebyscore/index.md b/doc/2/core-classes/memory-storage/zremrangebyscore/index.md deleted file mode 100644 index 3b4a80de..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebyscore/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: zremrangebyscore -description: MemoryStorage:zremrangebyscore ---- - -# zremrangebyscore - -Removes members from a sorted set with a score between `min` and `max` (inclusive by default). - -[[_Redis documentation_]](https://redis.io/commands/zremrangebyscore) - ---- - -## zremrangebyscore(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------ | -| `key` | string | Key identifier | -| `min` | double | Minimum score (inclusive by default) | -| `max` | double | Maximum score (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an integer containing the number of removed members from the sorted set. - -## Usage - -<<< ./snippets/zremrangebyscore-1.java - -> Callback response: - -```json -2 -``` diff --git a/doc/2/core-classes/memory-storage/zremrangebyscore/snippets/zremrangebyscore-1.java b/doc/2/core-classes/memory-storage/zremrangebyscore/snippets/zremrangebyscore-1.java deleted file mode 100644 index 583eaeba..00000000 --- a/doc/2/core-classes/memory-storage/zremrangebyscore/snippets/zremrangebyscore-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zremrangebyscore("key", 1, 2, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrevrange/index.md b/doc/2/core-classes/memory-storage/zrevrange/index.md deleted file mode 100644 index d2cde92c..00000000 --- a/doc/2/core-classes/memory-storage/zrevrange/index.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -code: true -type: page -title: zrevrange -description: MemoryStorage:zrevrange ---- - -# zrevrange - -Identical to [zrange](/sdk/java/2/core-classes/memory-storage/zrange), except that the sorted set is traversed in descending order. - -[[_Redis documentation_]](https://redis.io/commands/zrevrange) - ---- - -## zrevrange(key, start, stop, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------- | -| `key` | string | Key identifier | -| `start` | int | Start position in the set (index starts at position `0`) | -| `stop` | int | End position in the set | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of objects, each containing the following properties: - -- `member`: member value in the sorted set -- `score`: member associated score - -## Usage - -<<< ./snippets/zrevrange-1.java - -> Callback response: - -```json -[ - { "member": "baz", "score": 3 }, - { "member": "bar", "score": 2 }, - { "member": "foo", "score": 1 } -] -``` diff --git a/doc/2/core-classes/memory-storage/zrevrange/snippets/zrevrange-1.java b/doc/2/core-classes/memory-storage/zrevrange/snippets/zrevrange-1.java deleted file mode 100644 index 027d82ed..00000000 --- a/doc/2/core-classes/memory-storage/zrevrange/snippets/zrevrange-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrevrange("key", 0, -1, new ResponseListener() { - @Override - public void onSuccess(JSONObject[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrevrangebylex/index.md b/doc/2/core-classes/memory-storage/zrevrangebylex/index.md deleted file mode 100644 index 3eb4feac..00000000 --- a/doc/2/core-classes/memory-storage/zrevrangebylex/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: zrevrangebylex -description: MemoryStorage:zrevrangebylex ---- - -# zrevrangebylex - -Identical to [zrangebylex](/sdk/java/2/core-classes/memory-storage/zrangebylex) except that the sorted set is traversed in descending order. - -[[_Redis documentation_]](https://redis.io/commands/zrevrangebylex) - ---- - -## zrevrangebylex(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------- | -| `key` | string | Key identifier | -| `min` | string | Minimum member value (inclusive by default) | -| `max` | string | Maximum member value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `limit` | array | Limit the result set to a range of matching elements (similar to _SELECT LIMIT offset, count_ in SQL).
Format: `[, ]` | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of matching members. - -## Usage - -<<< ./snippets/zrevrangebylex-1.java - -> Callback response: - -```json -["member1", "member2", "..."] -``` diff --git a/doc/2/core-classes/memory-storage/zrevrangebylex/snippets/zrevrangebylex-1.java b/doc/2/core-classes/memory-storage/zrevrangebylex/snippets/zrevrangebylex-1.java deleted file mode 100644 index c526d829..00000000 --- a/doc/2/core-classes/memory-storage/zrevrangebylex/snippets/zrevrangebylex-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrevrangebylex("key", "-", "(g", new ResponseListener() { - @Override - public void onSuccess(String[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrevrangebyscore/index.md b/doc/2/core-classes/memory-storage/zrevrangebyscore/index.md deleted file mode 100644 index 525aed8e..00000000 --- a/doc/2/core-classes/memory-storage/zrevrangebyscore/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: zrevrangebyscore -description: MemoryStorage:zrevrangebyscore ---- - -# zrevrangebyscore - -Identical to [zrangebyscore](/sdk/java/2/core-classes/memory-storage/zrangebyscore) except that the sorted set is traversed in descending order. - -[[_Redis documentation_]](https://redis.io/commands/zrevrangebyscore) - ---- - -## zrevrangebyscore(key, min, max, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------ | -| `key` | string | Key identifier | -| `min` | double | Minimum score value (inclusive by default) | -| `max` | double | Maximum score value (inclusive by default) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `limit` | array | Limit the result set to a range of matching elements (similar to _SELECT LIMIT offset, count_ in SQL).
Format: `[, ]` | `null` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return value - -Returns the `MemoryStorage` object to allow chaining. - ---- - -## Callback Response - -Returns an array of matching members. - -## Usage - -<<< ./snippets/zrevrangebyscore-1.java - -> Callback response: - -```json -[ - { "member": "baz", "score": 3 }, - { "member": "bar", "score": 2 }, - { "member": "foo", "score": 1 } -] -``` diff --git a/doc/2/core-classes/memory-storage/zrevrangebyscore/snippets/zrevrangebyscore-1.java b/doc/2/core-classes/memory-storage/zrevrangebyscore/snippets/zrevrangebyscore-1.java deleted file mode 100644 index 3bd7961b..00000000 --- a/doc/2/core-classes/memory-storage/zrevrangebyscore/snippets/zrevrangebyscore-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrevrangebyscore("key", 2, 3, new ResponseListener() { - @Override - public void onSuccess(JSONObject[] members) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zrevrank/index.md b/doc/2/core-classes/memory-storage/zrevrank/index.md deleted file mode 100644 index 24abc5bf..00000000 --- a/doc/2/core-classes/memory-storage/zrevrank/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: zrevrank -description: MemoryStorage:zrevrank ---- - -# zrevrank - -Returns the position of an element in a sorted set, with scores in descending order. The index returned is 0-based (the lowest score member has an index of 0). - -[[_Redis documentation_]](https://redis.io/commands/zrevrank) - ---- - -## zrevrank(key, member, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------ | -| `key` | string | Key identifier | -| `member` | string | Member of the sorted set | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an integer containing the member's position in the sorted set. - -## Usage - -<<< ./snippets/zrevrank-1.java - -> Callback response: - -```json -0 -``` diff --git a/doc/2/core-classes/memory-storage/zrevrank/snippets/zrevrank-1.java b/doc/2/core-classes/memory-storage/zrevrank/snippets/zrevrank-1.java deleted file mode 100644 index acedf859..00000000 --- a/doc/2/core-classes/memory-storage/zrevrank/snippets/zrevrank-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zrevrank("key", "member", new ResponseListener() { - @Override - public void onSuccess(int position) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zscan/index.md b/doc/2/core-classes/memory-storage/zscan/index.md deleted file mode 100644 index 4a659e4c..00000000 --- a/doc/2/core-classes/memory-storage/zscan/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: zscan -description: MemoryStorage:zscan ---- - -# zscan - -Identical to [scan](/sdk/java/2/core-classes/memory-storage/scan), except that `zscan` iterates the members held by a sorted set. - -[[_Redis documentation_]](https://redis.io/commands/zscan) - ---- - -## zscan(key, cursor, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------------------------------------------------------------------- | -| `key` | string | Key identifier | -| `cursor` | int | Page number (iteration starts with a cursor value of `0`, and ends when the next cursor position is `0`) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------- | ------- | -| `count` | int | Return the _approximate_ `count` number of items per result page | `10` | -| `match` | string | Search only for member values matching the provided pattern | `*` | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a JSON array containing 2 entries: - -- the cursor position for the next page of results (a next position of `0` indicates the end of the scan) -- an array of sorted set members and their associated scores - -## Usage - -<<< ./snippets/zscan-1.java - -> Callback response: - -```json -{ - "cursor": 18, - "values": ["member1", "member1's score", "member2", "member2's score", "..."] -} -``` diff --git a/doc/2/core-classes/memory-storage/zscan/snippets/zscan-1.java b/doc/2/core-classes/memory-storage/zscan/snippets/zscan-1.java deleted file mode 100644 index 6988fe4b..00000000 --- a/doc/2/core-classes/memory-storage/zscan/snippets/zscan-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zscan("key", 0, new ResponseListener() { - @Override - public void onSuccess(JSONObject page) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zscore/index.md b/doc/2/core-classes/memory-storage/zscore/index.md deleted file mode 100644 index b02a61ea..00000000 --- a/doc/2/core-classes/memory-storage/zscore/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: zscore -description: MemoryStorage:zscore ---- - -# zscore - -Returns the score of a member in a sorted set. - -[[_Redis documentation_]](https://redis.io/commands/zscore) - ---- - -## zscore(key, member, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------- | -| `key` | string | Key identifier | -| `member` | string | Sorted set member | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a floating point number containing the searched member's score. - -## Usage - -<<< ./snippets/zscore-1.java - -> Callback response: - -```json -1 -``` diff --git a/doc/2/core-classes/memory-storage/zscore/snippets/zscore-1.java b/doc/2/core-classes/memory-storage/zscore/snippets/zscore-1.java deleted file mode 100644 index 60e8b0df..00000000 --- a/doc/2/core-classes/memory-storage/zscore/snippets/zscore-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -kuzzle.memoryStorage.zscore("key", "bar", new ResponseListener() { - @Override - public void onSuccess(double score) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/memory-storage/zunionstore/index.md b/doc/2/core-classes/memory-storage/zunionstore/index.md deleted file mode 100644 index b9bdf05d..00000000 --- a/doc/2/core-classes/memory-storage/zunionstore/index.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -code: true -type: page -title: zunionstore -description: MemoryStorage:zunionstore ---- - -# zunionstore - -Computes the union of the provided sorted sets and stores the result in the `destination` key. - -If the destination key already exists, it is overwritten. - -[[_Redis documentation_]](https://redis.io/commands/zunionstore) - ---- - -## zunionstore(destination, keys, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | -------------------------------- | -| `destination` | string | Destination key identifier | -| `keys` | string | List of sorted sets to intersect | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------- | ------- | ----------------------------------------------------------------------------------------------------------- | ------- | -| `aggregate` | string | Specify how members' scores are aggregated during the intersection.
Allowed values: `min`, `max`, `sum` | `sum` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `weights` | array | Specify a multiplication factor for each input sorted set | `[1]` | - ---- - -## Callback Response - -Returns an integer containing the number of members in the stored union. - -## Usage - -<<< ./snippets/zunionstore-1.java - -> Callback response: - -```json -4 -``` diff --git a/doc/2/core-classes/memory-storage/zunionstore/snippets/zunionstore-1.java b/doc/2/core-classes/memory-storage/zunionstore/snippets/zunionstore-1.java deleted file mode 100644 index d173e4fd..00000000 --- a/doc/2/core-classes/memory-storage/zunionstore/snippets/zunionstore-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -String[] keys = new String[]{"key1", "key2", "..."}; - -kuzzle.memoryStorage.zunionstore("destination", keys, new ResponseListener() { - @Override - public void onSuccess(int count) { - // callback called once the action has completed - } - - @Override - public void onError(JSONObject error) { - } -}); diff --git a/doc/2/core-classes/profile/add-policy/index.md b/doc/2/core-classes/profile/add-policy/index.md deleted file mode 100644 index 13a9af36..00000000 --- a/doc/2/core-classes/profile/add-policy/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -code: true -type: page -title: addPolicy -description: Profile:addPolicy ---- - -# addPolicy - -Adds a role to the security profile. - -:::info -Updating a security profile will have no impact until the [save](/sdk/java/2/core-classes/profile/save) method is called -::: - ---- - -## addPolicy(id) - -| Arguments | Type | Description | -| --------- | ------ | -------------------------------------- | -| `id` | string | Unique id of the new role to associate | - ---- - -## addPolicy(policy) - -| Arguments | Type | Description | -| --------- | ----------- | ----------------------------------------------------------------------------- | -| `policy` | JSON Object | policy instance corresponding to the new associated role and its restrictions | - ---- - -## Return Value - -Returns the `Profile` object to allow chaining calls. - -## Usage - -<<< ./snippets/add-policy-1.java diff --git a/doc/2/core-classes/profile/add-policy/snippets/add-policy-1.java b/doc/2/core-classes/profile/add-policy/snippets/add-policy-1.java deleted file mode 100644 index 35280791..00000000 --- a/doc/2/core-classes/profile/add-policy/snippets/add-policy-1.java +++ /dev/null @@ -1,15 +0,0 @@ - -JSONObject policy = new JSONObject() - .put("roleId", "some role id") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections", new JSONArray().put("foo").put("bar")) - ) - ); - -profile.addPolicy(policy); - -// you may also add a role ID directly -profile.addPolicy("some role id"); diff --git a/doc/2/core-classes/profile/constructor/index.md b/doc/2/core-classes/profile/constructor/index.md deleted file mode 100644 index b98090ee..00000000 --- a/doc/2/core-classes/profile/constructor/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Profile:constructor -order: 1 ---- - -# Constructors - -Instantiates a new `Profile` object, representing a security [profile](/core/1/guides/essentials/security#users-profiles-and-roles), which is a set of one or many [Role](/sdk/java/2/core-classes/role) objects. - ---- - -## Profile(Security, id, content, [meta]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------- | -| `Security` | Security | An instantiated [Security](/sdk/java/2/core-classes/security) object | -| `id` | string | Unique profile identifier | -| `content` | JSON Object | Profile content | -| `meta` | JSON Object | Profile metadata | - -**Note:** this constructor won't make any call to Kuzzle. - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ----------- | ------------------------- | ------- | -| `content` | JSON object | Raw profile content | get | -| `id` | string | Unique profile identifier | get | -| `meta` | JSON object | Profile metadata | get | - ---- - -## Return Value - -Returns to the `Profile` object. - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/profile/constructor/snippets/constructor-1.java b/doc/2/core-classes/profile/constructor/snippets/constructor-1.java deleted file mode 100644 index fd09501f..00000000 --- a/doc/2/core-classes/profile/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,20 +0,0 @@ - -JSONObject policy1 = new JSONObject() - .put("roleId", "myrole"); - -JSONObject policy2 = new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections",new JSONArray().put("foo").put("bar")) - ) - ); -JSONObject roles = new JSONObject() - .put("policies", new JSONArray() - .put(policy1) - .put(policy2) - ); - -Profile profile = new Profile(kuzzle.security, "profileId", roles); diff --git a/doc/2/core-classes/profile/delete/index.md b/doc/2/core-classes/profile/delete/index.md deleted file mode 100644 index 74767586..00000000 --- a/doc/2/core-classes/profile/delete/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: delete -description: Profile:delete ---- - -# delete - -Deletes this security profile from Kuzzle. - ---- - -## delete([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the ID of the deleted profile. - -## Usage - -<<< ./snippets/delete-1.java diff --git a/doc/2/core-classes/profile/delete/snippets/delete-1.java b/doc/2/core-classes/profile/delete/snippets/delete-1.java deleted file mode 100644 index dfb9e6f4..00000000 --- a/doc/2/core-classes/profile/delete/snippets/delete-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -profile - .delete(new ResponseListener() { - @Override - public void onSuccess(String deleteId) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/profile/get-policies/index.md b/doc/2/core-classes/profile/get-policies/index.md deleted file mode 100644 index 785b5257..00000000 --- a/doc/2/core-classes/profile/get-policies/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: getPolicies -description: Profile:getPolicies ---- - -# getPolicies - -Returns roles associated to this security policy. - ---- - -## Return Value - -Returns an array of roles linked to this security policy. - -## Usage - -<<< ./snippets/get-policies-1.java - -> Callback response - -```json -[ - { - "roleId": "", - "restrictedTo": { - "index": "", - "collections": ["", "", "<...>"] - } - }, - { - "roleId": "" - }, - { - "roleId": "", - "restrictedTo": { - "index": "", - "collections": [""] - } - } -] -``` diff --git a/doc/2/core-classes/profile/get-policies/snippets/get-policies-1.java b/doc/2/core-classes/profile/get-policies/snippets/get-policies-1.java deleted file mode 100644 index 84b89df1..00000000 --- a/doc/2/core-classes/profile/get-policies/snippets/get-policies-1.java +++ /dev/null @@ -1,3 +0,0 @@ - -for(JSONObject policy : profile.getPolicies()) { -} diff --git a/doc/2/core-classes/profile/index.md b/doc/2/core-classes/profile/index.md deleted file mode 100644 index 996694ea..00000000 --- a/doc/2/core-classes/profile/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Profile -description: Profile documentation ---- diff --git a/doc/2/core-classes/profile/save/index.md b/doc/2/core-classes/profile/save/index.md deleted file mode 100644 index 68d14949..00000000 --- a/doc/2/core-classes/profile/save/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: save -description: Profile:save ---- - -# save - -Creates or replaces the profile in Kuzzle. - -:::warning -Saving the object will return an error if the linked roles have not been previously created in Kuzzle. -::: - ---- - -## save([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Profile` object to allow chaining. - ---- - -## Callback Response - -Returns a `Profile` object. - -## Usage - -<<< ./snippets/save-1.java diff --git a/doc/2/core-classes/profile/save/snippets/save-1.java b/doc/2/core-classes/profile/save/snippets/save-1.java deleted file mode 100644 index e8abeeb1..00000000 --- a/doc/2/core-classes/profile/save/snippets/save-1.java +++ /dev/null @@ -1,32 +0,0 @@ - -JSONObject policy1 = new JSONObject() - .put("roleId", "myrole"); - -JSONObject policy2 = new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections",new JSONArray().put("foo").put("bar")) - ) - ); - -JSONObject roles = new JSONObject() - .put("policies", new JSONArray() - .put(policy1) - .put(policy2) - ); - -Profile profile = kuzzle.security.profile("myprofile", roles); - -profile.save(new ResponseListener() { - @Override - public void onSuccess(Profile savedProfile) { - - } - - @Overrid public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/profile/set-content/index.md b/doc/2/core-classes/profile/set-content/index.md deleted file mode 100644 index 8374e6f3..00000000 --- a/doc/2/core-classes/profile/set-content/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -code: true -type: page -title: setContent -description: Profile:setContent ---- - -# setContent - -Replaces the content of the `Profile` object. - -:::info -Updating a profile will have no impact until the `save` method is called -::: - ---- - -## setContent(data) - -| Arguments | Type | Description | -| --------- | ----------- | --------------- | -| `data` | JSON Object | Profile content | - ---- - -## Return Value - -Returns the `Profile` object. - -## Usage - -<<< ./snippets/set-content-1.java diff --git a/doc/2/core-classes/profile/set-content/snippets/set-content-1.java b/doc/2/core-classes/profile/set-content/snippets/set-content-1.java deleted file mode 100644 index 3ec8e775..00000000 --- a/doc/2/core-classes/profile/set-content/snippets/set-content-1.java +++ /dev/null @@ -1,21 +0,0 @@ - -JSONObject policy1 = new JSONObject() - .put("roleId", "myrole"); - -JSONObject policy2 = new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections",new JSONArray().put("foo").put("bar")) - ) - ); - -JSONObject newContent = new JSONObject() - .put("policies", new JSONArray() - .put(policy1) - .put(policy2) - ); - -profile.setContent(newRolesList); diff --git a/doc/2/core-classes/profile/set-policies/index.md b/doc/2/core-classes/profile/set-policies/index.md deleted file mode 100644 index f6a335b3..00000000 --- a/doc/2/core-classes/profile/set-policies/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -code: true -type: page -title: setPolicies -description: Profile:setPolicies ---- - -# setPolicies - -Replaces the roles associated with this security profile. - ---- - -## `setPolicies(Array policyIDs)` - -| Arguments | Type | Description | -| ----------- | ---------------- | ----------------- | -| `policyIDs` | array of strings | Policy IDs to add | - ---- - -## `setPolicies(Array policyDefinitions)` - -| Arguments | Type | Description | -| ------------------- | --------------------- | ------------------------- | -| `policyDefinitions` | array of JSON objects | Policy definitions to add | - ---- - -## Return Value - -Returns the `Profile` object. - -::: info -Updating a profile will have no impact until the `save` method is called -::: - -## Usage - -<<< ./snippets/set-policies-1.java diff --git a/doc/2/core-classes/profile/set-policies/snippets/set-policies-1.java b/doc/2/core-classes/profile/set-policies/snippets/set-policies-1.java deleted file mode 100644 index 0f5bb759..00000000 --- a/doc/2/core-classes/profile/set-policies/snippets/set-policies-1.java +++ /dev/null @@ -1,10 +0,0 @@ - -// Binding role IDs to a profile -profile.setPolicies(new String[]{"role1 ID", "role2 ID", "role3 ID"}); - -// Binding policies definition to a profile -profile.setPolicies(new JSONObject[]{ - new JSONObject().put('roleId', 'role1 ID'), - new JSONObject().put('roleId', 'role2 ID'), - new JSONObject().put('roleId', 'role3 ID') -}); diff --git a/doc/2/core-classes/profile/update/index.md b/doc/2/core-classes/profile/update/index.md deleted file mode 100644 index 371e1f1c..00000000 --- a/doc/2/core-classes/profile/update/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: update -description: Profile:update ---- - -# update - -Performs a partial content update on this object. - ---- - -## update(content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------- | -| `content` | JSON Object | Profile content | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Profile` object to allow chaining. - ---- - -## Callback Response - -Returns the updated version of this object. - -## Usage - -<<< ./snippets/update-1.java diff --git a/doc/2/core-classes/profile/update/snippets/update-1.java b/doc/2/core-classes/profile/update/snippets/update-1.java deleted file mode 100644 index e31f284b..00000000 --- a/doc/2/core-classes/profile/update/snippets/update-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -JSONObject policy1 = new JSONObject().put("roleId", "myrole"); - -JSONObject updateContent = new JSONObject() - .put("policies", new JSONArray().put(policy1)); - -profile.update(updateContent, new ResponseListener() { - @Override - public void onSuccess(Profile updatedProfile) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/role/constructor/index.md b/doc/2/core-classes/role/constructor/index.md deleted file mode 100644 index 0c3d223a..00000000 --- a/doc/2/core-classes/role/constructor/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Role:constructor -order: 1 ---- - -# Constructors - -Instantiates a new `Role` object, which defines a set of right policies. - ---- - -## Role(Security, id, content, [meta]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------- | -| `Security` | Security | An instantiated [Security](/sdk/java/2/core-classes/security) object | -| `id` | string | Unique role identifier | -| `content` | JSON Object | Role content | -| `meta` | JSON Object | Role metadata | - -**Note:** this constructor won't make any call to Kuzzle. - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ----------- | ------------------------- | ------- | -| `content` | JSON object | Raw role content | get | -| `id` | string | Unique profile identifier | get | -| `meta` | JSON object | Role metadata | get | - ---- - -## Return Value - -Returns the `Role` object. - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/role/constructor/snippets/constructor-1.java b/doc/2/core-classes/role/constructor/snippets/constructor-1.java deleted file mode 100644 index 740f55c8..00000000 --- a/doc/2/core-classes/role/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("*", new JSONObject() - .put("actions", new JSONObject() - .put("*", true) - ) - ) - ) -); - -Role role = new Role(kuzzle.security, "role ID", roleDefinition); diff --git a/doc/2/core-classes/role/delete/index.md b/doc/2/core-classes/role/delete/index.md deleted file mode 100644 index 52fb1235..00000000 --- a/doc/2/core-classes/role/delete/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: delete -description: Role:delete ---- - -# delete - -Deletes the role from Kuzzle. - ---- - -## delete([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the ID of the deleted role. - -## Usage - -<<< ./snippets/delete-1.java diff --git a/doc/2/core-classes/role/delete/snippets/delete-1.java b/doc/2/core-classes/role/delete/snippets/delete-1.java deleted file mode 100644 index df0bf65a..00000000 --- a/doc/2/core-classes/role/delete/snippets/delete-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -role.delete(new ResponseListener() { - @Override - public void onSuccess(String deletedId) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/role/index.md b/doc/2/core-classes/role/index.md deleted file mode 100644 index f0d01c2e..00000000 --- a/doc/2/core-classes/role/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Role -description: Role documentation ---- diff --git a/doc/2/core-classes/role/save/index.md b/doc/2/core-classes/role/save/index.md deleted file mode 100644 index b51ae7be..00000000 --- a/doc/2/core-classes/role/save/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: save -description: Role:save ---- - -# save - -Creates or replaces the role in Kuzzle's database layer. - ---- - -## save([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Role` object to allow chaining. - ---- - -## Callback Response - -Returns a `Role` object. - -## Usage - -<<< ./snippets/save-1.java diff --git a/doc/2/core-classes/role/save/snippets/save-1.java b/doc/2/core-classes/role/save/snippets/save-1.java deleted file mode 100644 index f2f1689b..00000000 --- a/doc/2/core-classes/role/save/snippets/save-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -role.save(new ResponseListener { - @Override - public void onSuccess(Role savedRole) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/role/set-content/index.md b/doc/2/core-classes/role/set-content/index.md deleted file mode 100644 index f2154b49..00000000 --- a/doc/2/core-classes/role/set-content/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -code: true -type: page -title: setContent -description: Role:setContent ---- - -# setContent - -Replaces the content of the `Role` object. - -:::info -Updating a role content will have no impact until the [save](/sdk/java/2/core-classes/role/save) method is called -::: - ---- - -## setContent(data) - -| Arguments | Type | Description | -| --------- | ----------- | ------------ | -| `data` | JSON Object | Role content | - ---- - -## Return Value - -Returns the `Role` object. - -## Usage - -<<< ./snippets/set-content-1.java diff --git a/doc/2/core-classes/role/set-content/snippets/set-content-1.java b/doc/2/core-classes/role/set-content/snippets/set-content-1.java deleted file mode 100644 index 9cdbf3ae..00000000 --- a/doc/2/core-classes/role/set-content/snippets/set-content-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("*", new JSONObject() - .put("actions", new JSONObject() - .put("*", true) - ) - ) - ) -); - -role.setContent(roleDefinition); diff --git a/doc/2/core-classes/role/update/index.md b/doc/2/core-classes/role/update/index.md deleted file mode 100644 index c951bce2..00000000 --- a/doc/2/core-classes/role/update/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -code: true -type: page -title: update -description: Role:update ---- - -# update - -Updates the role object in Kuzzle. - -:::warning -Unlike a regular document update, this method will replace the whole role definition under the indexes node with the `updateContent` parameter. -In other words, you always need to provide the complete role definition in the `updateContent` object. - -This method has the same effect as calling [setContent](/sdk/java/2/core-classes/role/set-content) followed by the [save](/sdk/java/2/core-classes/role/save) method. -::: - -To get more information about Kuzzle permissions, please refer to our [permissions guide](/core/1/guides/essentials/security#user-permissions). - ---- - -## update(content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------- | -| `content` | JSON Object | New role content | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `Role` object to allow chaining. - ---- - -## Callback Response - -Returns the updated version of this object. - -## Usage - -<<< ./snippets/update-1.java diff --git a/doc/2/core-classes/role/update/snippets/update-1.java b/doc/2/core-classes/role/update/snippets/update-1.java deleted file mode 100644 index 28ac63c9..00000000 --- a/doc/2/core-classes/role/update/snippets/update-1.java +++ /dev/null @@ -1,22 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("document", new JSONObject() - .put("actions", new JSONObject() - .put("get", true) - ) - ) - ) -); - -role.update(roleDefinition, new ResponseListener() { - @Override - public void onSuccess(Role updatedRole) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/room/constructor/index.md b/doc/2/core-classes/room/constructor/index.md deleted file mode 100644 index 976e5978..00000000 --- a/doc/2/core-classes/room/constructor/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Room:constructor -order: 1 ---- - -# Constructors - -The `Room` object is the result of a subscription request, allowing you to manipulate the subscription itself. - ---- - -## Room(Collection, [options]) - -| Arguments | Type | Description | -| ------------ | ------ | ---------------------------------------- | -| `Collection` | object | an instantiated Kuzzle Collection object | -| `options` | object | Optional subscription configuration | - ---- - -## Options - -| Option | Type | Description | Default | -| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `volatile` | JSON Object | Additional information passed to notifications to other users | `null` | -| `scope` | string | Filter [document notifications](/sdk/java/2/essentials/realtime-notifications#document-notification) depending on their scope status. You may receive entering documents (scope: `in`), leaving documents (scope: `out`), all documents changes (scope: `all`) or filter these notifications completely (scope: `none`). This filter does not affect pub/sub messages or user events. | `all` | -| `state` | string | Filter [document notifications](/sdk/java/2/essentials/realtime-notifications#document-notification) depending on the state of the modifying request. You may receive real-time notifications when a document is about to be changed (state: `pending`), or be notified when the change has been fully written in the database (state: `done`), or both (state: `all`). This filter does not affect pub/sub messages or user events. | `done` | -| `subscribeToSelf` | boolean | (Don't) subscribe to notifications fired as a consequence of our own queries | `true` | -| `users` | string | Filter [user notifications](/sdk/java/2/essentials/realtime-notifications#user-notification) triggered upon a user entering the room (user: `in`), leaving the room (user: `out`), or both (user: `all`). Setting this variable to `none` prevents receiving these notifications | `none` | - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ----------------- | ----------- | ---------------------------------------------------------------------------- | ------- | -| `collection` | string | The subscribed collection | get | -| `filters` | JSON object | The current set of filters of this room | get/set | -| `headers` | JSON Object | Common headers for all sent documents. | get/set | -| `volatile` | JSON Object | Additional information passed to notifications to other users | get/set | -| `subscribeToSelf` | boolean | (Don't) subscribe to notifications fired as a consequence of our own queries | get/set | -| `roomId` | string | Unique room identifier | get | - -**Notes:** - -- the `headers` property is inherited from the provided `Collection` object and can be overridden -- updating the `volatile` property takes effect only after the subscription is renewed -- by default, the global `volatile` properties are sent along with the subscription request. If a `volatile` option is provided during subscription, it will be merged with the global `volatile` for the subscription only. In case of conflicts, subscription `volatile` data takes priority over the global `volatile` ones. - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/room/constructor/snippets/constructor-1.java b/doc/2/core-classes/room/constructor/snippets/constructor-1.java deleted file mode 100644 index a9c633c7..00000000 --- a/doc/2/core-classes/room/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,5 +0,0 @@ - -Room room = new Room(dataCollection); - -RoomOptions options = new RoomOptions().setSubscribeToSelf(false); -Room room = new Room(dataCollection, options); diff --git a/doc/2/core-classes/room/count/index.md b/doc/2/core-classes/room/count/index.md deleted file mode 100644 index 9982097b..00000000 --- a/doc/2/core-classes/room/count/index.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -code: true -type: page -title: count -description: Room:count ---- - -# count - -Returns the number of subscribers in the room. - ---- - -## count(callback) - -| Arguments | Type | Description | -| ---------- | -------- | ------------------------------ | -| `callback` | function | Callback handling the response | - ---- - -## Callback Response - -Returns an `integer` containing the number of users subscribing to this room. - -## Usage - -<<< ./snippets/count-1.java - -> Callback response - -```json -1 -``` diff --git a/doc/2/core-classes/room/count/snippets/count-1.java b/doc/2/core-classes/room/count/snippets/count-1.java deleted file mode 100644 index eb1162e1..00000000 --- a/doc/2/core-classes/room/count/snippets/count-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -room.count(new ResponseListener() { - @Override - public void onSuccess(Integer result) throws Exception { - // ... - } - - @Override - public void onError(JSONObject error) throws Exception { - // Handle error - } -}); diff --git a/doc/2/core-classes/room/index.md b/doc/2/core-classes/room/index.md deleted file mode 100644 index acee84a3..00000000 --- a/doc/2/core-classes/room/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Room -description: Room documentation ---- diff --git a/doc/2/core-classes/room/renew/index.md b/doc/2/core-classes/room/renew/index.md deleted file mode 100644 index a30a9d5e..00000000 --- a/doc/2/core-classes/room/renew/index.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -code: true -type: page -title: renew -description: Room:renew ---- - -# renew - -Renew the subscription. Force a new subscription using the same filters if no new ones are provided. - -Unsubscribes first if this `Room` object was already listening to events. - ---- - -## renew([filters], notificationCallback, subscriptionCallback) - -| Arguments | Type | Description | -| ---------------------- | ----------- | ------------------------------------------------------------------------------------------------ | -| `filters` | JSON Object | [Filters](/core/1/guides/cookbooks/realtime-api) | -| `notificationCallback` | function | Function called each time a [notification](/sdk/java/2/essentials/realtime-notifications) is received | -| `subscriptionCallback` | function | Function called with the subscription result | - -## Usage - -<<< ./snippets/renew-1.java diff --git a/doc/2/core-classes/room/renew/snippets/renew-1.java b/doc/2/core-classes/room/renew/snippets/renew-1.java deleted file mode 100644 index e350bedf..00000000 --- a/doc/2/core-classes/room/renew/snippets/renew-1.java +++ /dev/null @@ -1,49 +0,0 @@ - -JSONObject filter = new JSONObject() - .put("and", new JSONArray() - .put( - new JSONObject().put("in", - new JSONObject().put("status", - new JSONArray() - .put("idle") - .put("wantToHire") - .put("toHire") - .put("riding") - ) - ) - ) - .put( - new JSONObject().put("in", - new JSONObject() - .put("type", new JSONArray().put("cab")) - ) - ) - .put( - new JSONObject().put("geo_distance", - new JSONObject() - .put("distance", "10km") - .put("pos", - new JSONObject() - .put("lat", "48.8566140") - .put("lon", "2.352222") - ) - ) - ) - ); - -room.renew(filters, new ResponseListener() { - @Override - public void onSuccess(NotificationResponse result) throws Exception { - // called each time a change is detected on documents matching this filter - - // check the Room/Notifications section of this documentation - // to get notification examples - } - - @Override - public void onError(JSONObject error) throws Exception { - // Handle error - } -}, new ResponseListener() { - // Handle the subscription result -}); diff --git a/doc/2/core-classes/room/set-headers/index.md b/doc/2/core-classes/room/set-headers/index.md deleted file mode 100644 index 35d5e6b8..00000000 --- a/doc/2/core-classes/room/set-headers/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -code: true -type: page -title: setHeaders -description: Room:setHeaders ---- - -# setHeaders - -> Returns itself - -This is a helper function returning itself, allowing to easily chain calls. - ---- - -## setHeaders(content, [replace]) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------------------------------------------------------- | -| `content` | JSON Object | New content | -| `replace` | boolean | true: replace the current content with the provided data, false: merge it | - -**Note:** by default, the `replace` argument is set to `false` - ---- - -## Return value - -Returns this `Room` object to allow chaining. - -## Usage - -<<< ./snippets/set-headers-1.java diff --git a/doc/2/core-classes/room/set-headers/snippets/set-headers-1.java b/doc/2/core-classes/room/set-headers/snippets/set-headers-1.java deleted file mode 100644 index ca09ea47..00000000 --- a/doc/2/core-classes/room/set-headers/snippets/set-headers-1.java +++ /dev/null @@ -1,4 +0,0 @@ - -JSONObject headers = new JSONObject(); -headers.put("someContent", "someValue"); -room.setHeaders(headers, true); diff --git a/doc/2/core-classes/room/unsubscribe/index.md b/doc/2/core-classes/room/unsubscribe/index.md deleted file mode 100644 index 15a6c543..00000000 --- a/doc/2/core-classes/room/unsubscribe/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: unsubscribe -description: Room:unsubscribe ---- - -# unsubscribe - -Cancels the current subscription. - ---- - -## Return value - -Returns this `Room` object to allow chaining. - -## Usage - -<<< ./snippets/unsubscribe-1.java diff --git a/doc/2/core-classes/room/unsubscribe/snippets/unsubscribe-1.java b/doc/2/core-classes/room/unsubscribe/snippets/unsubscribe-1.java deleted file mode 100644 index 52bce96c..00000000 --- a/doc/2/core-classes/room/unsubscribe/snippets/unsubscribe-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -room.unsubscribe(); diff --git a/doc/2/core-classes/search-result/constructor/index.md b/doc/2/core-classes/search-result/constructor/index.md deleted file mode 100644 index 23db326b..00000000 --- a/doc/2/core-classes/search-result/constructor/index.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -code: true -type: page -title: constructor -description: SearchResult:constructor -order: 1 ---- - -# Constructor - -This object can only be instantiated internally by this SDK, and is an easy-to-use representation of a paginated result from a [search](/sdk/java/2/core-classes/collection/search) or a [scroll](/sdk/java/2/core-classes/collection/scroll) request. - ---- - -## Properties - -| Property name | Type | Description | get/set | -| -------------- | ---------- | --------------------------------------------------------- | ------- | -| `aggregations` | object | The result of an aggregation produced by a search request | get | -| `collection` | Collection | The collection associated to this document | get | -| `documents` | Document[] | An array of instantiated Document objects | get | -| `fetched` | number | The number of fetched documents so far | get/set | -| `options` | object | The arguments of the search/scroll request | get | -| `filters` | object | The filters of the search request | get | -| `total` | integer | The total number of results that can be fetched | get | - ---- diff --git a/doc/2/core-classes/search-result/fetch-next/index.md b/doc/2/core-classes/search-result/fetch-next/index.md deleted file mode 100644 index 55735304..00000000 --- a/doc/2/core-classes/search-result/fetch-next/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -code: true -type: page -title: fetchNext -description: SearchResult:fetchNext ---- - -# fetchNext - -Fetches the next SearchResult, by triggering a new search/scroll request depending on the options and filters of the SearchResult. - -If the previous request was a search or a scroll action which provided a `scroll` argument, -`fetchNext` will use the `scrollId` retrieved from the current result to make a new scroll request. - -If the previous request was a search action which provided `size` argument and `sort` filtering, -`fetchNext` will use Elasticsearch's [`search_after`](https://www.elastic.co/guide/en/elasticsearch/reference/master/search-request-search-after.html) mechanism, which can efficiently search through a large volume of documents, bypassing internal hard limits\[1\], -but at the cost of reflecting the latest changes of the index, as opposed to using scroll. - -If the previous request was a search action which provided `from` and `size` arguments, -`fetchNext` will add `size` to `from` and make a new search request. - ---- - -## How to process every document of a collection - -The safest way to process all documents in a collection is to fetch them as a batch in order to avoid memory exhaustion and possibly hitting some hard limits\[1\] on the database layer. - -:::warning -Make sure your first search request includes the `size` and `scroll` parameters -::: - -:::info -\[1\] Elasticsearch limits the number of documents inside a single page to [10,000 by default](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/index-modules.html#dynamic-index-settings). -::: - -## Usage - -<<< ./snippets/fetch-next-1.java - -<<< ./snippets/fetch-next-2.java diff --git a/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-1.java b/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-1.java deleted file mode 100644 index e6b8e262..00000000 --- a/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -searchResult.fetchNext(new ResponseListener() { - @Override - public void onSuccess(SearchResult nextSearchResult) { - // called once the fetchNext action has been completed - // nextSearchResult is an instantiated SearchResult object - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -}); diff --git a/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-2.java b/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-2.java deleted file mode 100644 index ae1f884a..00000000 --- a/doc/2/core-classes/search-result/fetch-next/snippets/fetch-next-2.java +++ /dev/null @@ -1,37 +0,0 @@ - -import io.kuzzle.sdk.core.Kuzzle; -import io.kuzzle.sdk.core.Options; - -Kuzzle kuzzle = new Kuzzle("localhost"); - -JSONObject filter = new JSONObject(); - -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 1000); -options.setScroll("30s"); - -ResponseListener listener = new ResponseListener() { - @Override - public void onSuccess(SearchResult searchResult) { - if (searchResult == null) { - return; - } - - for (Document doc : searchResult.getDocuments()) { - // do something with the document - // this.processDocument(doc); - } - - searchResult.fetchNext(this); - } - - @Override - public void onError(JSONObject error) { - // handle errors here - } -}; - -kuzzle - .collection("collection", "index") - .search(filter, options, listener); diff --git a/doc/2/core-classes/search-result/index.md b/doc/2/core-classes/search-result/index.md deleted file mode 100644 index 9d05e1bd..00000000 --- a/doc/2/core-classes/search-result/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: SearchResult -description: SearchResult documentation ---- diff --git a/doc/2/core-classes/security/constructor/index.md b/doc/2/core-classes/security/constructor/index.md deleted file mode 100644 index 6316ea02..00000000 --- a/doc/2/core-classes/security/constructor/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -code: true -type: page -title: constructor -description: Security:constructor -order: 1 ---- - -# Constructor - -The Security component lets you handle user permissions in Kuzzle. - -Please refer to our [permissions guide](/core/1/guides/essentials/security#user-permissions) for more information. - ---- - -## Security - -| Arguments | Type | Description | -| --------- | ------ | -------------------------------------------------------------------- | -| `Kuzzle` | object | An instantiated [Kuzzle](/sdk/java/2/core-classes/kuzzle) object | - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/security/constructor/snippets/constructor-1.java b/doc/2/core-classes/security/constructor/snippets/constructor-1.java deleted file mode 100644 index 7a7e5f51..00000000 --- a/doc/2/core-classes/security/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,6 +0,0 @@ - -// using the static instance -Security security = kuzzle.security; - -// or instantiating a new Security object -Security security = new Security(kuzzle); diff --git a/doc/2/core-classes/security/create-credentials/index.md b/doc/2/core-classes/security/create-credentials/index.md deleted file mode 100644 index b1107419..00000000 --- a/doc/2/core-classes/security/create-credentials/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: createCredentials -description: Security:createCredentials ---- - -# createCredentials - -Create credentials of user with `kuid` for the specified `strategy`. - ---- - -## createCredentials(strategy, kuid, credentials, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `strategy` | string | Strategy you want to create credentials in | -| `kuid` | string | User's kuid | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the created credentials. - -## Usage - -<<< ./snippets/create-credentials-1.java - -> Callback response - -```json -{ - "username": "foo", - "kuid": "" -} -``` diff --git a/doc/2/core-classes/security/create-credentials/snippets/create-credentials-1.java b/doc/2/core-classes/security/create-credentials/snippets/create-credentials-1.java deleted file mode 100644 index b13e1560..00000000 --- a/doc/2/core-classes/security/create-credentials/snippets/create-credentials-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "bar"); - -kuzzle.security.createCredentials("local", "kuid", credentials, new ResponseListener() { - @Override - public void onSuccess(JSONObject credentials) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/create-profile/index.md b/doc/2/core-classes/security/create-profile/index.md deleted file mode 100644 index bf484502..00000000 --- a/doc/2/core-classes/security/create-profile/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: createProfile -description: Security:createProfile ---- - -# createProfile - -Create a new profile in Kuzzle. - -:::info -There is a small delay between profile creation and its availability in our search layer (usually a couple of seconds). -That means that a profile that was just created might not be immediately returned by the `searchProfiles` function. -::: - ---- - -## createProfile(id, content, [options], callback) - -| Arguments | Type | Description | -| ---------- | --------------------- | ----------------------------------------- | -| `id` | string | Unique profile identifier | -| `policies` | array of JSON objects | List of policies to apply to this profile | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `replaceIfExist` | boolean | If the same profile already exists: throw an error if sets to false. Replace the existing profile otherwise | `false` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Callback Response - -Returns a security [Profile](/sdk/java/2/core-classes/profile) object. - -## Usage - -<<< ./snippets/create-profile-1.java diff --git a/doc/2/core-classes/security/create-profile/snippets/create-profile-1.java b/doc/2/core-classes/security/create-profile/snippets/create-profile-1.java deleted file mode 100644 index 4d094d1d..00000000 --- a/doc/2/core-classes/security/create-profile/snippets/create-profile-1.java +++ /dev/null @@ -1,29 +0,0 @@ - -JSONObject[] policies = new JSONObject[]{ - new JSONObject().put("roleId", "myrole"), - new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections",new JSONArray().put("foo").put("bar")) - ) - ) -}; - -Options opts = new Options().setReplaceIfExist(true); - -kuzzle - .security - .createProfile("myprofile", policies, opts, new ResponseListener() { - @Override - public void onSuccess(Profile profile) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/create-restricted-user/index.md b/doc/2/core-classes/security/create-restricted-user/index.md deleted file mode 100644 index 39d20706..00000000 --- a/doc/2/core-classes/security/create-restricted-user/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: createRestrictedUser -description: Security:createRestrictedUser ---- - -# createRestrictedUser - -Create a new restricted user in Kuzzle. -This function allows anonymous users to create a "restricted" user with predefined rights. - -:::info -There is a small delay between user creation and its availability in our search layer (usually a couple of seconds). -That means that a user that was just created may not be immediately returned by the `searchUsers` function. -::: - ---- - -## createRestrictedUser(id, content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------ | -| `id` | string | Unique user identifier, will be used as username | -| `content` | JSON Object | A plain JSON object representing the user | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer indexation to return (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Callback response - -Resolves to a [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/create-restricted-user-1.java diff --git a/doc/2/core-classes/security/create-restricted-user/snippets/create-restricted-user-1.java b/doc/2/core-classes/security/create-restricted-user/snippets/create-restricted-user-1.java deleted file mode 100644 index 1eaaecca..00000000 --- a/doc/2/core-classes/security/create-restricted-user/snippets/create-restricted-user-1.java +++ /dev/null @@ -1,28 +0,0 @@ - -JSONObject content = new JSONObject(); - -JSONObject newUser = new JSONObject().put("content", content); - -JSONObject credentials = new JSONObject() - .put("local", new JSONObject() - // The "local" authentication strategy requires a password - .put("password", "secret password") - .put("lastLoggedIn", 1494411803)); - -newUser.put("credentials", credentials); - -Options opts = new Options().setReplaceIfExist(true); - -kuzzle - .security - .createUser("myNewUser", newUser, opts, new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/create-role/index.md b/doc/2/core-classes/security/create-role/index.md deleted file mode 100644 index 8af2b187..00000000 --- a/doc/2/core-classes/security/create-role/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: createRole -description: Security:createRole ---- - -# createRole - -Create a new role in Kuzzle. - -:::info -There is a small delay between role creation and its availability in our search layer (usually a couple of seconds). -That means that a role that was just created may not be immediately returned by the `searchRole` function. -::: - ---- - -## createRole(id, content, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique role identifier | -| `content` | JSON Object | A plain JSON object representing the role | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `replaceIfExist` | boolean | If the same role already exists: throw an error if sets to false. Replace the existing role otherwise | `false` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Callback Response - -Returns a [Role](/sdk/java/2/core-classes/role) object. - -## Usage - -<<< ./snippets/create-role-1.java diff --git a/doc/2/core-classes/security/create-role/snippets/create-role-1.java b/doc/2/core-classes/security/create-role/snippets/create-role-1.java deleted file mode 100644 index 57062c93..00000000 --- a/doc/2/core-classes/security/create-role/snippets/create-role-1.java +++ /dev/null @@ -1,26 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("*", new JSONObject() - .put("actions", new JSONObject() - .put("*", true) - ) - ) - ) -); - -Options opts = new Options().setReplaceIfExist(true); - -kuzzle - .security - .createRole("myrole", roleDefinition, opts, new ResponseListener() { - @Override - public void onSuccess(Role role) { - // the result is an instantiated Role object - } - - @Override - public void onError(JSONObject error) { - - } - }) diff --git a/doc/2/core-classes/security/create-user/index.md b/doc/2/core-classes/security/create-user/index.md deleted file mode 100644 index f069c560..00000000 --- a/doc/2/core-classes/security/create-user/index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -code: true -type: page -title: createUser -description: Security:createUser ---- - -# createUser - -Create a new user in Kuzzle. - -:::info -There is a small delay between user creation and its availability in our search layer (usually a couple of seconds). -That means that a user that was just created might not be returned immediately by the `searchUsers` function. -::: - ---- - -## createUser(id, user, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `id` | string | [Unique user identifier](/core/1/guides/essentials/user-authentication#kuzzle-user-identifier-kuid) | -| `user` | JSON Object | A plain JSON object representing the user (see below) | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | Callback handling the response | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - -The `user` object to provide must have the following properties: - -- `content` (JSON object): user global properties - - This object must contain a `profileIds` properties, an array of strings listing the security [profiles](/core/1/guides/essentials/security#users-profiles-and-roles) to be attached to the new user - - Any other property will be copied as additional global user information -- `credentials` (JSON object): a description of how the new user can identify themselves on Kuzzle - - Any number of credentials can be added, each one being an object with name equal to the [authentication strategy](/core/1/plugins/guides/strategies#exposing-authentication-strategies) used to authenticate the user, and with the login data as content. - - If this object is left empty, the user will be created in Kuzzle but the will not be able to login. - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/create-user-1.java diff --git a/doc/2/core-classes/security/create-user/snippets/create-user-1.java b/doc/2/core-classes/security/create-user/snippets/create-user-1.java deleted file mode 100644 index 6f51922e..00000000 --- a/doc/2/core-classes/security/create-user/snippets/create-user-1.java +++ /dev/null @@ -1,38 +0,0 @@ - -JSONObject content = new JSONObject() - // A "profileIds" field is required to bind a user to existing profiles - .put("profileIds", new JSONArray() - .put("admin") - ) - // You can also set custom fields to your user - .put("firstname", "John") - .put("lastname", "Doe"); - -JSONObject newUser = new JSONObject().put("content", content); - -JSONObject credentials = new JSONObject() - // Authentication strategy to use - .put("local", new JSONObject() - // The necessary information to provide vary, - // depending on the chosen authentication strategy - .put("password", "secret password") - .put("username", "jdoe") - ); - -newUser.put("credentials", credentials); - -Options opts = new Options(); - -kuzzle - .security - .createUser("myNewUser", newUser, opts, new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/delete-credentials/index.md b/doc/2/core-classes/security/delete-credentials/index.md deleted file mode 100644 index 93addf55..00000000 --- a/doc/2/core-classes/security/delete-credentials/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -code: true -type: page -title: deleteCredentials -description: Security:deleteCredentials ---- - -# deleteCredentials - -Delete current user's credentials for the specified `strategy`. - ---- - -## deleteCredentials(strategy, kuid, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | -------------------------------------------- | -| `strategy` | string | Strategy you want to delete credentials from | -| `kuid` | string | User's kuid | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object reflecting the query status. - -## Usage - -<<< ./snippets/delete-credentials-1.java - -> Callback response - -```json -{ - "acknowledged": true -} -``` diff --git a/doc/2/core-classes/security/delete-credentials/snippets/delete-credentials-1.java b/doc/2/core-classes/security/delete-credentials/snippets/delete-credentials-1.java deleted file mode 100644 index 1d1d0ee6..00000000 --- a/doc/2/core-classes/security/delete-credentials/snippets/delete-credentials-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.security.deleteCredentials("local", "kuid", new ResponseListener() { - @Override - public void onSuccess(JSONObject result) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/delete-profile/index.md b/doc/2/core-classes/security/delete-profile/index.md deleted file mode 100644 index 20df30e1..00000000 --- a/doc/2/core-classes/security/delete-profile/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -code: true -type: page -title: deleteProfile -description: Security:deleteProfile ---- - -# deleteProfile - -Delete the provided profile. - -:::info -There is a small delay between the time a profile is deleted and it being reflected in the search layer (usually a couple of seconds). -That means that a profile that was just deleted might still be returned by the `searchProfiles` function. -::: - ---- - -## deleteProfile(id, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique profile identifier to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Returns the ID of the security profile that has been deleted. - -## Usage - -<<< ./snippets/delete-profile-1.java - -> Callback response - -```json -"deleted profile identifier" -``` diff --git a/doc/2/core-classes/security/delete-profile/snippets/delete-profile-1.java b/doc/2/core-classes/security/delete-profile/snippets/delete-profile-1.java deleted file mode 100644 index 5c48727f..00000000 --- a/doc/2/core-classes/security/delete-profile/snippets/delete-profile-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .deleteProfile("myprofile", new ResponseListener() { - @Override - public void onSuccess(String profileName) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/delete-role/index.md b/doc/2/core-classes/security/delete-role/index.md deleted file mode 100644 index 84470bc4..00000000 --- a/doc/2/core-classes/security/delete-role/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -code: true -type: page -title: deleteRole -description: Security:deleteRole ---- - -# deleteRole - -Delete the provided role. - -:::info -There is a small delay between the time a role is deleted and it being reflected in the search layer (usually a couple of seconds). -That means that a role that was just deleted might still be returned by the `searchRoles` function. -::: - ---- - -## deleteRole(id, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique role identifier to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Returns the id of the rold that has been deleted. - -## Usage - -<<< ./snippets/delete-role-1.java - -> Callback response - -```json -"deleted role identifier" -``` diff --git a/doc/2/core-classes/security/delete-role/snippets/delete-role-1.java b/doc/2/core-classes/security/delete-role/snippets/delete-role-1.java deleted file mode 100644 index a23f999f..00000000 --- a/doc/2/core-classes/security/delete-role/snippets/delete-role-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .deleteRole("myrole", new ResponseListener() { - @Override - public void onSuccess(String roleName) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/delete-user/index.md b/doc/2/core-classes/security/delete-user/index.md deleted file mode 100644 index 8e631ac3..00000000 --- a/doc/2/core-classes/security/delete-user/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -code: true -type: page -title: deleteUser -description: Security:deleteUser ---- - -# deleteUser - -Delete the provided user. - -:::info -There is a small delay between the time a user is deleted and it being reflected in the search layer (usually a couple of seconds). -That means that a user that has just been deleted might still be returned by the `searchUsers` function. -::: - ---- - -## deleteUser(id, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique user identifier to delete | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Return the id of the user that has been deleted. - -## Usage - -<<< ./snippets/delete-user-1.java - -> Callback response - -```json -"deleted user identifier" -``` diff --git a/doc/2/core-classes/security/delete-user/snippets/delete-user-1.java b/doc/2/core-classes/security/delete-user/snippets/delete-user-1.java deleted file mode 100644 index e203abca..00000000 --- a/doc/2/core-classes/security/delete-user/snippets/delete-user-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .deleteUser("myuser", new ResponseListener() { - @Override - public void onSuccess(String userName) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/fetch-profile/index.md b/doc/2/core-classes/security/fetch-profile/index.md deleted file mode 100644 index 185f7afd..00000000 --- a/doc/2/core-classes/security/fetch-profile/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: fetchProfile -description: Security:fetchProfile ---- - -# fetchProfile - -Fetches a single stored profile using its unique ID. - ---- - -## fetchProfile(id, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `id` | string | Unique profile identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a security [Profile](/sdk/java/2/core-classes/profile) object. - -## Usage - -<<< ./snippets/fetch-profile-1.java diff --git a/doc/2/core-classes/security/fetch-profile/snippets/fetch-profile-1.java b/doc/2/core-classes/security/fetch-profile/snippets/fetch-profile-1.java deleted file mode 100644 index b9beb3a4..00000000 --- a/doc/2/core-classes/security/fetch-profile/snippets/fetch-profile-1.java +++ /dev/null @@ -1,15 +0,0 @@ - - -kuzzle - .security - .fetchProfile("myprofile", new ResponseListener() { - @Override - public void onSuccess(Profile profile) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/fetch-role/index.md b/doc/2/core-classes/security/fetch-role/index.md deleted file mode 100644 index b07e64a6..00000000 --- a/doc/2/core-classes/security/fetch-role/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: fetchRole -description: Security:fetchRole ---- - -# fetchRole - -Fetches a single stored role using its unique ID. - ---- - -## fetchRole(id, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `id` | string | Unique role identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a [Role](/sdk/java/2/core-classes/role) object. - -## Usage - -<<< ./snippets/fetch-role-1.java diff --git a/doc/2/core-classes/security/fetch-role/snippets/fetch-role-1.java b/doc/2/core-classes/security/fetch-role/snippets/fetch-role-1.java deleted file mode 100644 index 3a5d21cf..00000000 --- a/doc/2/core-classes/security/fetch-role/snippets/fetch-role-1.java +++ /dev/null @@ -1,15 +0,0 @@ - - -kuzzle - .security - .fetchRole("myrole", new ResponseListener() { - @Override - public void onSuccess(Role role) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/fetch-user/index.md b/doc/2/core-classes/security/fetch-user/index.md deleted file mode 100644 index d0a6439b..00000000 --- a/doc/2/core-classes/security/fetch-user/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: fetchUser -description: Security:fetchUser ---- - -# fetchUser - -Fetches a single stored user using its unique ID. - ---- - -## fetchUser(id, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `id` | string | Unique user identifier | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/fetch-user-1.java diff --git a/doc/2/core-classes/security/fetch-user/snippets/fetch-user-1.java b/doc/2/core-classes/security/fetch-user/snippets/fetch-user-1.java deleted file mode 100644 index a8f73d93..00000000 --- a/doc/2/core-classes/security/fetch-user/snippets/fetch-user-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .fetchUser("myuser", new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/get-all-credential-fields/index.md b/doc/2/core-classes/security/get-all-credential-fields/index.md deleted file mode 100644 index 04544e14..00000000 --- a/doc/2/core-classes/security/get-all-credential-fields/index.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -code: true -type: page -title: getAllCredentialFields -description: Security:getAllCredentialFields ---- - -# getAllCredentialFields - -Fetches a list of accepted fields per authentication strategy. - ---- - -## getAllCredentialFields([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the credential fields. - -## Usage - -<<< ./snippets/get-all-credential-fields-1.java - -> Callback response: - -```json -{ - "local": ["kuid", "username"] -} -``` diff --git a/doc/2/core-classes/security/get-all-credential-fields/snippets/get-all-credential-fields-1.java b/doc/2/core-classes/security/get-all-credential-fields/snippets/get-all-credential-fields-1.java deleted file mode 100644 index 14b8a8e6..00000000 --- a/doc/2/core-classes/security/get-all-credential-fields/snippets/get-all-credential-fields-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.security.getAllCredentialFields(new ResponseListener() { - @Override - public void onSuccess(JSONObject strategies) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/get-credentials-fields/index.md b/doc/2/core-classes/security/get-credentials-fields/index.md deleted file mode 100644 index 0305efa5..00000000 --- a/doc/2/core-classes/security/get-credentials-fields/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: getCredentialsFields -description: Security:getCredentialsFields ---- - -# getCredentialFields - -Get credential information for the specified `strategy`. - ---- - -## getCredentialFields(strategy, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `strategy` | string | Strategy you want to get credentials from | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -The result is a an array of credential fields. - -## Usage - -<<< ./snippets/get-credentials-fields-1.java - -> Callback response: - -```json -["kuid", "username"] -``` diff --git a/doc/2/core-classes/security/get-credentials-fields/snippets/get-credentials-fields-1.java b/doc/2/core-classes/security/get-credentials-fields/snippets/get-credentials-fields-1.java deleted file mode 100644 index 97021d8b..00000000 --- a/doc/2/core-classes/security/get-credentials-fields/snippets/get-credentials-fields-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.security.getCredentialFields("local", new ResponseListener() { - @Override - public void onSuccess(String[] fields) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/get-credentials/index.md b/doc/2/core-classes/security/get-credentials/index.md deleted file mode 100644 index b4527150..00000000 --- a/doc/2/core-classes/security/get-credentials/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: getCredentials -description: Security:getCredentials ---- - -# getCredentials - -Get credential information of user with `kuid` for the specified `strategy`. - ---- - -## getCredentials(strategy, kuid, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `strategy` | string | Strategy you want to get credentials from | -| `kuid` | string | User's kuid | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -The result is a an object with the credentials. - -## Usage - -<<< ./snippets/get-credentials-1.java - -> Callback response - -```json -{ - "username": "foo", - "kuid": "" -} -``` diff --git a/doc/2/core-classes/security/get-credentials/snippets/get-credentials-1.java b/doc/2/core-classes/security/get-credentials/snippets/get-credentials-1.java deleted file mode 100644 index d7760617..00000000 --- a/doc/2/core-classes/security/get-credentials/snippets/get-credentials-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.security.getCredentials("local", "kuid", new ResponseListener() { - @Override - public void onSuccess(JSONObject credentials) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/get-user-rights/index.md b/doc/2/core-classes/security/get-user-rights/index.md deleted file mode 100644 index 1bd08450..00000000 --- a/doc/2/core-classes/security/get-user-rights/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: getUserRights -description: Security:getUserRights ---- - -# getUserRights - -> Callback response example - -```json -[ - { - "controller": "my-controller", - "action": "my-action", - "index": "*", - "collection": "*", - "value": "allowed" - }, - { - "controller": "another-controller", - "action": "*", - "index": "my-index", - "collection": "*", - "value": "conditional" - } -] -``` - -Given a Kuzzle user id (`kuid`), retrieves the list of permissions granted to that user. - ---- - -### getUserRights(id, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------- | -| `kuid` | String | [Kuzzle User Unique Identifier](/core/1/guides/essentials/user-authentication#kuzzle-user-identifier-kuid) | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -### Callback Response - -Returns an array of objects. - -## Usage - -<<< ./snippets/get-user-rights-1.java diff --git a/doc/2/core-classes/security/get-user-rights/snippets/get-user-rights-1.java b/doc/2/core-classes/security/get-user-rights/snippets/get-user-rights-1.java deleted file mode 100644 index 5c2ffadd..00000000 --- a/doc/2/core-classes/security/get-user-rights/snippets/get-user-rights-1.java +++ /dev/null @@ -1,15 +0,0 @@ - - -kuzzle - .security - .getUserRights("kuid", new ResponseListener() { - @Override - public void onSuccess(JSONObject[] rights) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/has-credentials/index.md b/doc/2/core-classes/security/has-credentials/index.md deleted file mode 100644 index 05c4d411..00000000 --- a/doc/2/core-classes/security/has-credentials/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -code: true -type: page -title: hasCredentials -description: Security:hasCredentials ---- - -# hasCredentials - -Checks if a user has credentials for the provided strategy. - ---- - -## hasCredentials(strategy, kuid, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------- | -| `strategy` | string | Strategy to check for credentials | -| `kuid` | JSON object | User's kuid | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a boolean value. - -## Usage - -<<< ./snippets/has-credentials-1.java diff --git a/doc/2/core-classes/security/has-credentials/snippets/has-credentials-1.java b/doc/2/core-classes/security/has-credentials/snippets/has-credentials-1.java deleted file mode 100644 index e12845e2..00000000 --- a/doc/2/core-classes/security/has-credentials/snippets/has-credentials-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -kuzzle.security.hasCredentials("local", "kuid", new ResponseListener() { - @Override - public void onSuccess(Boolean result) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/index.md b/doc/2/core-classes/security/index.md deleted file mode 100644 index 5cdb0b71..00000000 --- a/doc/2/core-classes/security/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: Security -description: Security documentation ---- diff --git a/doc/2/core-classes/security/is-action-allowed/index.md b/doc/2/core-classes/security/is-action-allowed/index.md deleted file mode 100644 index 219cec03..00000000 --- a/doc/2/core-classes/security/is-action-allowed/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -code: true -type: page -title: isActionAllowed -description: Security:isActionAllowed ---- - -# isActionAllowed - -Specifies if an action is allowed, denied or conditional based on the rights provided as the first argument: - -- `allowed` is returned when an action is authorized without condition -- `conditional` is returned when the authorization depends on a closure -- `denied` is returned when the action is forbidden - -An action is defined as a pair of action and controller (mandatory), plus an index and a collection(optional). - -:::info -You can get the rights from Kuzzle by using [Security.getUserRights](/sdk/java/2/core-classes/security/get-user-rights) and [Kuzzle.getMyRights](/sdk/java/2/core-classes/kuzzle/get-my-rights). -::: - ---- - -## isActionAllowed(rights, controller, action, index, collection) - -| Arguments | Type | Description | -| ------------ | ---------- | -------------- | -| `rights` | JSON array | Rights list | -| `controller` | String | The controller | -| `action` | String | The action | -| `index` | String | The index | -| `collection` | String | The collection | - ---- - -## Return Value - -Returns either `allowed`, `denied` or `conditional`. - -## Usage - -<<< ./snippets/is-action-allowed-1.java diff --git a/doc/2/core-classes/security/is-action-allowed/snippets/is-action-allowed-1.java b/doc/2/core-classes/security/is-action-allowed/snippets/is-action-allowed-1.java deleted file mode 100644 index 1eaf8b25..00000000 --- a/doc/2/core-classes/security/is-action-allowed/snippets/is-action-allowed-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle.security.getMyRights(new ResponseListener() { - @Override - public void onSuccess(JSONObject[] rights) { - // Policies is an enum with the following properties: - // allowed, denied, conditional - Policies authorization = kuzzle.security.isActionAllowed(rights, "read", "get", "index1", "collection1"); - } - - @Override - public void onError(JSONObject error) { - // ... - } -}); diff --git a/doc/2/core-classes/security/profile/index.md b/doc/2/core-classes/security/profile/index.md deleted file mode 100644 index 92656560..00000000 --- a/doc/2/core-classes/security/profile/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: profile -description: Security:profile ---- - -# profile - -Instantiate a new security [Profile](/sdk/java/2/core-classes/profile) object. - ---- - -## profile(id, content) - -| Arguments | Type | Description | -| --------- | ----------- | ------------------------- | -| `id` | string | Unique profile identifier | -| `content` | JSON Object | Profile content | - ---- - -## Return Value - -Returns the new security [Profile](/sdk/java/2/core-classes/profile) object. - -## Usage - -<<< ./snippets/profile-1.java diff --git a/doc/2/core-classes/security/profile/snippets/profile-1.java b/doc/2/core-classes/security/profile/snippets/profile-1.java deleted file mode 100644 index 496345f4..00000000 --- a/doc/2/core-classes/security/profile/snippets/profile-1.java +++ /dev/null @@ -1,20 +0,0 @@ - -JSONObject policy1 = new JSONObject() - .put("roleId", "myrole"); - -JSONObject policy2 = new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections",new JSONArray().put("foo").put("bar")) - ) - ); -JSONObject profileDefinition = new JSONObject() - .put("policies", new JSONArray() - .put(policy1) - .put(policy2) - ); - -Profile profile = kuzzle.security.profile("myprofile", profileDefinition); diff --git a/doc/2/core-classes/security/replace-user/index.md b/doc/2/core-classes/security/replace-user/index.md deleted file mode 100644 index 66afc110..00000000 --- a/doc/2/core-classes/security/replace-user/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: replaceUser -description: Security:replaceUser ---- - -# replaceUser - -Replaces an existing user. - ---- - -## replaceUser(id, content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------------------------------------------------------------------ | -| `id` | string | Unique user identifier | -| `content` | JSON Object | A plain JSON object representing the user, should contain the mandatory `profileIds` field | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Returns a [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/replace-user-1.java diff --git a/doc/2/core-classes/security/replace-user/snippets/replace-user-1.java b/doc/2/core-classes/security/replace-user/snippets/replace-user-1.java deleted file mode 100644 index 42cd6f2b..00000000 --- a/doc/2/core-classes/security/replace-user/snippets/replace-user-1.java +++ /dev/null @@ -1,21 +0,0 @@ - -JSONObject newContent = new JSONObject() - .put("profileIds", new JSONArray() - .put("admin") - ) - .put("firstname", "My Name Is") - .put("lastname", "Jonas"); - -kuzzle - .security - .replaceUser("User ID", newContent, new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/role/index.md b/doc/2/core-classes/security/role/index.md deleted file mode 100644 index aa830dbb..00000000 --- a/doc/2/core-classes/security/role/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: role -description: Security:role ---- - -# role - -Instantiate a new [Role](/sdk/java/2/core-classes/role) object. - ---- - -## role(id, content) - -| Arguments | Type | Description | -| --------- | ----------- | ---------------------- | -| `id` | string | Unique role identifier | -| `content` | JSON Object | Role content | - ---- - -## Return Value - -Returns the new [Role](/sdk/java/2/core-classes/role) object. - -## Usage - -<<< ./snippets/role-1.java diff --git a/doc/2/core-classes/security/role/snippets/role-1.java b/doc/2/core-classes/security/role/snippets/role-1.java deleted file mode 100644 index 8cb273b3..00000000 --- a/doc/2/core-classes/security/role/snippets/role-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("*", new JSONObject() - .put("actions", new JSONObject() - .put("*", true) - ) - ) - ) -); - -Role role = kuzzle.security.role("myrole", roleDefinition); diff --git a/doc/2/core-classes/security/scroll-profiles/index.md b/doc/2/core-classes/security/scroll-profiles/index.md deleted file mode 100644 index 15d44150..00000000 --- a/doc/2/core-classes/security/scroll-profiles/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: scrollProfiles -description: Security:scrollProfiles ---- - -# scrollProfiles - -Scrolls on stored profiles using the provided scroll ID. - ---- - -## scrollProfiles(scrollId, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------- | -| `scrollId` | string | Scroll identifier retrieved from a search query | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the list of fetched security profiles according to the scroll parameters (offset, limit etc.). - -## Usage - -<<< ./snippets/scroll-profiles-1.java diff --git a/doc/2/core-classes/security/scroll-profiles/snippets/scroll-profiles-1.java b/doc/2/core-classes/security/scroll-profiles/snippets/scroll-profiles-1.java deleted file mode 100644 index 8987b747..00000000 --- a/doc/2/core-classes/security/scroll-profiles/snippets/scroll-profiles-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .scrollProfiles(scrollId, options, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList response) { - // called once the scroll action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/security/scroll-users/index.md b/doc/2/core-classes/security/scroll-users/index.md deleted file mode 100644 index 9d564b97..00000000 --- a/doc/2/core-classes/security/scroll-users/index.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -code: true -type: page -title: scrollUsers -description: Security:scrollUsers ---- - -# scrollUsers - -Scrolls on stored users using the provided scroll ID. - ---- - -## scrollUsers(scrollId, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------- | -| `scrollId` | string | Scroll identifier retrieved from a search query | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns the list of fetched users according to the scroll parameters (offset, limit etc.). - -## Usage - -<<< ./snippets/scroll-users-1.java diff --git a/doc/2/core-classes/security/scroll-users/snippets/scroll-users-1.java b/doc/2/core-classes/security/scroll-users/snippets/scroll-users-1.java deleted file mode 100644 index 5cc6eef9..00000000 --- a/doc/2/core-classes/security/scroll-users/snippets/scroll-users-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -kuzzle - .security - .scrollUsers(scrollId, options, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList response) { - // called once the scroll action has been completed - } - - @Override - public void onError(JSONObject error) { - // Handle error - } - }); diff --git a/doc/2/core-classes/security/search-profiles/index.md b/doc/2/core-classes/security/search-profiles/index.md deleted file mode 100644 index ca327176..00000000 --- a/doc/2/core-classes/security/search-profiles/index.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -code: true -type: page -title: searchProfiles -description: Security:searchProfiles ---- - -# searchProfiles - -Search for security profiles, optionally returning only those linked to the provided list of security roles. - ---- - -## searchProfiles(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `filters` | JSON Object | Search query | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `from` | number | Starting offset | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Start a scroll session, with a time to live equals to this parameter's value following the [Elastisearch time format](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/common-options.html#time-units) | `undefined` | -| `size` | integer | Number of hits to return per page | `10` | - ---- - -## Filters - -| Filter | Type | Description | Default | -| ------- | ----- | ------------------------------------------------ | ------- | -| `roles` | array | Contains an array `roles` with a list of role id | `[]` | - ---- - -## Callback Response - -Returns a JSON Object - -## Usage - -<<< ./snippets/search-profiles-1.java - -> Callback response: - -```json -{ - "total": 124, - "profiles": [ - // array of Profile objects - ], - // only if a scroll parameter has been provided - "scrollId": "" -} -``` diff --git a/doc/2/core-classes/security/search-profiles/snippets/search-profiles-1.java b/doc/2/core-classes/security/search-profiles/snippets/search-profiles-1.java deleted file mode 100644 index 8884481a..00000000 --- a/doc/2/core-classes/security/search-profiles/snippets/search-profiles-1.java +++ /dev/null @@ -1,35 +0,0 @@ - -// optional: search only for profiles referring the listed roles -JSONObject filters = new JSONObject() - .put("roles", new JSONArray().put("myrole").put("admin")); - -// optional: result pagination configuration -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 42); -options.setScroll("1m"); - - -kuzzle - .security - .searchProfiles(filters, options, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList profiles) { - // Contains a profiles list - for(Profile profile : profiles.getDocuments()) { - - } - - // Total number of profiles, regardless of pagination - long total = profiles.getTotal(); - - // Available only if a "scroll" option has been provided - String scrollId = profiles.getScroll() - } - - @Override - public void onError(JSONObject error) { - - } - }); - diff --git a/doc/2/core-classes/security/search-roles/index.md b/doc/2/core-classes/security/search-roles/index.md deleted file mode 100644 index 00ab2cc7..00000000 --- a/doc/2/core-classes/security/search-roles/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -code: true -type: page -title: searchRoles -description: Security:searchRoles ---- - -# searchRoles - -Search for security roles, optionally returning only the roles giving access to the provided controller names. - ---- - -## searchRoles(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| `filters` | JSON Object | Optionally contains a "controllers" array listing the controller names used to filter searched roles | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Filters - -| Filter | Type | Description | Default | -| ------------- | ----- | --------------------------------------------------------- | ------- | -| `controllers` | array | retrieve only roles allowing access to the provided names | `[]` | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ---------------------------------- | ------- | -| `from` | number | Starting offset | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `size` | number |  Number of hits to return per page | `10` | - ---- - -## Callback Response - -Return a JSON Object - -## Usage - -<<< ./snippets/search-roles-1.java - -> Callback response: - -```json -{ - "total": 124, - "roles": [ - // array of Role - ] -} -``` diff --git a/doc/2/core-classes/security/search-roles/snippets/search-roles-1.java b/doc/2/core-classes/security/search-roles/snippets/search-roles-1.java deleted file mode 100644 index 5daed381..00000000 --- a/doc/2/core-classes/security/search-roles/snippets/search-roles-1.java +++ /dev/null @@ -1,29 +0,0 @@ - -// optional: retrieve only roles allowing access to the -// provided controller names -JSONObject filter = new JSONObject() - .put("controllers", new JSONArray() - .put("document") - .put("security") - ); - -// optional: result pagination configuration -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 42); -options.setScroll("1m"); - -kuzzle - .security - .searchRoles(filter, options, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList roles) { - // roles.getDocuments() returns a roles list - for(Role role : roles.getDocuments()) { - - } - - // roles.getTotal() returns the number of matched roles, regardless of pagination - roles.getTotal(); - } - }); diff --git a/doc/2/core-classes/security/search-users/index.md b/doc/2/core-classes/security/search-users/index.md deleted file mode 100644 index 146d9e77..00000000 --- a/doc/2/core-classes/security/search-users/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -code: true -type: page -title: searchUsers -description: Security:searchUsers ---- - -# searchUsers - -Return users matching the given filter. - ---- - -## searchUsers(filters, [options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `filters` | JSON Object | Filter in [Elasticsearch's Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/query-filter-context.html) format | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `from` | number | Starting offset | `0` | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `scroll` | string | Start a scroll session, with a time to live equals to this parameter's value following the [Elastisearch time format](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/common-options.html#time-units) | `undefined` | -| `size` | number |  Number of hits to return per result page | `10` | - -:::info -To get more information about scroll sessions, please refer to the [API reference documentation](/core/1/api/controllers/document/search). -::: - ---- - -## Callback Response - -Return a JSON Object - -## Usage - -<<< ./snippets/search-users-1.java - -> Callback response: - -```json -{ - "total": 124, - "users": [ - // array of User objects - ], - // only if a scroll parameter has been provided - "scrollId": "" -} -``` diff --git a/doc/2/core-classes/security/search-users/snippets/search-users-1.java b/doc/2/core-classes/security/search-users/snippets/search-users-1.java deleted file mode 100644 index 54c4c779..00000000 --- a/doc/2/core-classes/security/search-users/snippets/search-users-1.java +++ /dev/null @@ -1,49 +0,0 @@ - -JSONObject filter = new JSONObject() - .put("bool", new JSONObject() - .put("must", new JSONArray() - .put(new JSONObject() - .put("terms", new JSONObject() - .put("profileIds", new JSONArray().put("anonymous").put("default")) - ) - ) - .put(new JSONObject() - .put("geo_distance", new JSONObject() - .put("distance", "10km") - .put("pos", new JSONObject() - .put("lat", 48.8566140) - .put("lon", 2.352222) - ) - ) - ) - ) - ); - -// optional: result pagination configuration -Options options = new Options(); -options.setFrom((long) 0); -options.setSize((long) 42); -options.setScroll("1m"); - -kuzzle - .security - .searchUsers(filters, options, new ResponseListener() { - @Override - public void onSuccess(SecurityDocumentList users) { - // users.getDocuments() returns an users list - for(User user : users.getDocuments()) { - - } - - // Total number of profiles, regardless of pagination - long total = users.getTotal(); - - // Available only if a "scroll" option has been provided - String scrollId = users.getScroll() - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/update-credentials/index.md b/doc/2/core-classes/security/update-credentials/index.md deleted file mode 100644 index 3a973497..00000000 --- a/doc/2/core-classes/security/update-credentials/index.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -code: true -type: page -title: updateCredentials -description: Security:updateCredentials ---- - -# updateCredentials - -Update the current user's credentials for the specified ``. The credentials to send depend on the authentication plugin and the strategy. - ---- - -## updateCredentials(strategy, kuid, credentials, [options], [callback]) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `strategy` | string | Strategy you want to create credentials in | -| `kuid` | JSON object | User's kuid | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an object with the updated credentials. - -## Usage - -<<< ./snippets/update-credentials-1.java - -> Callback response - -```json -{ - "username": "foo", - "kuid": "" -} -``` diff --git a/doc/2/core-classes/security/update-credentials/snippets/update-credentials-1.java b/doc/2/core-classes/security/update-credentials/snippets/update-credentials-1.java deleted file mode 100644 index 22c9c3e4..00000000 --- a/doc/2/core-classes/security/update-credentials/snippets/update-credentials-1.java +++ /dev/null @@ -1,13 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "foo"); - -kuzzle.security.updateCredentials("local", "kuid", credentials, new ResponseListener() { - @Override - public void onSuccess(JSONObject updatedCredentials) { - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/security/update-profile/index.md b/doc/2/core-classes/security/update-profile/index.md deleted file mode 100644 index a7d46749..00000000 --- a/doc/2/core-classes/security/update-profile/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: updateProfile -description: Security:updateProfile ---- - -# updateProfile - -Performs a partial update on an existing profile. - ---- - -## updateProfile(id, content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ---------------- | ----------------------------------------- | -| `id` | string | Unique role identifier | -| `policies` | array of objects | List of policies to apply to this profile | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Return an updated [Profile](/sdk/java/2/core-classes/profile) object. - -## Usage - -<<< ./snippets/update-profile-1.java diff --git a/doc/2/core-classes/security/update-profile/snippets/update-profile-1.java b/doc/2/core-classes/security/update-profile/snippets/update-profile-1.java deleted file mode 100644 index 54da81da..00000000 --- a/doc/2/core-classes/security/update-profile/snippets/update-profile-1.java +++ /dev/null @@ -1,27 +0,0 @@ - -JSONObject[] policies = new JSONObject[]{ - new JSONObject().put("roleId", "myrole"), - new JSONObject() - .put("roleId", "default") - .put("restrictedTo", new JSONArray() - .put(new JSONObject().put("index", "index1")) - .put(new JSONObject() - .put("index", "index2") - .put("collections", new JSONArray().put("foo").put("bar")) - ) - ) -}; - -kuzzle - .security - .updateProfile("profile ID", policies, new ResponseListener() { - @Override - public void onSuccess(Profile profile) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/update-role/index.md b/doc/2/core-classes/security/update-role/index.md deleted file mode 100644 index ac73bdf9..00000000 --- a/doc/2/core-classes/security/update-role/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: updateRole -description: Security:updateRole ---- - -# updateRole - -Performs a partial update on an existing role. - ---- - -## updateRole(id, content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique role identifier | -| `content` | JSON Object | A plain JSON object representing the role | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Returns an updated [Role](/sdk/java/2/core-classes/role) object. - -## Usage - -<<< ./snippets/update-role-1.java diff --git a/doc/2/core-classes/security/update-role/snippets/update-role-1.java b/doc/2/core-classes/security/update-role/snippets/update-role-1.java deleted file mode 100644 index 17b12ebb..00000000 --- a/doc/2/core-classes/security/update-role/snippets/update-role-1.java +++ /dev/null @@ -1,24 +0,0 @@ - -JSONObject roleDefinition = new JSONObject() - .put("controllers", new JSONObject() - .put("*", new JSONObject() - .put("actions", new JSONObject() - .put("*", true) - ) - ) - ) -); - -kuzzle - .security - .updateRole("Role ID", roleDefinition, new ResponseListener() { - @Override - public void onSuccess(Role role) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/update-user/index.md b/doc/2/core-classes/security/update-user/index.md deleted file mode 100644 index 7b1b305f..00000000 --- a/doc/2/core-classes/security/update-user/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -code: true -type: page -title: updateUser -description: Security:updateUser ---- - -# updateUser - -Performs a partial update on an existing user. - ---- - -## updateUser(id, content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `id` | string | Unique user identifier | -| `content` | JSON Object | A plain JSON object representing the user | -| `options` | string | (Optional) Optional arguments | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Filter | Type | Description | Default | -| ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `queuable` | boolean | Make this request queuable or not | `true` | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing (available with Elasticsearch 5.x and above) | `undefined` | - ---- - -## Return Value - -Returns the `Security` object to allow chaining. - ---- - -## Callback Response - -Returns an updated [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/update-user-1.java diff --git a/doc/2/core-classes/security/update-user/snippets/update-user-1.java b/doc/2/core-classes/security/update-user/snippets/update-user-1.java deleted file mode 100644 index a922b597..00000000 --- a/doc/2/core-classes/security/update-user/snippets/update-user-1.java +++ /dev/null @@ -1,18 +0,0 @@ - -JSONObject newContent = new JSONObject() - .put("firstname", "My Name Is") - .put("lastname", "Jonas"); - -kuzzle - .security - .updateUser("User ID", newContent, new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } - }); diff --git a/doc/2/core-classes/security/user/index.md b/doc/2/core-classes/security/user/index.md deleted file mode 100644 index ae20fb8b..00000000 --- a/doc/2/core-classes/security/user/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: true -type: page -title: user -description: Security:user ---- - -# user - -Instantiates a new [User](/sdk/java/2/core-classes/user) object. - ---- - -## user(id, content) - -| Arguments | Type | Description | -| --------- | ----------- | ---------------------- | -| `id` | string | Unique user identifier | -| `content` | JSON Object | User content | - ---- - -## Return value - -Returns the new [User](/sdk/java/2/core-classes/user) object. - -## Usage - -<<< ./snippets/user-1.java diff --git a/doc/2/core-classes/security/user/snippets/user-1.java b/doc/2/core-classes/security/user/snippets/user-1.java deleted file mode 100644 index f6b966e4..00000000 --- a/doc/2/core-classes/security/user/snippets/user-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -JSONObject userContent = new JSONObject() - // A "profileIds" field is required to bind a user to an existing profile - .put("profileIds", new JSONArray().put('someProfile')) - // The "local" authentication strategy requires a password - .put("password", "a password") - // You can also set custom fields to your user - .put("firstname", "John") - .put("lastname", "Doe"); - -User user = kuzzle.security.user("", userContent); diff --git a/doc/2/core-classes/security/validate-credentials/index.md b/doc/2/core-classes/security/validate-credentials/index.md deleted file mode 100644 index 98b8a83e..00000000 --- a/doc/2/core-classes/security/validate-credentials/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -code: true -type: page -title: validateCredentials -description: Security:validateCredentials ---- - -# validateCredentials - -> - -Validate credentials of user with `kuid` for the specified `strategy`. Resolves to an error if the credentials are invalid. - ---- - -## validateCredentials(strategy, credentials, [options], callback) - -| Arguments | Type | Description | -| ------------- | ----------- | ------------------------------------------ | -| `strategy` | string | Strategy you want to create credentials in | -| `kuid` | JSON object | User's kuid | -| `credentials` | JSON object | The credentials | -| `options` | JSON object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a boolean value if the credentials are valid, otherwise returns an error. - -## Usage - -<<< ./snippets/validate-credentials-1.java - -> Callback response - -```json -true -``` diff --git a/doc/2/core-classes/security/validate-credentials/snippets/validate-credentials-1.java b/doc/2/core-classes/security/validate-credentials/snippets/validate-credentials-1.java deleted file mode 100644 index 10d0c439..00000000 --- a/doc/2/core-classes/security/validate-credentials/snippets/validate-credentials-1.java +++ /dev/null @@ -1,14 +0,0 @@ - -JSONObject credentials = new JSONObject().put("username", "bar"); - -kuzzle.security.validateCredentials("local", "kuid", credentials, new ResponseListener() { - @Override - public void onSuccess(Boolean result) { - - } - - @Override - public void onError(JSONObject error) { - // Handle error - } -} diff --git a/doc/2/core-classes/user/add-profile/index.md b/doc/2/core-classes/user/add-profile/index.md deleted file mode 100644 index dc46fdce..00000000 --- a/doc/2/core-classes/user/add-profile/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -code: true -type: page -title: addProfile -description: User:addProfile ---- - -# addProfile - -Replaces the security profile associated with the user. - -:::info -Updating a user will have no impact until the [create](/sdk/java/2/core-classes/user/create) or [replace](/sdk/java/2/core-classes/user/replace) method is called -::: - ---- - -## addProfile(profileId) - -| Arguments | Type | Description | -| ----------- | ------ | ----------- | -| `profileId` | string | Profile ID | - ---- - -## addProfile(profile) - -| Arguments | Type | Description | -| --------- | ------- | --------------------------------------------------------------------- | -| `profile` | Profile | An instantiated [Profile](/sdk/java/2/core-classes/profile) object | - ---- - -## Return Value - -Returns the `User` object. - -## Usage - -<<< ./snippets/add-profile-1.java diff --git a/doc/2/core-classes/user/add-profile/snippets/add-profile-1.java b/doc/2/core-classes/user/add-profile/snippets/add-profile-1.java deleted file mode 100644 index c762ec18..00000000 --- a/doc/2/core-classes/user/add-profile/snippets/add-profile-1.java +++ /dev/null @@ -1,15 +0,0 @@ - - -// Updating the profile with a Profile object -kuzzle - .security - .fetchProfile("myprofile", opts, new ResponseListener() { - @Override - public void onSuccess(Profile profile) { - // Can add the profile directly with a Profile object - user.addProfile(profile); - } - }); - -// Updating the profile with a profile ID -user.addProfile("myprofile"); diff --git a/doc/2/core-classes/user/constructor/index.md b/doc/2/core-classes/user/constructor/index.md deleted file mode 100644 index 615b75d7..00000000 --- a/doc/2/core-classes/user/constructor/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -code: true -type: page -title: constructor -description: User:constructor -order: 1 ---- - -# Constructors - -## Instantiates a new User object, which is a representation of a Kuzzle user and is linked to a security [Profile](/sdk/java/2/core-classes/profile). - -## User(Security, id, content, [meta]) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------- | -| `Security` | Security | An instantiated Security object | -| `id` | string | Unique user identifier | -| `content` | JSON Object | User content | -| `meta` | JSON Object | User metadata | - -**Note:** this constructor won't make any call to Kuzzle. - ---- - -## Properties - -| Property name | Type | Description | get/set | -| ------------- | ----------- | ------------------------- | ------- | -| `content` | JSON object | Raw user content | get | -| `id` | string | Unique profile identifier | get | -| `meta` | JSON object | User metadata | get | - ---- - -## Return Value - -Returns the `User` object. - -## Usage - -<<< ./snippets/constructor-1.java diff --git a/doc/2/core-classes/user/constructor/snippets/constructor-1.java b/doc/2/core-classes/user/constructor/snippets/constructor-1.java deleted file mode 100644 index e8b1866e..00000000 --- a/doc/2/core-classes/user/constructor/snippets/constructor-1.java +++ /dev/null @@ -1,15 +0,0 @@ - -JSONObject userContent = new JSONObject() - // A "profile" field is required to bind a user to an existing profile - .put("profileIds", new JSONArray().put("admin")) - // The "local" authentication strategy requires a password - .put("password", "secret password") - // You can also set custom fields to your user - .put("firstname", "John") - .put("lastname", "Doe"); - -// Using the KuzzleSecurity factory: -User user = kuzzle.security.user("user ID", userContent); - -// Or directly with the constructor: -User user = new User(kuzzle.security, "user ID", userContent); diff --git a/doc/2/core-classes/user/create/index.md b/doc/2/core-classes/user/create/index.md deleted file mode 100644 index 5f3d3aec..00000000 --- a/doc/2/core-classes/user/create/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: create -description: User:create ---- - -# create - -Create the user in Kuzzle. Credentials can be created during the process by using [setCredentials](/sdk/java/2/core-classes/user/set-credentials) beforehand. - ---- - -## create([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `User` object to allow chaining. - ---- - -## Callback Response - -Returns a `User` object. - -## Usage - -<<< ./snippets/create-1.java diff --git a/doc/2/core-classes/user/create/snippets/create-1.java b/doc/2/core-classes/user/create/snippets/create-1.java deleted file mode 100644 index d6f7ae27..00000000 --- a/doc/2/core-classes/user/create/snippets/create-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -user.create(new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/delete/index.md b/doc/2/core-classes/user/delete/index.md deleted file mode 100644 index e6b7b030..00000000 --- a/doc/2/core-classes/user/delete/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: delete -description: User:delete ---- - -# delete - -Deletes the user in Kuzzle. - ---- - -## delete([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns a `String` containing the id of the deleted user. - -## Usage - -<<< ./snippets/delete-1.java diff --git a/doc/2/core-classes/user/delete/snippets/delete-1.java b/doc/2/core-classes/user/delete/snippets/delete-1.java deleted file mode 100644 index 7386edb3..00000000 --- a/doc/2/core-classes/user/delete/snippets/delete-1.java +++ /dev/null @@ -1,11 +0,0 @@ - -user.delete(new ResponseListener() { - @Override - public void onSuccess(String deletedId) { - - } - - @Override public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/get-profileids/index.md b/doc/2/core-classes/user/get-profileids/index.md deleted file mode 100644 index 385f2147..00000000 --- a/doc/2/core-classes/user/get-profileids/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -code: true -type: page -title: getProfileids -description: User:getProfileids ---- - -# getProfileIds - -Returns the list of profile identifiers associated with this user. - ---- - -## Return Value - -Returns an array of strings, each a profile identifier associated with this user. - -## Usage - -<<< ./snippets/get-profileids-1.java diff --git a/doc/2/core-classes/user/get-profileids/snippets/get-profileids-1.java b/doc/2/core-classes/user/get-profileids/snippets/get-profileids-1.java deleted file mode 100644 index eed4412b..00000000 --- a/doc/2/core-classes/user/get-profileids/snippets/get-profileids-1.java +++ /dev/null @@ -1,2 +0,0 @@ - -String[] profileIds = user.getProfileIds(); diff --git a/doc/2/core-classes/user/get-profiles/index.md b/doc/2/core-classes/user/get-profiles/index.md deleted file mode 100644 index 43999904..00000000 --- a/doc/2/core-classes/user/get-profiles/index.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -code: true -type: page -title: getProfiles -description: User:getProfiles ---- - -# getProfiles - -Gets the security [Profile](/sdk/java/2/core-classes/profile) instances linked to the user from Kuzzle's API. - ---- - -## getProfiles([options], callback) - -| Arguments | Type | Description | -| ---------- | ----------- | ------------------------------ | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Callback Response - -Returns an array of security [Profile](/sdk/java/2/core-classes/profile) objects. - -## Usage - -<<< ./snippets/get-profiles-1.java diff --git a/doc/2/core-classes/user/get-profiles/snippets/get-profiles-1.java b/doc/2/core-classes/user/get-profiles/snippets/get-profiles-1.java deleted file mode 100644 index 641a2358..00000000 --- a/doc/2/core-classes/user/get-profiles/snippets/get-profiles-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -user.getProfiles(new ResponseListener() { - @Override - public void onSuccess(Profile[] profiles) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/index.md b/doc/2/core-classes/user/index.md deleted file mode 100644 index 5424b319..00000000 --- a/doc/2/core-classes/user/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -code: true -type: branch -title: User -description: User documentation ---- diff --git a/doc/2/core-classes/user/replace/index.md b/doc/2/core-classes/user/replace/index.md deleted file mode 100644 index 1031ed81..00000000 --- a/doc/2/core-classes/user/replace/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: replace -description: User:replace ---- - -# replace - -Replaces the user in Kuzzle. - ---- - -## replace([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `User` object to allow chaining. - ---- - -## Callback Response - -Returns a `User` object. - -## Usage - -<<< ./snippets/replace-1.java diff --git a/doc/2/core-classes/user/replace/snippets/replace-1.java b/doc/2/core-classes/user/replace/snippets/replace-1.java deleted file mode 100644 index 832d100e..00000000 --- a/doc/2/core-classes/user/replace/snippets/replace-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -user.replace(new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/save-restricted/index.md b/doc/2/core-classes/user/save-restricted/index.md deleted file mode 100644 index bd877624..00000000 --- a/doc/2/core-classes/user/save-restricted/index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -code: true -type: page -title: saveRestricted -description: User:saveRestricted ---- - -# saveRestricted - -## Saves this user as restricted in Kuzzle. - -## saveRestricted([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `User` object to allow chaining. - ---- - -## Callback Response - -Returns a `User` object. - -## Usage - -<<< ./snippets/save-restricted-1.java diff --git a/doc/2/core-classes/user/save-restricted/snippets/save-restricted-1.java b/doc/2/core-classes/user/save-restricted/snippets/save-restricted-1.java deleted file mode 100644 index d99efb0a..00000000 --- a/doc/2/core-classes/user/save-restricted/snippets/save-restricted-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -user.saveRestricted(new ResponseListener() { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/save/index.md b/doc/2/core-classes/user/save/index.md deleted file mode 100644 index 37fb47b4..00000000 --- a/doc/2/core-classes/user/save/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -code: true -type: page -title: save -description: User:save ---- - -# save - -Creates or replaces this user in Kuzzle. - ---- - -## save([options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | ----------------------------------------- | -| `options` | JSON Object | Optional parameters | -| `callback` | function | (Optional) Callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `User` object to allow chaining. - ---- - -## Callback Response - -Returns a `User` object. - -## Usage - -<<< ./snippets/save-1.java diff --git a/doc/2/core-classes/user/save/snippets/save-1.java b/doc/2/core-classes/user/save/snippets/save-1.java deleted file mode 100644 index 608499ec..00000000 --- a/doc/2/core-classes/user/save/snippets/save-1.java +++ /dev/null @@ -1,12 +0,0 @@ - -user.save(new ResponseListener { - @Override - public void onSuccess(User user) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/core-classes/user/set-content/index.md b/doc/2/core-classes/user/set-content/index.md deleted file mode 100644 index eb6c20e8..00000000 --- a/doc/2/core-classes/user/set-content/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -code: true -type: page -title: setContent -description: User:setContent ---- - -# setContent - -Replaces the content of User. - -:::info -Updating a user will have no impact until the [create](/sdk/java/2/core-classes/user/create) or [replace](/sdk/java/2/core-classes/user/replace) method is called. -::: - ---- - -## setContent(data) - -| Arguments | Type | Description | -| --------- | ----------- | ------------ | -| `data` | JSON Object | User content | - ---- - -## Return Value - -Returns the `User` object. - -## Usage - -<<< ./snippets/set-content-1.java diff --git a/doc/2/core-classes/user/set-content/snippets/set-content-1.java b/doc/2/core-classes/user/set-content/snippets/set-content-1.java deleted file mode 100644 index fc8875ad..00000000 --- a/doc/2/core-classes/user/set-content/snippets/set-content-1.java +++ /dev/null @@ -1,7 +0,0 @@ - -JSONObject newContent = new JSONObject() - .put("profileIds", new JSONArray() - .put("profileId") - ); - -user.setContent(newContent); diff --git a/doc/2/core-classes/user/set-credentials/index.md b/doc/2/core-classes/user/set-credentials/index.md deleted file mode 100644 index ab6591ca..00000000 --- a/doc/2/core-classes/user/set-credentials/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -code: true -type: page -title: setCredentials -description: User:setCredentials ---- - -# setCredentials - -Sets the user's credentials. - -:::info -Updating user credentials will have no impact until the [create](/sdk/java/2/core-classes/user/create) method is called. -The credentials to send depend on the authentication plugin and the strategy you want to create credentials for. -::: - ---- - -## setCredentials(credentials) - -| Arguments | Type | Description | -| ------------- | ------ | --------------------------------------------------------------------------------- | -| `credentials` | object | An object containing an attribute for each strategy you want to link the user to. | - ---- - -## Return Value - -Returns the `User` object. - -## Usage - -<<< ./snippets/set-credentials-1.java diff --git a/doc/2/core-classes/user/set-credentials/snippets/set-credentials-1.java b/doc/2/core-classes/user/set-credentials/snippets/set-credentials-1.java deleted file mode 100644 index 287a00c0..00000000 --- a/doc/2/core-classes/user/set-credentials/snippets/set-credentials-1.java +++ /dev/null @@ -1,6 +0,0 @@ - -JSONObject - strategyCredentials = new JSONObject().put("some", "credentials"), - credentials = new JSONObject().put("", strategyCredentials); - -user.setCredentials(credentials); diff --git a/doc/2/core-classes/user/set-profiles/index.md b/doc/2/core-classes/user/set-profiles/index.md deleted file mode 100644 index 92c4855f..00000000 --- a/doc/2/core-classes/user/set-profiles/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -code: true -type: page -title: setProfiles -description: User:setProfiles ---- - -# setProfiles - -Replaces the security profiles linked to the user. - -:::info -Updating a user will have no impact until the [create](/sdk/java/2/core-classes/user/create) or [replace](/sdk/java/2/core-classes/user/replace) method is called. -::: - ---- - -## setProfiles(profileIds) - -| Arguments | Type | Description | -| ------------ | ---------------- | ------------------- | -| `profileIds` | array of strings | List of profile IDs | - ---- - -## setProfiles(profiles) - -| Arguments | Type | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------------------- | -| `profiles` | array of Profile objects | An array of instantiated [Profile](/sdk/java/2/core-classes/profile) objects | - ---- - -## Return Value - -Returns the `User` object. - -## Usage - -<<< ./snippets/set-profiles-1.java diff --git a/doc/2/core-classes/user/set-profiles/snippets/set-profiles-1.java b/doc/2/core-classes/user/set-profiles/snippets/set-profiles-1.java deleted file mode 100644 index ac5ef05e..00000000 --- a/doc/2/core-classes/user/set-profiles/snippets/set-profiles-1.java +++ /dev/null @@ -1,22 +0,0 @@ - - -// Updating the profile with a Profile object -kuzzle - .security - .fetchProfile("myprofile", opts, new ResponseListener() { - @Override - public void onSuccess(Profile profile) { - - ArrayList profileIds = new ArrayList(); - profileIds.add(profile); - - user.setProfiles(profileIds); - - } - }); - -// Updating the profile with a profile ID -ArrayList profileIds = new ArrayList(); -profileIds.add("myprofile"); - -user.setProfiles(profileIds); diff --git a/doc/2/core-classes/user/update/index.md b/doc/2/core-classes/user/update/index.md deleted file mode 100644 index ae46a54e..00000000 --- a/doc/2/core-classes/user/update/index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -code: true -type: page -title: update -description: User:update ---- - -# update - -Performs a partial content update on this object. - ---- - -## update(content, [options], [callback]) - -| Arguments | Type | Description | -| ---------- | ----------- | --------------------------------------- | -| `content` | JSON Object | User content | -| `options` | JSON Object | Optional parameters | -| `callback` | function | Optional callback handling the response | - ---- - -## Options - -| Option | Type | Description | Default | -| ---------- | ------- | --------------------------------- | ------- | -| `queuable` | boolean | Make this request queuable or not | `true` | - ---- - -## Return Value - -Returns the `User` object to allow chaining. - ---- - -## Callback Response - -Returns the updated version of this object. - -## Usage - -<<< ./snippets/update-1.java diff --git a/doc/2/core-classes/user/update/snippets/update-1.java b/doc/2/core-classes/user/update/snippets/update-1.java deleted file mode 100644 index 3f3332f4..00000000 --- a/doc/2/core-classes/user/update/snippets/update-1.java +++ /dev/null @@ -1,16 +0,0 @@ - -JSONObject updateContent = new JSONObject() - .put("firstname", "My Name Is") - .put("lastname", "Jonas"); - -user.update(updateContent, new ResponseListener() { - @Override - public void onSuccess(User updatedUser) { - - } - - @Override - public void onError(JSONObject error) { - - } -}); diff --git a/doc/2/essentials/error-handling/index.md b/doc/2/essentials/error-handling/index.md deleted file mode 100644 index 074f4f64..00000000 --- a/doc/2/essentials/error-handling/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -code: false -type: page -title: Error Handling -order: 100 ---- - -# Error Handling - -<<< ./snippets/handling-errors-1.java -All methods that accept a callback as an argument can return an error. The error can be generated directly by the SDK, or by Kuzzle and included in the response to a request. - -All errors generated by Kuzzle contain the following properties: - -- `message`: the error message -- `status`: an error code following the [HTTP standard](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) diff --git a/doc/2/essentials/error-handling/snippets/handling-errors-1.java b/doc/2/essentials/error-handling/snippets/handling-errors-1.java deleted file mode 100644 index 01d121cd..00000000 --- a/doc/2/essentials/error-handling/snippets/handling-errors-1.java +++ /dev/null @@ -1,17 +0,0 @@ - -kuzzle.checkToken("some jwt token", new ResponseListener() { - @Override - public void onSuccess(TokenValidity tokenInfo) { - if (tokenInfo.isValid()) { - // tokenInfo.getExpiresAt() returns the expiration timestamp - } - else { - // tokenInfo.getState() returns the invalidity reason - } - } - - @Override - public void onError(JSONObject error) { - System.err.println(error.getInt('status') + ': ' + error.getString('message')); - } -}); diff --git a/doc/2/essentials/events/index.md b/doc/2/essentials/events/index.md deleted file mode 100644 index 819d2700..00000000 --- a/doc/2/essentials/events/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -code: false -type: page -title: Events -order: 200 ---- - -# Events - -The [Kuzzle instance](/sdk/java/2/core-classes/kuzzle) periodically emits named events that provide useful updates about the state of the Kuzzle client. To subscribe to these events, use the [addListener](/sdk/java/2/core-classes/kuzzle/add-listener) function and specify the event name and the callback function that will be executed when the event is emitted. To unsubscribe to an event, use the [removeListener](/sdk/java/2/core-classes/kuzzle/remove-listener) function, specifying the name of the event to remove. - ---- - -## Emitted Events - -| Event Name | Callback arguments | Description | -| ------------------ | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -| `connected` | _(none)_ | Triggered when the SDK has successfully connected to Kuzzle | -| `discarded` | `error` (object) | Triggered when Kuzzle rejects a request (e.g. request can't be parsed, request too large, ...) | -| `disconnected` | _(none)_ | Triggered when the current session has been unexpectedly disconnected | -| `loginAttempt` | `{ "success": , "error": "" }` | Triggered when a login attempt completes, either with a success or a failure result | -| `networkError` | `error` (object) | Triggered when the SDK has failed to connect to Kuzzle. Does not trigger offline mode. | -| `offlineQueuePop` | `query` (object) | Triggered whenever a request is removed from the offline queue. | -| `offlineQueuePush` | `{ "query": , "cb": }` | Triggered whenever a request is added to the offline queue | -| `queryError` | `error` (object), `query` (object) | Triggered whenever Kuzzle responds with an error | -| `reconnected` | _(none)_ | Triggered when the current session has reconnected to Kuzzle after a disconnection, and only if `autoReconnect` is set to `true` | -| `tokenExpired` | _(none)_ | Triggered when Kuzzle rejected a request because the authentication token expired | - -**Note:** listeners are called in the order of their insertion. diff --git a/doc/2/essentials/index.md b/doc/2/essentials/index.md deleted file mode 100644 index a75e1c5c..00000000 --- a/doc/2/essentials/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -code: false -type: branch -order: 0 -title: Essentials -description: Essentials ---- diff --git a/doc/2/essentials/offline-tools/index.md b/doc/2/essentials/offline-tools/index.md deleted file mode 100644 index 2b8b1399..00000000 --- a/doc/2/essentials/offline-tools/index.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -code: false -type: page -title: Offline Tools -order: 300 ---- - -# Offline Tools - -When using an unstable network connection, an application must maintain a normal behavior when it is disconnected. Our goal is to provide the right toolkit to handle such situations. - ---- - -## Handling a Network Disconnect - -There are two ways to handle a network disconnect: - -- Automatically reconnect to Kuzzle when possible, and enter _offline mode_ in the meantime. This is the default behavior. -- Stop all further communication with Kuzzle and invalidate the current instance and all its children. The application will have to manually reconnect once the network is available. To do so, simply set the `autoReconnect` option to `false` when creating the SDK instance. - -_Offline mode_ refers to the time between a `disconnected` and a `reconnected` event (see [Events](/sdk/java/2/essentials/events)). - ---- - -## Subscriptions - -A subscription opens a permanent pipe between the client and Kuzzle. Whenever a real-time message or a modified document matches a subscription filter, a notification is sent by Kuzzle to the client (for instance, see the [Collection.subscribe](/sdk/java/2/core-classes/collection/subscribe) method). - -While in offline mode, the Kuzzle SDK client maintains all subscriptions configurations and, by default, when Kuzzle SDK client reconnects, all subscriptions are renewed. This behavior can be changed by setting the `autoResubscribe` to `false`, in which case, each subscription will have to be renewed manually using the `Room.renew` method. - ---- - -## API Requests - -While in offline mode, API requests can be queued, and then executed once the network connection has been reestablished. -By default, there is no request queuing. - -- Queue all requests automatically when going offline by setting the `autoQueue` option to `true` (see [Kuzzle SDK constructor](/sdk/java/2/core-classes/kuzzle)) -- Start and stop queuing manually, by using the [startQueuing](/sdk/java/2/core-classes/kuzzle/start-queuing) and [stopQueuing](/sdk/java/2/core-classes/kuzzle/stop-queuing) methods - -The queue itself can be configured using the `queueTTL` and `queueMaxSize` options. - ---- - -## Filtering Requests to be Queued - -By default, when queuing is first activated, all requests are queued. - -However, you can choose to omit certain request by using the [`queueFilter`](/sdk/java/2/core-classes/kuzzle#properties) property. This property can be set to a function that accepts the request as an input value and returns a boolean result which indicates whether or not the request should be queud. - -Additionally, almost all request methods accept a `queuable` option, which when set to `false`, will cause the request to be discarded if the Kuzzle SDK is disconnected. This option overrides the `queueFilter` property. - ---- - -## Handling Network Reconnect - - - -Once a `reconnected` event is fired, you may replay the content of the queue with the `playQueue` method. Or you can let the Kuzzle SDK replay it automatically upon reconnection by setting the `autoReplay` option to `true`. - -Requests are sent to Kuzzle with a `replayInterval` delay between each call. - -Any request made while the client is processing the queue will be delayed until the queue is empty. This ensures that all requests are played in the right order. - ---- - -## Taking Control of the Offline Queue - -You can be notified about what's going on in the offline queue, by using the [`offlineQueuePush`](/sdk/java/2/essentials/events) and the [`offlineQueuePop`](/sdk/java/2/essentials/events) events. - -The `offlineQueuePush` event is fired whenever a request is queued. It will emit an object containing a `query` property, describing the queued request, and an optional `cb` property containing the corresponding callback, if any. - -The `offlineQueuePop` event is fired whenever a request has been removed from the queue, either because the queue limits have been reached, or because the request has been replayed. It provides the removed request to its listeners. - -The `offlineQueueLoader` property of the Kuzzle SDK instance loads requests to the queue, **before any previously queued request**. It is invoked every time the Kuzzle SDK starts dequeuing requests. -This property must be set with a function that returns an array of objects with the following accessible properties: - -- a `query` property, containing the request to be replayed -- an optional `cb` property pointing to the callback to invoke after the completion of the request - -Finally, if the provided methods don't give you enough control over the offline queue, you can access and edit the queue directly using the `offlineQueue` property. - ---- - -## Automatic Offline-Mode - -You can set the `offlineMode` option to `auto` when instantiating the [Kuzzle SDK instance](/sdk/java/2/core-classes/kuzzle). This sets the offline mode configuration to the following presets: - -- `autoReconnect` = `true` -- `autoQueue` = `true` -- `autoReplay` = `true` -- `autoResubscribe` = `true` diff --git a/doc/2/essentials/realtime-notifications/index.md b/doc/2/essentials/realtime-notifications/index.md deleted file mode 100644 index 4c88f410..00000000 --- a/doc/2/essentials/realtime-notifications/index.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -code: false -type: page -title: Realtime Notifications -order: 300 ---- - -# Realtime Notifications - -With Kuzzle, you don't [subscribe](/sdk/java/2/core-classes/collection/subscribe) to a room or a topic but, instead, you subscribe to documents. -This means, that when you want to subscribe you must provide a set of filter definitions, using [Koncorde](/core/1/guides/cookbooks/realtime-api), that tell Kuzzle what documents should trigger a notification. Then, any time a document matches the defined filters, Kuzzle will send a notification to the subscriber. - -You can also provide an empty set of filters, which will tell Kuzzle that you want to listen to any change occurring on a collection, emulating the behavior of a traditional topic. - -To subscribe, you must provide a callback that will be called each time a new notification is received. - -Once you have subscribed, depending on the subscription configuration you provided, you may receive a notification when: - -- a pub/sub message matches your criteria (real-time) -- a matching document is about to be created or deleted in real-time (deactivated by default) -- a matching document is created, updated or deleted (once the change is effective in the database) -- a user enters or leaves the room (deactivated by default) - -You may subscribe multiple times to the same room, with identical or different subscription parameters, and with different callbacks. This allows you to dispatch notifications to dedicated processes of your application, instead of maintaining a single all-purpose notification consumer (but you can do that too I you want). - ---- - -## Document Notification - -| Notification field | Type | Description | Possible values | -| ------------------ | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | ----------------- | -| `document` | [Document](/sdk/java/2/core-classes/document) | Content of the document or real-time message that generated the notification | | -| `scope` | string | Indicates if the document enters or exits the subscription scope | `in`, `out` | -| `state` | string | Shows if the document is about to be changed, or if the change is done | `pending`, `done` | -| `type` | string | Notification type | `document` | - -#### Example - -```json -{ - "status": 200, - "requestId": "bc41ced6-38fc-42b9-8fd5-22ae0774aac2", - "controller": "name of the controller that generated the notification", - "action": "name of the action that generated the notification", - "collection": "collection name", - "index": "index name", - "volatile": {}, - "state": "done", - "scope": "in", - "type": "document", - "document": { - "content": { - "content": "document content example" - }, - "id": "" - } -} -``` - ---- - -## User notification - -| Notification field | Type | Description | Possible values | -| ------------------ | ----------- | -------------------------------------------------------------------------- | --------------- | -| `user` | string | Indicates if the user enters or leaves the subscribed room | `in`, `out` | -| `volatile` | JSON object | If provided during subscription, contains application specific information | | -| `result.count` | integer | Updated number of users subscribing to this room | | -| `type` | string | Notification type | `user` | - -#### Example - -```json -{ - "status": 200, - "roomId": "ID of the room concerned by this notification", - "requestId": "5897cd2f-a8a2-40b2-aa43-b31898172008", - "controller": "subscribe", - "user": "in", - "protocol": "protocol used by the notifying user", - "timestamp": 1453193069592, - "volatile": { - "optional": "user information" - }, - "type": "user", - "result": { - "count": 42 - } -} -``` diff --git a/doc/2/index.md b/doc/2/index.md deleted file mode 100644 index 002542d1..00000000 --- a/doc/2/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -code: false -type: root -order: 6 -title: JAVA SDK 2.x -description: JAVA SDK v2.x ---- From 8d8dcc107ab0a0def5aad7bafc7af3c2e4115bfb Mon Sep 17 00:00:00 2001 From: ycombes Date: Fri, 23 Aug 2019 10:56:11 +0200 Subject: [PATCH 004/134] Change kuzzle version in build.gradle file --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4ab207a4..81a729e5 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { } group = 'io.kuzzle' -version = '2.0.0' +version = '3.0.0' allprojects { repositories { From 09666e932ac33472d7e7f339fc23de0be02f3209 Mon Sep 17 00:00:00 2001 From: Aschen Date: Fri, 30 Aug 2019 10:29:23 +0200 Subject: [PATCH 005/134] feat(doc): init framework --- doc/3/controllers/index.md | 7 +++++++ doc/3/core-classes/index.md | 7 +++++++ doc/3/essentials/index.md | 7 +++++++ doc/3/exceptions/index.md | 7 +++++++ doc/3/getting-started/index.md | 6 ++++++ doc/3/protocols/index.md | 7 +++++++ doc/doc.sh | 4 ++-- 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 doc/3/controllers/index.md create mode 100644 doc/3/core-classes/index.md create mode 100644 doc/3/essentials/index.md create mode 100644 doc/3/exceptions/index.md create mode 100644 doc/3/getting-started/index.md create mode 100644 doc/3/protocols/index.md diff --git a/doc/3/controllers/index.md b/doc/3/controllers/index.md new file mode 100644 index 00000000..fc59442a --- /dev/null +++ b/doc/3/controllers/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 100 +title: Controllers +description: Kuzzle Java SDK controllers +--- diff --git a/doc/3/core-classes/index.md b/doc/3/core-classes/index.md new file mode 100644 index 00000000..5f2b6b45 --- /dev/null +++ b/doc/3/core-classes/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 40 +title: Core classes +description: Kuzzle Java SDK core classes +--- diff --git a/doc/3/essentials/index.md b/doc/3/essentials/index.md new file mode 100644 index 00000000..5ed4b8a5 --- /dev/null +++ b/doc/3/essentials/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 20 +title: Essentials +description: Kuzzle Java SDK essentials guides +--- diff --git a/doc/3/exceptions/index.md b/doc/3/exceptions/index.md new file mode 100644 index 00000000..0cadf3c0 --- /dev/null +++ b/doc/3/exceptions/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 80 +title: Exceptions +description: Kuzzle Java SDK exceptions +--- diff --git a/doc/3/getting-started/index.md b/doc/3/getting-started/index.md new file mode 100644 index 00000000..150d6807 --- /dev/null +++ b/doc/3/getting-started/index.md @@ -0,0 +1,6 @@ +--- +code: false +type: branch +order: 0 +title: Getting Started +--- diff --git a/doc/3/protocols/index.md b/doc/3/protocols/index.md new file mode 100644 index 00000000..b2ad68fb --- /dev/null +++ b/doc/3/protocols/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 60 +title: Protocols +description: Kuzzle Java SDK available protocol classes +--- diff --git a/doc/doc.sh b/doc/doc.sh index e0e4a476..0d7e18ec 100644 --- a/doc/doc.sh +++ b/doc/doc.sh @@ -2,8 +2,8 @@ set -eu -DOC_VERSION=2 -DOC_PATH=/sdk/java/2 +DOC_VERSION=4 +DOC_PATH=/sdk/java/4 # Used by vuepress export DOC_DIR=$DOC_VERSION From 41bc738a61f6ec2ff2864442ff3310f00cffbc39 Mon Sep 17 00:00:00 2001 From: Shiranuit Date: Wed, 8 Jan 2020 13:39:36 +0100 Subject: [PATCH 006/134] SDK new architecture w/ WebSocket (#40) ## What does this PR do ? This PR adds the Kuzzle and WebSocket class plus : - AbstractProtocol class (Used to create new protocols) - EventListener class (Used to handle events) - Task class (Used to create a new CompletableFuture to handle response of queries) - Response class (Used as a structure) - KuzzleOptions and WebSocketOptions class ### How should this be manually tested? Run `cd kuzzle-sdk-java && ./gradlew test` --- .gitignore | 7 + .travis.yml | 127 ++++---- build.gradle | 131 -------- doc/doc.sh | 32 +- gradle/wrapper/gradle-wrapper.jar | Bin 54333 -> 0 bytes kuzzle-sdk-java/.project | 23 ++ kuzzle-sdk-java/build.gradle | 54 ++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55190 bytes .../gradle}/wrapper/gradle-wrapper.properties | 3 +- gradlew => kuzzle-sdk-java/gradlew | 2 +- gradlew.bat => kuzzle-sdk-java/gradlew.bat | 2 +- kuzzle-sdk-java/package.json | 11 + kuzzle-sdk-java/settings.gradle | 2 + .../Json/ConcurrentHashMapTypeAdapter.java | 155 ++++++++++ .../sdk/CoreClasses/Json/JsonSerializer.java | 30 ++ .../sdk/CoreClasses/Maps/KuzzleMap.java | 251 +++++++++++++++ .../sdk/CoreClasses/Maps/KuzzleMapEntry.java | 64 ++++ .../io/kuzzle/sdk/CoreClasses/Maps/Null.java | 8 + .../sdk/CoreClasses/Maps/Serializable.java | 8 + .../CoreClasses/Responses/ErrorResponse.java | 57 ++++ .../sdk/CoreClasses/Responses/Response.java | 142 +++++++++ .../java/io/kuzzle/sdk/CoreClasses/Task.java | 100 ++++++ .../io/kuzzle/sdk/Events/EventListener.java | 74 +++++ .../sdk/Exceptions/ApiErrorException.java | 41 +++ .../Exceptions/ConnectionLostException.java | 15 + .../sdk/Exceptions/InternalException.java | 19 ++ .../sdk/Exceptions/KuzzleException.java | 38 +++ .../sdk/Exceptions/KuzzleExceptionCode.java | 30 ++ .../sdk/Exceptions/NotConnectedException.java | 14 + .../java/io/kuzzle/sdk/Helpers/Default.java | 14 + .../src/main/java/io/kuzzle/sdk/Kuzzle.java | 292 ++++++++++++++++++ .../io/kuzzle/sdk/Options/KuzzleOptions.java | 140 +++++++++ .../Options/Protocol/WebSocketOptions.java | 113 +++++++ .../kuzzle/sdk/Protocol/AbstractProtocol.java | 79 +++++ .../io/kuzzle/sdk/Protocol/ProtocolState.java | 6 + .../io/kuzzle/sdk/Protocol/WebSocket.java | 186 +++++++++++ .../CoreClasses/TaskTest/KuzzleMapTest.java | 239 ++++++++++++++ .../test/CoreClasses/TaskTest/TaskTests.java | 151 +++++++++ .../CoreClasses/TaskTest/TestableTask.java | 32 ++ .../test/EventsTest/EventListenerTests.java | 159 ++++++++++ .../EventsTest/TestableEventListener.java | 22 ++ .../io/kuzzle/test/Helpers/DefaultTests.java | 24 ++ .../test/java/io/kuzzle/test/KuzzleTests.java | 177 +++++++++++ .../test/ProtocolTest/TestableWebSocket.java | 38 +++ .../test/ProtocolTest/WebSocketTests.java | 90 ++++++ .../java/io/kuzzle/test/TestableKuzzle.java | 51 +++ package.json | 11 - settings.gradle | 10 - src/main/java/io/kuzzle/sdk/Kuzzle.java | 5 - 49 files changed, 3043 insertions(+), 236 deletions(-) delete mode 100644 build.gradle mode change 100644 => 100755 doc/doc.sh delete mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 kuzzle-sdk-java/.project create mode 100644 kuzzle-sdk-java/build.gradle create mode 100644 kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.jar rename {gradle => kuzzle-sdk-java/gradle}/wrapper/gradle-wrapper.properties (79%) rename gradlew => kuzzle-sdk-java/gradlew (99%) rename gradlew.bat => kuzzle-sdk-java/gradlew.bat (94%) create mode 100644 kuzzle-sdk-java/package.json create mode 100644 kuzzle-sdk-java/settings.gradle create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java create mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java create mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java delete mode 100644 package.json delete mode 100644 settings.gradle delete mode 100644 src/main/java/io/kuzzle/sdk/Kuzzle.java diff --git a/.gitignore b/.gitignore index 2e9487e3..2407ed41 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,12 @@ build out .idea +bin +*.iml +*.class +bin +.classpath +.project +.settings doc/framework \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 674ad6f2..5a99cb79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,31 @@ - -env: - global: - # BINTRAY_USER - - secure: "LxONQZ8tHhxTqgu+kqx9fMCubCfTQHZsy/3ibE+l72xG8sOAYfj4hB5k1p4kklnv3skeFQEiL6B++B2qRITOEAPRdD8FExkc+UF/TM1rY5aUtjIjoA3uH4n9hYjHirTO5qNKf4KxDr1Zbcn4ISGebJ0EYwE0SG/ptrd06wPp1G8AHshc8XaZgen6gDaik66OWpQkOkmGsRz2EPmIBVgo7L2LGK21DSxE4/PTo+ou0WYCyxyyWSKLTLt1xZpt9LOtk7IckrHl+Nenl6IbV/CjHb3+5vwdifyFQd+K6AVe32iTIVjdxj7rDhEHYD0EqKb79ey+u8p9HquLnGH03gcVBeFQu/qhhQStsiwrD/S9c8jwBjWOOUnVI4bEbqjqxFaRlPfVnRaAjQZLRKHdqxyTJCdC2Ls79LmkqSCyTxM7WBwwgu4Slf6RJSbKJb5naHYlwDuKPbeyHLAYrxgjEHC28bxQiTr5wwBWxE9BLxUcnkFAXzsy3qE74FQOIjvQbtrruLIOGwRGRYtzyfygGA3MfTHug6JwZGngqFf3k+kbznE8fZe7zxMwT63P6/54rR5fU/plLoTNFqdQsZGAfGOSYuHIEzWXOkWxffqsOwxPa1VxQTLD32O95oBcrcvmw4toC2NeFTe/+zZRMfGMbu7QIi0AL3qFpky3j12zcyA/M2I=" - # BINTRAY_KEY - - secure: "Iqn4ImAwFmQeoXXDb5JOsfcunSiSeLvdp4+AEsIeniMhpIk++ZJPDSxecC+NrvndTrxOXVqHEsFUfHnZYvPHMuvg9nhXvz/rmmyYH0hZqkKg2q2qM+Sz2UJBCvs6D1sJv3ZEVi8d6fVx5bbKXMzSE023XFBBK7l8nBsG5ObXBOzTzrus9UP+fk4FXif/QKJNcUSN7rLejUIxMCk36gMQYqYGiiqL3VE60aTpaUh7Vqj/8nCEPcO3K3gXTVybcGBcmsvinV5YEc+5s5ue8eX10ONY0oYF5GFd7aEsrKEFzT2d7MVq0a29cH1rWrxt6q7vXGZNKAdAQrDyRZUz9rMFtqH+2xOgagm22UiUYNlzrn2eDYRBd08X0y043gumdgmOq/CsyaI5bcUSKMr+rsZ2XIzBjefl8MU0xBhtKMO9g9WRfGBxjRbdg0ivRQoVGJbcUXTDl2WrLMgMjt8DT4nQP+PHdIV2FjZVNioqucqmEzfHIJt+hiw7EonGDnZ9uqkW6hm6b4JpGr5QF1yY6kKVCUQxLueUBAVdiZpULdevL7uYEUzdWIES2wTFE7LaWpHqnCOHYVpkIQpdole6+R0OhINhSHK0FW858xhZ2QGjtL1SSh5yzK4th6dpGKCiwMUSGSj5frpIeWPi+GqYoUQz+TvMGLGG2XGfihx74kQE0FA=" - - AWS_ACCESS_KEY_ID=AKIAIYAXFUAHXOWP2MJA - # AWS_SECRET_ACCESS_KEY - - secure: "dIcQzFpHKRf92cAiMA+SYsudtHWNcbYadVDb7zlJayWGUGy0i4CGwwOoOOrUcWgHxYhdN9XGwvFJTSswjHLRiHEyPFBwW8x/VfaCRS+jAcblMXyWNajvm0930S/3fRv5LA+4UKNmeXMuCGSf35ZqyEIEeuThkIomYvB/tBD1wcMpBUtQfmilLm3sUTaGUnFB651jBHshlYOZ8BAGLLmX1PAfT1wCrpVcrjq5kayNOIilJkwKGSr6q9C0p7+ULNZ4bHsATKLlYNs7Xcs+9a66p1EtKetP72DQsHrr8x3wB2Hhk3U425kmjIoE3gYnF7x3h3EpO5m0rGessbgdRF1SF7XK7Bsj4ukLb4HoktA8G7734ox4848RpH60aKUHRCsiebX7JKgJe1eEwU5BZK8+PFPGH6bI1YG1HQNqthzotTHFXu058uMHnyLv2PmDWWEYMM79fCyuRo8gJJ8GJhDgaGLgtizzEb6grcNW+QwunjA6nP4o7F9o+9b3lfGlsgL595V/CeWLNnHvENkSr67RN2NkDZm6q6EHbOk8AWtQc24mVawCwCbcJjp0sPkbQdCHUXSBNXjdwrvJLA3h94A2uVEmrV7mzMdfj+i9X3IS/HXRLeQk6Ivq2s/b1W6c7rBfz4zZUO7Uu5iYpVzT71yNFra13JkW3REFgHgETEvGkko=" - - -sudo: true - +--- +# ----------------- +# YAML Templates +# ----------------- + +# ------------------------ +# Jobs configuration +# ------------------------ jobs: include: - stage: Tests name: Dead link check if: type = pull_request OR type = push AND branch =~ /^master|[0-9]+-(dev|stable)$/ OR type = cron language: node_js - node_js: 10 + node_js: 12 before_script: - - npm run doc-prepare - - npm run --prefix doc/framework clone-repos + - bash -c "cd kuzzle-sdk-java && npm run doc-prepare" + - npm run --prefix $TRAVIS_BUILD_DIR/doc/framework clone-repos script: - gem install typhoeus - - HYDRA_MAX_CONCURRENCY=20 npm run --prefix doc/framework dead-links + - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io if: type = push AND branch =~ .*-dev language: node_js - node_js: 10 + node_js: 12 env: - NODE_ENV=production - S3_BUCKET=docs-next.kuzzle.io @@ -45,26 +39,26 @@ jobs: - python-pip install: - - pip install awscli --upgrade --user - + - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - gradle assemble script: - - npm run doc-prepare - - npm run doc-build + - cd kuzzle-sdk-java && npm run doc-prepare + - npm run doc-build && cd - deploy: provider: script script: - - npm run doc-upload + - cd kuzzle-sdk-java && npm run doc-upload && cd - skip_cleanup: true after_deploy: - - npm run doc-cloudfront + - cd kuzzle-sdk-java && npm run doc-cloudfront && cd - - stage: Deployment Doc Prod name: Deploy docs.kuzzle.io if: type = push AND branch =~ /^master|[0-9]+-stable$/ language: node_js - node_js: 10 + node_js: 12 env: - NODE_ENV=production - S3_BUCKET=docs.kuzzle.io @@ -78,42 +72,53 @@ jobs: - python-pip install: - - pip install awscli --upgrade --user - + - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - gradle assemble + - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - gradle assemble script: - - npm run doc-prepare - - npm run doc-build - - deploy: - provider: script - script: - - npm run doc-upload - skip_cleanup: true - - after_deploy: - - npm run doc-cloudfront - - - - stage: Deployment - name: Deploy to Bintray - if: branch = master AND tag IS present AND type != cron - language: java - - jdk: - - openjdk8 - - script: - bash gradlew test jacocoTestReport - - notifications: - email: false - + - gradle check after_success: - bash <(curl -s https://codecov.io/bash) - deploy: - provider: script - script: ./gradlew bintrayUpload - skip_cleanup: true - on: - condition: $TRAVIS_BRANCH = master + # --------------------------------------- + # Builds + # --------------------------------------- + - stage: Builds + name: Build SDK Java + language: java + jdk: openjdk8 + sudo: false + before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + install: + - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - gradle assemble + - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - gradle assemble + script: + - gradle build + +# ------------------------ +# Stages configuration +# ------------------------ +stages: + - name: Unit Tests + if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ + - name: Builds + if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ + +# --------------------------------------- +# Notifications +# --------------------------------------- +notifications: + slack: + rooms: + - secure: "ACjz4TJEYBEzmwVOYrCNnr4+jC0FaX+qh150QacYGIgaQYL+U3xLEQmWNlZ3oxaPPMDAk42m+diHolqNwh6qsOWaPSWRlGfLKhHLSzRI98bhF7HQ+3eLMYmx7y7SKwRzyRjus0jgxp0Kc2mq0nhKqv+7rarQtIgWlC1PLrzZ35CUbUlqYSoeYAlXoyDB1eZgYsvjt+eC5yCvGePsfKbupWC2/hIVl+qZ+9AhVmOfiMv7daFW29Vu300aoY+0IqwX7jHGcmHn/7QCRsx0IBy/SL24TzfSV9SUSnbjK4fTrcrhjYDEZdH1lpvDtvr50GgkrTjy1wPVz8XIyCZ7LZolylkx+nR1MWyvum20QRFub2Qhz/+rS+OFiQZ8H01BPuklLUTSQhBksfpGBck3d2yNLiTqGEVWYTnZ9mkCnMQ3BzJXEF04KLHG7wYn2rk6wjPghVmFQH5GMsxM5v33CFgcNzp6lRJOX9CmjZosck6o9SA0WlazHH/CLWWKk1wrQ1ygDayW5m+N/o58UIxgW2LIUlp4tV1z/bRtO2yTd020yWchlKPVmf1A5OMfigJNMRsQGNZNadS7qA2M394OJw3/Hg+0EVF8gai/V8FRijmkxmhYyCIYMcjaGwx8JxfoMrRKcM76haBAhg0JQxsSVKzyXfONGzd5DXjcxSGZ2wuEdu0=" + on_success: never + on_failure: always diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 81a729e5..00000000 --- a/build.gradle +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This is a general purpose Gradle build. - * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ - */ - -buildscript { - repositories { - jcenter() - } -} - -plugins { - id "com.jfrog.bintray" version "1.7.3" - id 'jacoco' -} - -group = 'io.kuzzle' -version = '3.0.0' - -allprojects { - repositories { - jcenter() - } - apply plugin: 'maven-publish' - apply plugin: 'java' - apply plugin: 'java-library' -} - -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource -} - -javadoc.failOnError = false -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -bintray { - user = System.getenv('BINTRAY_USER') - key = System.getenv('BINTRAY_KEY') - publications = ['MyPublication'] - - pkg { - repo = 'maven' - name = 'kuzzle-sdk-java' - userOrg = 'kuzzle' - licenses = ['Apache-2.0'] - desc = 'Kuzzle JAVA SDK' - vcsUrl = 'https://github.com/kuzzleio/sdk-java.git' - websiteUrl = 'https://kuzzle.io' - issueTrackerUrl = 'https://github.com/kuzzleio/sdk-java/issues' - publicDownloadNumbers = true - publish = true - } -} - -def pomConfig = { - licenses { - license { - name "The Apache Software License, Version 2.0" - url "http://www.apache.org/licenses/LICENSE-2.0.txt" - distribution "repo" - } - } - developers { - developer { - id "kuzzle" - name "kuzzle" - email "support@kuzzle.io" - } - } - - scm { - url "https://github.com/kuzzleio/sdk-java" - } -} - -publishing { - publications { - MyPublication(MavenPublication) { - from components.java - artifact sourcesJar - artifact javadocJar - groupId 'io.kuzzle' - artifactId 'kuzzle-sdk-java' - version version - pom.withXml { - def root = asNode() - root.appendNode('description', 'Kuzzle JAVA SDK') - root.appendNode('name', 'kuzzle-sdk-java') - root.appendNode('url', 'https://github.com/kuzzleio/sdk-java') - root.children().last() + pomConfig - } - } - } -} - -dependencies { - compile group: 'org.json', name: 'json', version: '20180813' - compile 'tech.gusavila92:java-android-websocket-client:1.2.2' - testImplementation 'junit:junit:4.12' - testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0' - testImplementation 'org.mockito:mockito-core:1.9.5' - testImplementation 'org.skyscreamer:jsonassert:1.5.0' -} - -jacocoTestReport { - reports { - xml.enabled = true - html.enabled = true - } -} - -check.dependsOn jacocoTestReport - -sourceSets { - test { - java { - srcDirs = ["test"] - } - } -} - -artifacts { - archives sourcesJar - archives javadocJar -} \ No newline at end of file diff --git a/doc/doc.sh b/doc/doc.sh old mode 100644 new mode 100755 index 0d7e18ec..b7d98fa9 --- a/doc/doc.sh +++ b/doc/doc.sh @@ -2,51 +2,55 @@ set -eu -DOC_VERSION=4 -DOC_PATH=/sdk/java/4 +DOC_VERSION=3 +DOC_PATH=/sdk/java/3 +PWD=$(dirname $(readlink -f $0)) +FMWKDIR="$PWD/framework" +FMWKTARGET="$FMWKDIR/src$DOC_PATH" +VUEPRESS="$FMWKDIR/node_modules/.bin/vuepress" # Used by vuepress -export DOC_DIR=$DOC_VERSION +export DOC_DIR="$PWD/${DOC_VERSION}" export SITE_BASE=$DOC_PATH/ # Used to specify --no-cache for example ARGS=${2:-""} -if [ ! -d "./$DOC_DIR" ] +if [ ! -d "$DOC_DIR" ] then - echo "Cannot find $DOC_DIR/. You must run this script from doc/ directory." + echo "Cannot find documentation directory: $DOC_DIR" exit 1 fi case $1 in prepare) echo "Clone documentation framework" - rm -rf framework/ - git clone --depth 10 --single-branch --branch master https://github.com/kuzzleio/documentation.git framework/ + rm -rf $FMWKDIR + git clone --depth 10 --single-branch --branch master https://github.com/kuzzleio/documentation.git $FMWKDIR echo "Link local doc for dead links checking" - rm framework/src$DOC_PATH - ln -s ../../../../$DOC_VERSION framework/src$DOC_PATH + rm $FMWKTARGET + ln -s ${DOC_DIR} $FMWKTARGET echo "Install dependencies" - npm --prefix framework/ install + npm --prefix $FMWKDIR ci ;; dev) - ./framework/node_modules/.bin/vuepress dev $DOC_VERSION/ $ARGS + $VUEPRESS dev $DOC_DIR/ $ARGS ;; build) - ./framework/node_modules/.bin/vuepress build $DOC_VERSION/ $ARGS + $VUEPRESS build $DOC_DIR/ $ARGS ;; build-netlify) export SITE_BASE="/" - ./framework/node_modules/.bin/vuepress build $DOC_VERSION/ $ARGS + $VUEPRESS build $DOC_DIR/ $ARGS ;; upload) - aws s3 sync $DOC_VERSION/.vuepress/dist s3://$S3_BUCKET$SITE_BASE + aws s3 sync $DOC_DIR/.vuepress/dist s3://$S3_BUCKET$SITE_BASE ;; cloudfront) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index c44b679acd3f794ddbb3aa5e919244914911014a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54333 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
K7|BUm`^7>V&Zk%^_d-%A~k@lFe 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

Qox z0`xkkAPQweAlfOtBr;PCpCyY@I(B}_q2#9zd3W%J|3eWKpVLA(TO z5%Zf>!cM)^YQ?&n@bvEeMq7qf)_Rqe86vho+bO6^&4TNMJrCK9V`zKRuXfd8M5%~s`9IYm95q_DwQl# zw{#U3?nojDov=wtw2sQ^BnoussoxlxR&D21ZG+h=hHHPRxddwfoNLfm=2*#>S;;QV z!b3X2P@Y~tG@ zEsv?a$avqb z!A;+xKmVyOCP2?u_M?6ro!|6p3hE1XWYaW#CmFc3%s^$13Jd-mV|FHKD;5_gD8=oL zv9{Lt);bu_WV&2XT749?b+HvE@zDP45=p1BaTTD|Ujs_}Pptcu-!Z)p9f!fEsGcW0 zNI*A-;X6d73JsXdwnqOVLo}*B?BqJxV>?b(wQd&e?en)d{)G}U1e&OCD|aImZ`3H6ub*NDlQpCW z7Fvb22s61l4U30fGmyZE_9%KpbX?j2jtpKREvCcg;qd6)+bMk%rMajuBY7%4@T_MqDUPcc-On;3{h}TDaHHiD8llM)Y zenv30d7+wIdgsx!>bknt{ArjL-`i3>%>zm7b1aEWPdW0}Dn`+tNiz|#nDU#_Mw2GC zF??~VSmm`iB5JmNJnfW{;S|zFTxex&mW5Oa^r*W%uJM>*pmo=TO24r~ap-AG@Z^z& z@ag%!NpczPaLM}v-G7twO{k8Y@*^M&%;gdP$@biw`0`qQ$SNmi*8mkopTL?V(*&}c zBLjqsFZ6T@g5&L+aa)+Qr61|;9SRLU@j)Cb*v4VnqP&h-Cqz$)nB3x)s@C4u!g%pM zEyb*^R3|r3{4MKBUPH?(D8W81Y2Wi>?d83MZ{MQ=!DaVyWJQG-->ZYzQh6mm-2RAr zwJeG0GKJdfJyLuoeXc_f?Ancb`$9pUO=9Ebr%&VtFna#h@=(gm!2vLt`(x|`>{9<} z;LQAwbHwG{$}BQEX-KrBUk$h+Oe|hb=vXisNt!NgrwZ!qNZKii4fNz~AIrU&Cthe& z52`m1Pr}7=!w75=OcL=4TjSp2n8D(|{FJg?rBNVX+2cqF#nR*srLf3GN^A4tb~jU^ zw^00dk6n`pHdS@eyf=nvnjNK@PwmDHX|tg8hQda*<{Z&cN~6kAkK*PmYn!Yzdc&qo zZRN_;yI>xRqWF|ahf0Yk&#(p9mfqqvcEXjhG7XuCqJKPLZjihSvsrMYmv?GtZtpBC zygaAfZLcR?ncPb{QqRN2JsWmcosmDIY;l(-I{^F9WE4l-zK$g{sJwQ;rCrzj0d1cdA`jz{$1?pXrG=acA{?JbGvy(oh&ivO9cX;@g)xX}$b5Kq948PdDBiJbiYt zR0vER&T`jt{Dj;JtKbTgsy#L^0Zs{7FHT^NL1-580djJX)=Wk;e1aj-1UzILng@P` zgo%F__Zz9(sqT9~vJ}FxsRdQtC%d@`Y#?J>qrJisrL;3PxBXf$=g6%%F_Kn$wT!uy>CK@uaU z0F>zhy{(7o7W{}c*oBRdoE}3X9G68iyzT}{29wew58xymHl3&f zuKG?e$hb&uX*2Ki=|a54*X&bX`B`dyny*-oDJu~g-4!B*9?~JIa+lH+$w8>&CeB|M zHvac;C8+@GF9lftZ_OM3ZT2pD_C|l3H&!SuSWnBsak1EK_1KA#TB#1nPbCna#xZ|L zpr$O$`yj6vKXAO9!cL#;+Jqw2C99vUJ7z+5)ek$x)ON(BhmLXEvqt zE!l_#8jiyN2{>H4nZuoy$hkMW7~ZA(&|1LI{Yc%}K>^G0u+8Mhn>+&O@;9PmZ+CBO zd<`V`uQ_1;u#fK2XLP6rV;~bO>TAn7O zQMZ>EM(ELT)0mClcC7IkY##L4t!cV?uT^+Uv(ezz;AQS!p56^|2ln2^-NffhZ58{8k5t*V zK`^yH?32h(0seh<&w7XO%$Z1y)w53NfD`s^S{ugGPuHN8_N`V=MyaLW6}=7_9keUc zvywH`bHX{CBFadUFYkPsYx=p;Pq^#j9gMo|hCtf!oZMZ6X~|VEMT>W)6bPXLuT2Ap zJ%ZZk@$w9(`$o7^Iy-RnM@|Xu={|tY$Y&YlR*My=zA-==mW?tW$O31Vktg8KK&8c| zt&F3QqchlLNVw7JK-*T|@o?4G%0i>wMA$*6Ho#wB=#~XnqUXjFR}?T@Q0ZC4cK~uy zai|eukdf#KcZjRHEmS(8y5K?=Gy&|vDh_o+kTdxq`%T@zMMso0AuN*p|hGHue ztCRZL7%~=DgK+i8FgEJPi?!01K5?H;fX!C`Y@X$J)=Gca{L9sQqSC)S;ohgSlXA>x zl|!Cx$o0kf70i=VQyK_; z&K^)rtR@yP*;m_RzF|SzbaP7PBWHUc?&b|#+I6n2Hfgbm;0k9HKrS{`Z4Dakb4dY*Nn57C#) z=ECn}*Y1u~%pvL}>{5-!9ou<#23Q+=AWl%|Fh%D`@94AW$~9{*_^6gdOv_vO&i4#0 zi>d7wf0OY^@!GR6z5U_yf%%@H zb_*}SllSF=(a5w$dA9WgP&+VDPtU-lb%--Yg=2F}3b)WP0VEyFbgc;K0!u_p1{4rl zuT+SIC>2yD51g9c>`p3T&p2+oQL(5e|2W(B$-NV`5TnJLPXMj)X95zlFc(T zV;*6TyX^>C`K+kBi4bGJ>i#^BW(A^ z2R?pZE|5he!8_?UlcB|w%_0M@^j3}-P=KiErPlGVW3{%4&fPv#IAO4uW)`Fs%HdX0 z4uXay5=!}E#1_g(zlx6i4*S=UAd|qct{89ztmyBuO26J4`s1zm+aQoAuk}+_iK|wv z)>%rbE^X5#f=rmq8cBx`-;@{04=R@PmRT(5WWZS2n1skDm#0`Jkoy++K0nNb`4v30 znKSlSX6s(oFqg~Iu@@rhE)gMy+y%s!B#=XC5lrSbcUrKR$z_rHy{EXWQk4a zmmK_S-=qaodySWOuo0Yn0BnhzJa^IL{EV%fVr%SpfN3d4*xzu`(i-(9^dQMw_P_=J3AAf)c! zAse)jx9GXO<_2en3`Uh-2z8`DF&5mVd9kgOIN~Y#PHsnmFyg$b8z^Yy(D02 zoKEp6SSnKeg4dW0^j?V;Nn5Msgfom9_Ra|-8Eq(DM2}Po zznRFri~2Y@(7*&=g{uWLz>v=P+NbkQ%-4S*!O-i6?^~ojVUXKfh^9Jb%7Ug488T`; zw%)u^R7wXUN^k!Ch~9-yz2O91qMVV+)k#Se#gDM&Z-nT)& z`UYdx9f?)jAU1d0MkwkmwszZ9x^9G4YoBv2mCTx!u*`eK7){fT)5EE;*$DjXHpwDf z+B>rK9jC1zCQ1Bc10wytMU7r7OkgF~_?uGdw*u+T705iMs*&&Kw3bSnqm-`FrA}vr z!W%guPH=rNWM0$5a=0G^P$m1Q?MNLmXp%Z3rbRtARBplpqpfO+n%Hn7vqA5C%b-Qp z+eQD1+DQj-rcg*QeYitDz0(!Y!KC7r^cItL6*ZnfuNh6R}}T(~1u5O?VNB zazm$B2ZzJRrqkk@@!TD{k*wqsa-1eO`MW5waLvX58*vi*Apt}OUQ@w(Q1@!D(UW>e zcO0zH`fRacvP`=RNHEB@r>%OdxQEbG=|2&qN@3-lQ4o9cuW<6K2YgR3sl()d2)fvc z^ksPGL6UJVNL3_`?cQoV;vZTJcT;DI>_PSo?%u7+8!E%x9~O@p)qhSD8#35D$v7(K zI6H7FIw1XofP_Jo4t<=rHzC9K+?pUdAhr){`9xQE^SUL8+nAY5f+8iU;k}(35!A}5 zm!^M^MqQWaj~5xVnv+C0ya7h81TgadkGbxzefOD);{eG3q$gwNrNF|#Fj-_Od}ULz z8YDP=@sNU0v3OxgT0-}CLj^Eu&V#2(x0Rm<)4@G1UWXF*)%qk{j5g%S*Y$OeJ? zrF-59F#A3AL1aYzc$qfI_b6}LRCM2~8=I9THdQ0E{)ZU}7FdO>e;(H)(3iSoVHkG|S#aj2Tq z13192TLHUM^uIHq{rjM;u=Z28^GTWv3EBa)vBW`cSytEb%bhW8nkXY3-V(wH_O-Kb zkP}(sZUe(T&)sG?G50O_tqA(K)qYg?c>VH6H#`}x6q z^DW3M^$!}RaP~A_2mO^0sqR|=y3Sp>BC03%Qygt*H(XbIm%!HvtsA@`B>Z=aS*)YC zBhe6n2D$h$SNia^wYS>hGET4Ig|KlNT5>U(35bGx_ujl-I|9FIiUn z%A!qX4=Gi_*^Yx@ek2!es9RP$&WoWkyKoO_s3fM*-ZWPXC|6kr#%W@9iJ6;+K=B8_ zgLBgb&2+wc=YH{yfsSfL79Qm*NZAv+`Eg?!%5~Vh$RK}sRimWG^2(=ISXblie3Gsm zkK2$-;pwf)lq+C2v?v$rk~-@{_#m}iJ}PhSt9AF`&k?MvcWSmHaa$jN`&g7=<{wAR zNZ3fLv?YO6KfWer;3IoQUMtDBm|b|oLr4eVAU1OGL+}d=m5|f}Yjo!b6}I*bgVH1ubk21&MUkV)QN7<&uymkUFE>r< zRJC!XLc#MB*=_8uo-W;Fba(JOkRc)8K>If?}tg%gm)QkX(fIQa|paNyJ8fcJnWvT2Uz|@W^8=TE8K%hO4V={C$dIW zk<_T%6h2)427`Bs0W+9r@(4Pvw#;mAk!7(6hSdultQxeDKf*0j9hHq63p&l*E(FHq zl~K*c=h162i{3RX9UFFpLROYIRdmX|o1R3iy^YjVKc=N{?5{iTVIC(6EOWfq@NLSw zX(u)6dvXRcHYKWnVf9zj!?PJ-8WU%! zdEZM6*bp}($=xSOM%u!x2^BAKOZfSc!}MT;t8+GqQSzI5X>Z1-J85T-mVmxY<0e^& z7~XF%qlW1*u9!0frNO=uAfZ7yv-Y6Y*;5X@{vO#^|7xb1f=&>p>&?AtPz(}mu9AG+ zz|9w;ukfOIUX0b>>nJ9vB|CHsz+>vFxdQ5rvAY&;vA40ZJ@E0nI_}!cuNc>j zSfe|EQlVpN8lnf%3D(b?beq9Cc!v}_9kvVOKl6CnmZr&i#72Zag{PpMy*G}v??HyN zO8&AaWQrqa{}nGEUv*xlXQ8qs4naxzP?UxmT=QK4?m>78a}pL0&=Q;c3^)#t!f1&S za(5yxVC4v$X(0N*9uQ{#cWj(`#rCG-Fy;-80sV-kOj z2GWhcO2{(!nHJH6m|ycyyR3e(1*Lpu%Di-DmI<$Ds$;f-TjN3dA?wU(@|vonx3EIX zvO;F{Y?*^0Rg9YWI(pgRlx^)M)8_linWXm9eri4t%5Z%1yno}DEvqY6k$yKOSQ2ZhtlABUwteQ;g#Dy+(+fYbu;gkjV3cE;=xrY2}c4kOd}3t7r&sENjgXy znUD)|0haHPGcN6??4{G-@)Q3IDSjGyXcsp%y_+6S;$Vc0b1NIKkL6@vL;TH&G9EN7 z!BoD~ATT2@UmJydh+b;QsXQ08fM3Lau_Rtxs?@Q(n71U!?Nv#xN`dkTB@}L{v|2f~ zgd>}hv_frR+Ls-@{0!_EqclpDX?LgXu=nMP?v+pj=2soU@eGc2WSy|LF$`+MaHO@1 zhDpSL?PBePnGXhy870Ohpxc%^nZ#OSu?|iPxTCMka)~2?Ex#DWTfP}^Gp|*Or+N($ zQ6$-*5s=d@(4Fi4GY2wjvX^gYIPH`g;WZpM7$N}#q!p%7H-OJ%`!2m`J3J?&cy|* z5T_-Ly24xvz21zOCgLSfhT}vAfoj*h`pQiA69$4zq^jA&u)cD-qqJjDjvT#D=(ROt zD`W%1>hrz84DCcI9d^@6MUhmk8W?HsTx`teYYH#gQ21=SvA-eIHqgLB&GnUAAMu_5 zhMo$13J`_-s2Yn01^OamS(fznfc$a!R1(H;*&bty{za2&E=b0lC_ z%Vjwk`jnU}N?NVHPDWvp(0-JcnKYG6Qh#}3(WtM1l$&EKP}dD(!(@PWm8E$}?9QLS z`NQCgQ-+k0SGzeeYrAE?tH*G^c+~!3-FUc{y4k0MjiyZnpTtjL z381SjY6g#q`z-qOVTxHSg;*tz&@|R@ zbd<#4L`k4$XfR3evmym5l>K0ejVsGDFsJt0>nQEKmyeC%{8MAi_D_t0IFy7QY4g-n z*$FU?>hw$S?UfVN+v&=N-w2r(;tEv2<~B`zshv9{vDDNLdT{+P9!98t*glCKUPD*c zqphqt*%2Vls{*U$`>20h>&v0hlUialwQWKswd1Mh?w@ax?Z#WBTMn)@-DnuW*N>;M zVH~ss-kIoe(1U}Z!hM!y8iL+XL+S6M#faI!ejL(TSO=|o7xF|tkSf|x?e#X0bh(yg z>p(Vw%Re_n;~=SfZFO#@P@mpona|<`%Ski&e!|2jR0Q;6xol8{U8AU#^wb9#&B+7# zFQZX!D6nbNT1;be>MZr)NcW1__de&zjTwb~`!Z-7WkDm4pF{!gn`r3Jap-PQM>E@r zEtY#WVi#wgfC=2Vi2}^BNerB=P)oDU%s;gcZ<2n2jh#PeEkKPh&SCM{xw7IxXc4{r<4&%*uV_Gv8Q+3Qhh%eVQI1h(0MS(iKGBXp@ z6JVyswUL`@^?^OSq*zJitjTufqqxBRw!Q#$?Drtd7;gdU#Nm*4Mi!epVqr>5$U&Oa zDx`Tb==O!0LY8$mGYyNqdv?$sY1`^oAJd?WeZb5M-Rt{QDKQwf%?mHfFM8pjTuNKu z7o8$CEe4$I+wroMqnh}r8MYbh^YK^)m4ZA`8qw`*J*DF{V49W0-o5*5CuTLUw*!4# zr>QGXH0V%>g7BeW@*(i+snwxfE1t_hCK*TkJoJ(gf>UXGAraOGZ{L=Z)JR8}tY#%UPMNjFrCF~oCZ!m7FJr`mg`l^aM7h@ij z`rIV83S-NA9C9XNDn-Ar-F~HH!LY(76AzC39mvBsLOCR7 z)+%U0;re8Yg>L1nrq@oAMq3p_M-?*+HGLz+$oU%8<*UZKYIchR6de_7?}31DT)og`sIzEIud*k%-vx2vN1K0@Qi6W~ z;UFffX2pQKL3I%%fMh_*&1>f}4%qGC$Lhu6icketpd5QtG+F3A4P?SeuaZ7zx=X@~ zCKHk-Uuxd{n%SPr6hL+phIOEJb*hED6U0d^Gf{%Li{Nq2Kunl+&fV_G58vOaEOL3k50-xR_JxGz3#Y-H5vu<;srb1&&Y@gH4W^p5(6H zYqP+udfjjY@l`EIZ?#>cWi#mhN(45K5!Y}hT)iK^XQYGtXo??=q#HAZ5cqwZ{YJyvsQjT;hwxjKG~P+9F4rG?~i9wQJmdgjF*-( zOV#UgMn!x|viNZH7UgcRJ0boAhZ;p{Q=4=5sWK2hbM}=J-}O`hG4d9%%e3P=!DD-b zawq6f5-tv!JEhR=BN=H*?t z_If)wCJljVi(fKcWW$QUpZy|b)mI5IbrJgh@AU!gcp?`)tZ4}QT4zrM1D zE^&Zn$mLu4uCz*((eyPQogGX~UWdVBe7qZ@Ya`khCn;Roe~M+_OpWRE5g|4^@_m%R zoW@0zD(O|NN@dG1jl;ztVf*%)#nsa3AkK;U9}=gw4u*gIDpO$LEZ>?(An6fYs<8;*w~0zLKZkzj`%#s4Dw@oz-@WA&41ie9!O%NmtJ!8VqLle z{mt9ct`*G6U7`ovlEgM8Ob6CoWkqaX=8(?@W_;f1C6g$$(|F=gvb6$D!4Eo{%flDi zPZzsm`D9-lP)A4d(as?3mxOZ~l{f=4^tK^`bYb+wzd?LmA}=+BP|zR`miv6<$Fh&r z$Joi|CNv5Ky4HK?uH!Vp5`qrCGnrFaWeUgeHcuC%b`k05IO$b$@^B|#hAkXP4E;XA zMW{b($tup}Tm3hX)Fhpn={dyv6sk-iZcg68H6cj7Vam|vd>w8yHEuG*(`trkHVm1T z)9zkk@?o&|k7g}yGP<33NU<#eUxH&;{N#hS63$`*1+Tn~oF{l90@*HaB#DNzIVWe| z@JJ1PoU;_C5_5C9f*2zG&{m}nml)P$52s|#S;7qm1Cw`;3+3;d(5wi`QnHhVqN8Ok z_t9SMM2|9G$y31@dG2Td|EfTgi>jt*r$rN;^?Dg-Ru*+ok)@gE{Z#0sykHAfjSv+u z4pk|3&n9`I3^qr07B6ykI$e5T6;OrgXOs;8Z+FX3h)Y$ds5v-RO$bYBZ#Yt1I4*#k zH^?+YK6P6^qM>e}7I*@mxZ+^321%#BmN3qh*v-)hnXoyI&rBxJASagLZ9XcZpD)C$~!S=cnRMT(r0mO1)9 zVyyKv?tkl-542I>%2KL$v(MRi7k^m^OeN8rN3LCV&J8QmOA5E|e6hw)WIf7@NL3PG zJEIg3foR7ew7h}8Y0fD{vxMIxG0ODuM6ro3fM_(4YDVO!EsI?zwsOEDg-C5%L;kE% zd}g+U4Xw|NZQeOE`tHGfhBgUGy%dYKv;2@S=?hsv2}aKWaQ|vK+UVfjCG&nVkQaUO zZGDIVmO)i2-D+Qol?hB@2M2m(^9V2rIXi<}$n759e9{KQL0d|YeBT}|)v{!m9%pyG zQi?(Uh=GKt-kx;C{5-nuuFt#iDTWeJHVP3d67OK~CF~2!0?xdWM_Z8LMe^XPjB_;^ zRjo;3Bu%yeC8`-SPpm%k7JU$l{T7D9_L&Bj!%#gjpSC<>vEW-QI#}@$^|0#L801gX zM21{}j5Re(BI4GxEM!JyX+(JHD!B4T?Kt23U$I1>_oX5+zjw=D6548v=0bx(%5nlR z`G!Su*&opq)w)5Qx>|rd^P9p0B!#I!d)O0^bsXy4MT-h^B&an zT&hJ+4N@_Uy1qvoTuBrSrAubJG<|(Fy+hzB|R5B8)Q{XHddbNgL0yaQ%e3oTLY#+!pzjN}(n7xHrUFzGr0dTGZJVThU%RY3H|s z;hhqPbHCB*&=#2U@o0BexSg$qAXx9Tk^13HJ$?fgy+@(P_ZI17liCVmndH!8+I?#b zI}ST+ZGJd45Pn~gyai!7Rq=1umAa~vlei?>l~POc*dp`u_jn4f9!3009cE>kb_ZC~ zk}edI3O{;BN?r4O+7#uo9fMdz8#x(Wok^tW(s3ON3e!6tu#}Wdvy?paa(IK+80Nd$ zTp{jt>|By+a`m}-4s8Kiq_a>sk*XfzTrrbmcZ;d3XB+~Xhh*Z>kM|q<*!rF&RlR9X z<%wx|5wntIqjvYFi3Z#~v5CFnuR4R!9@h@{%ALLH;&((;6J&c%_>N%vOP4mbjyX>% zAPcXuHr`vl<;pMTR$tI`a;z^N)7Z{*Kzk?)Ym+$iVy?N5YZtWzX5GSkBD@^_m%|l?>l8;#$nbby= z70Hd{fj~Bjk>1*e^F+WldSI)>1)sXdZdfiyZ5CwPf~g;|lO4`59z(I+vlFjPW`F3Y za^V!@dV#rHn%>B*DlymX*?I@Uo?zeK$-i4{-_F$Et4|)a7Q2$+pK>@8`Y|q96rD>#oIDVK*+lpFDe%FLJ{&`C*WK`Dwpi&zd~f zGP*()xIf$tKFlt{L9>&tvpRZy`brL)(|KE&8Zr2QQR<3Rds1t;FT=Jy+!Z zGB)k4(aw6zN`miKm^@M~k+%feU-zDP{<>kR;cA_d0Pu_U13Wyx@b3J}!EX4cAm@MY zk*X~Cyi-Ab5?&gZ60BD0k6IyCnr2NhVhbXia4iYnB9_8jBC`{-Rfj^fz?X?JNthf6 z)ex7+od_%}1WilwVhHywV1y**Nn*LZ7<*^acCG@~!NGtbG228(1K2rbyW!aLG-;mV zd3xyQ0luYOmB~R2f?@E5i$K|yOR^*L{m@#~laJpmozuHgLR=j%ET-96NT@5rt#miKK(YEQbW#J;BlX9pFw&ERcRz=`p~tW>_eq1$YOWBx#9 zN%&zLyK4Q_)OwvdcI*Uw87l0|NAOjTLq}`!a$2-^3JBrAerFf{UA} zSV~|uhRq0VI^@^CF%hqX*l&N=z}y)Xc^G6JEw(>0OO{c^B*CRKC44_78X}njD&;zU zZd@9^$8-dFA;s@Ll%XPFq9}oCVN=_?lR+H7A1?)o=T#YS&3=Yy&|r3vF7JHn2%H$R zLcS8weK~f#;7TmYp-;1)2(&`%c{pSod3}u=MCiykRi*h+&W@GW=koM4v@Qa~$UwqG zsBg1DjpFv&Qb!gcK|%?jofFwrPy(IjACKcmuY3_>r1Amcw9L8LTw>px-L{}K87fV* zqFg2FKsiu-iY;~_=lnH=qvLRk?^6TiheUO*lL2On%gOXv(3!I4Y3t%xT%mg5aUdGdG4GpU1!wY>+`;RSnI86o zn&Uny$$U3ln5%0R16umR-^s_BpH#X?d|9iRFL8QZ zY!)PEdakEjt$w%OpvCk&ium?>ml|dx9vGao6TEN)&O9H zQ?(!L)@p|}xT>8Z=W^&O$Zh^EMxH92H|JiUJfGhZ8J_O4Ff=eJBRxX!BwZjf_XwXF zJt}sNpF2Q;x7)F19F%M`M54yF&bexYwu60E*rTb5K^|F8@I!v|QyC{#@OKg7&R7QGaU(D2C`GEb(UO4cZ*AXwIW7Z(dm!` z%bC5Z{ryOc26$!#7F~wW7OhJtp`c&p(Rfw^n84|Hgca;NSPNyMNY?2G+XnPDHnS%aNeG)n3MPjio~E`y@mAG3_QpCxUm0pk2@F4T>kS0 zkMNE=0&l4MJ>z>?!_&67R!}mRce%|P5No^v`U(2SVB1b~($#_bn_zL@Eo2EL_vWgk zx|A{sV&cwKEVG*c3U^oZZIq!^p zQa){S$s7xy>)Lxo>gmj|jrCZu##a*0GwMRW?Lim%KpU=ARsD`;)4MGIMw?hHpVKbm z)q?1TUIboH@npEjIo(r#3ehHO6r4@mEuw3JGj>;hW+fiqtEf%1bep)SZFsI}9v z0+~%Q@eEAQIDSt*?pOyI{Aydc2;H6`-Y9X!Xn%!D^ype2xdR~GH?f?)yNIn24Thn(7Y?{F`=H!D(JNs=g!Wd zR0k-q7s!&r9NtR(8?)@eY6k4KFjGS(z(eRR^M+y<&HGSnEngi>cwAW7eyN%=249!{ z2GT#zh{1d1`tI~{L!tcUz6F^h``YX~43W08_9Jp$Kwy-q0DCKo;GTN%H=ph?fLBxE zESz;_nFi__#r;Q|PUT`9qMol*kz5Ba2`VND1GR3Z05uO;L%C@?+|IX@n-mPk6yUr( zG3Exrl8;1r*g5Znd}ShqS4gq1YCb@~3C9{;X|Bb5rk8k-*Lsb-#s@0Y&qoWiBEZ-N za%#P9B%GkNnriCBNLO`gGX$wFnL%DW6_-tgf9vebF)eCe0NKBXq>d%tvk-n;Zt?&- zel6=`<$Qk?Ur~nBLSGf68L~ts*Qj|J+ynA`&wbyTj;kB*j&j8o>xPUVvlz-o~`P;bu$04{sM)ybs zjei{pX=tQ6!7tQA;v+@Pr5XxDZIdknp~ExlDFE}g5#Ue@vUEvbp@R2;8Yk|!%?TBc z5%jtSY@{Dk7b1yyre?A|WS)7hu`zu5;rZj0E<6R9p{%T&B%UAt+k4vVyq%!1bTP_; znD<$IRFuSa8s29gnkYWqY}XWQc7%aLA$W{f+Ntmr)eK*!tbPqBQ3*JrqS!Bi>ekmD z-heW0@lN)u9i$YfbdRcv*r6{Z6z@XNR^wyTnOB6 zXEL^?7a4Fsi*V!cOW3ApFxU_3J|v#AD4Nir@87vnYMsWKZ z*`{%!koSx#jm_z`mNbps*RD}&4{Sf^DF^r!$g#~`LE<{cK%z5dbX7Gz}Lkv#VyIC(58=rn|46|`NWI5CJqqK-HiEk8*PI{qzwF_3*TLEM{Bh?mN9h+_K{Bp;)37iNA|PO;G)#!-5QEhjvSUQ0#}s3`f@CaW>Zkz z=8*Zn545hcPzWM0uy>MFy}C6q^_-sL4+@AhuekawJaVnJzkpRCxSzT|7QIh2CwaR} zlz=!37KLyT6&Qs{9;_4kVW*wvYBq$O6hD~LcQHWUM|>vo8WI)jW5s-!<5%M&ZE}g5 zrWq`#wfZ7hRi)K)4CQvLi2P+UT5LL>0Snl!PMsyvPCfp;4AbSxnv@ihOcxQZV%&gWnR5;M3Gz8 z3PeJg682V6)pam0?CMj3u^^~o4v^660+Afd9@%~sB;T!9;#MC`y=yA^a2VP6PRv~^ z>L;sUE2bT~O|M5_O}?b&S;MhD_A`|%Y2{E0`yzdb`{Yms&UUpfH~czuEN`<0Bb6L6 z(cyuHH%rL`Qk;C(p!$swGKGWx5CvTa)C|Zep>0veW!-z`Pr0cyj#QwdlzAK_rhtE` z^VFeAxh;;>e}MdT5&HH=w+a&AQ6d1YpUIj3Erkv^vHQ<5=sPdP&mkZn0M+>b*Khi*7y%G;Dp?tN(SKG#@^&_oIn5MKQ#cVF@Gwb0rx*^{96+KpQwKJ z!E-qR-2SQJzvb%x#(d_ko_q#qSt)255SuNTm;X!fIC${Aj~hI1px{HmNt5Z|B<142{>fK?(i1SO}v2iGX4dS z6W|&7CqTf+;p)cc;Fjizl8S=p@r85bmb1fWPTo^e=bXa zm+2R+1xOoPIynI3L4?gLjra@<01Q%k)_VV!P5mVSNQwK3CZNOR03H5U;|K%1{=Xm) zvDX7+a8v?F35wcS8A;mMSUB1Kx@(Tg&Etyz!tsoNmXbd=9B@a6{}0grPCNC}_I{1K zcdY7A3P4!`TmYay6&%1X_(hY&{$q8&#>*^2yZr*_V`e~ZhQH!LQvVvy+QCuJ((=FA za3*v!FCpMfy#{k8dyTa*D02neux`1wJ8E{|4=U%3tyl@F&1eEBje~ z<|uhCwgA9Cy;MJAcV1S0nX%-#a`xXV|0ik0f1eG$gnyZZ;u)UY^lxqZ5B%?}BwiA| zRFZ!t8n^r#(VyD?Uv%YP!oQS6e}*@*{wMesljWDNFO|TbVS8=<3HHx^hL@NxWo4f+ zN1Xl%^N%Qi|Mq2kDd75y+T{EjsQ+Eg^=0#4ic&rkNxALt}nsf=eTz3|_l`Ul~R zmrO5Z37(mBqJD$v4|CxArAWa`s+ZB=&r}MrzfA@BzS#a*+3h9C%i!8)60?NgCi&xi z{gd3tOO}^WoX;%ANx#kV=a|ly1TQ1#o(UvU|33--SC74nX?mt21gzR#jB$VZy#M>7 z_CNdTWpK+gzDL$?;Qw=|%gcUy84K`C)(lvW{I4JL>q*wj9q4DwzPOF^WS)0PCNf(M*m|Nf9ZL7 zrors`zbV~+^TYh7&HwSb{Ml*p)9dnFtN>vD%?BeZ0SZ_L{S5e{2hstYLKp!2EfCQE E17(ftEC2ui diff --git a/kuzzle-sdk-java/.project b/kuzzle-sdk-java/.project new file mode 100644 index 00000000..1a097e23 --- /dev/null +++ b/kuzzle-sdk-java/.project @@ -0,0 +1,23 @@ + + + kuzzle-sdk-java + Project kuzzle-sdk-java created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/kuzzle-sdk-java/build.gradle b/kuzzle-sdk-java/build.gradle new file mode 100644 index 00000000..70d4d8d0 --- /dev/null +++ b/kuzzle-sdk-java/build.gradle @@ -0,0 +1,54 @@ +import org.gradle.api.JavaVersion + +plugins { + id 'jacoco' + id 'java' +} + +allprojects { + repositories { + jcenter() + } + apply plugin: 'idea' + apply plugin: 'maven-publish' + apply plugin: 'java' + apply plugin: 'java-library' +} + +group 'io.kuzzle' +version '3.0.0' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.neovisionaries:nv-websocket-client:2.9' + implementation 'com.google.code.gson:gson:2.8.5' + testImplementation 'junit:junit:4.12' + testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0' + testImplementation 'org.mockito:mockito-core:1.9.5' + testImplementation 'org.skyscreamer:jsonassert:1.5.0' +} + +jacocoTestReport { + reports { + xml.enabled = true + html.enabled = true + } +} + +check.dependsOn jacocoTestReport + +compileJava { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +test { + useJUnit() + + maxHeapSize = '1G' +} diff --git a/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.jar b/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..87b738cbd051603d91cc39de6cb000dd98fe6b02 GIT binary patch literal 55190 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 z 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 { + + + @Override + public void write(JsonWriter out, ConcurrentHashMap map) throws IOException { + if (map == null) { + out.nullValue(); + } else { + out.beginObject(); + Iterator> iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + out.name(String.valueOf(entry.getKey())); + writeObject(out, entry.getValue()); + } + + out.endObject(); + } + } + + @Override + public ConcurrentHashMap read(JsonReader in) throws IOException { + JsonToken peek = in.peek(); + if (peek == JsonToken.NULL) { + in.nextNull(); + return null; + } else if (peek == JsonToken.BEGIN_OBJECT) { + KuzzleMap map = new KuzzleMap(); + Object key; + Object value; + + in.beginObject(); + + while(in.hasNext()) { + key = in.nextName(); + value = readObject(in); + if (!map.containsKey(key)) { + map.put((String) key, value); + } else { + throw new JsonSyntaxException("duplicate key: " + key); + } + } + + in.endObject(); + + return map; + } + return null; + } + + private void writeObject(JsonWriter out, Object value) throws IOException { + if (value instanceof Number) { + out.value((Number)value); + } else if (value instanceof Boolean) { + out.value((Boolean)value); + } else if (value instanceof String) { + out.value((String)value); + } else if (value instanceof ArrayList) { + out.beginArray(); + Iterator + iterator = ((ArrayList)value).iterator(); + + while(iterator.hasNext()) { + writeObject(out, iterator.next()); + } + + out.endArray(); + } else if (value instanceof ConcurrentHashMap) { + out.beginObject(); + Iterator> + iterator = ((ConcurrentHashMap)value) + .entrySet() + .iterator(); + + while(iterator.hasNext()) { + Map.Entry e = iterator.next(); + out.name(e.getKey()); + writeObject(out, e.getValue()); + } + + out.endObject(); + } else if (value instanceof Serializable) { + try { + writeObject(out, ((Serializable)value).toMap()); + } catch (Exception e) { + throw new IOException(e); + } + } else if (value == null) { + out.nullValue(); + } + } + + private Object readObject(JsonReader in) throws IOException { + switch(in.peek()) { + case NUMBER: + String number = in.nextString(); + return new LazilyParsedNumber(number); + case BOOLEAN: + return in.nextBoolean(); + case STRING: + return in.nextString(); + case NULL: + in.nextNull(); + return null; + case BEGIN_ARRAY: + ArrayList array = new ArrayList<>(); + in.beginArray(); + + while(in.hasNext()) { + array.add(readObject(in)); + } + + in.endArray(); + return array; + case BEGIN_OBJECT: + KuzzleMap map = new KuzzleMap(); + in.beginObject(); + + while(in.hasNext()) { + String key = in.nextName(); + Object object = readObject(in); + if (object != null) { + map.put(key, object); + } + } + + in.endObject(); + return map; + case END_DOCUMENT: + case NAME: + case END_OBJECT: + case END_ARRAY: + default: + throw new IllegalArgumentException(); + } + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java new file mode 100644 index 00000000..7af35c7b --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java @@ -0,0 +1,30 @@ +package io.kuzzle.sdk.CoreClasses.Json; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.concurrent.ConcurrentHashMap; + +public class JsonSerializer { + private static Gson gson; + + static { + gson = new GsonBuilder() + .disableHtmlEscaping() + .disableInnerClassSerialization() + .serializeNulls() + .registerTypeAdapter( + ConcurrentHashMap.class, + new ConcurrentHashMapTypeAdapter() + ) + .create(); + } + + public static ConcurrentHashMap deserialize(String rawJson) { + return gson.fromJson(rawJson, ConcurrentHashMap.class); + } + + public static String serialize(ConcurrentHashMap map) { + return gson.toJson(map, ConcurrentHashMap.class); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java new file mode 100644 index 00000000..da2fe35e --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java @@ -0,0 +1,251 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * CustomMap is a Class that extends ConcurrentHashMap to be ThreadSafe + * and that has the purpose of giving a wrapper on top of ConcurrentHashMap to easily + * manipulate them. + */ +public class KuzzleMap extends ConcurrentHashMap { + + /** + * Convert à ConcurrentHashMap to a CustomMap + * @param map ConcurrentHashMap representing JSON. + * @return a CustomMap instance + */ + public static KuzzleMap from(ConcurrentHashMap map) { + if (map == null) { + return null; + } + if (map instanceof KuzzleMap) { + return (KuzzleMap) map; + } + return new KuzzleMap(map); + } + + /** + * Create a new instance of CustomMap + */ + public KuzzleMap() { + super(); + } + + /** + * Create a new instance of CustomMap from a ConcurrentHashMap. + * @param map ConcurrentHashMap representing JSON. + */ + public KuzzleMap(ConcurrentHashMap map) { + super(); + Iterator> it = map.entrySet().iterator(); + + while(it.hasNext()) { + Entry entry = it.next(); + this.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public Object put(String s, Object o) { + Object obj = null; + if (o != null) { + obj = super.put(s, o); + } else { + obj = super.put(s, new Null()); + } + if (obj instanceof Null) { + return null; + } + return obj; + } + + @Override + public Object get(Object key) { + Object value = super.get(key); + if (value instanceof Null) { + return null; + } + return value; + } + + @Override + public Set> entrySet() { + Set> entrySet = super.entrySet(); + return entrySet.parallelStream().map((Entry entry) -> { + if (entry.getValue() instanceof Null) { + return new KuzzleMapEntry(entry.getKey(), entry.getValue(), this); + } + return entry; + }).collect(Collectors.toSet()); + } + + /** + * Check whether the key value is null or not. + * @param key a String representing the key. + * @return true if the value is null. + */ + public boolean isNull(String key) { + return super.get(key) instanceof Null; + } + /** + * Check whether the key value is a String or not. + * @param key a String representing the key. + * @return true if the key is a String. + */ + public boolean isString(String key) { + return super.get(key) instanceof String; + } + + /** + * Check whether the key value is a Boolean or not. + * @param key a String representing the key. + * @return true if the key is a Boolean. + */ + public boolean isBoolean(String key) { + return super.get(key) instanceof Boolean; + } + + /** + * Check whether the key value is a Number or not. + * @param key a String representing the key. + * @return true if the key is a Number. + */ + public boolean isNumber(String key) { + return super.get(key) instanceof Number; + } + + /** + * Check whether the key value is an ArrayList or not. + * @param key a String representing the key. + * @return true if the key is an ArrayList. + */ + public boolean isArrayList(String key) { + return super.get(key) instanceof ArrayList; + } + + /** + * Check whether the key value is a ConcurrentHashMap or not. + * @param key a String representing the key. + * @return true if the key is a ConcurrentHashMap. + */ + public boolean isMap(String key) { + return super.get(key) instanceof ConcurrentHashMap; + } + + /** + * Return the specified key value or null if the value is not a String. + * @param key a String representing the key. + * @return The String at the key or null + */ + public String getString(String key) { + return isString(key) + ? (String) super.get(key) + : null; + } + + /** + * Return the specified key value or null if the value is not a Boolean. + * @param key a String representing the key. + * @return The Boolean at the key or null + */ + public Boolean getBoolean(String key) { + return isBoolean(key) + ? (Boolean) super.get(key) + : null; + } + + /** + * Return the specified key value or null if the value is not a Number. + * @param key a String representing the key. + * @return The Number at the key or null + */ + public Number getNumber(String key) { + return isNumber(key) + ? (Number) super.get(key) + : null; + } + + /** + * Return the specified key value or null if the value is not an ArrayList. + * @param key a String representing the key. + * @return The ArrayList at the key or null + */ + public ArrayList getArrayList(String key) { + return isArrayList(key) + ? (ArrayList) super.get(key) + : null; + } + + /** + * Return the specified key value or null if the value is not a ConcurrentHashMap. + * @param key a String representing the key. + * @return The ConcurrentHashMap at the key or null + */ + public KuzzleMap getMap(String key) { + return isMap(key) + ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) + : null; + } + + /** + * Return the specified key value or the def value if the value is nul or not a String. + * @param key a String representing the key. + * @return The String at the key or def value + */ + public String optString(String key, String def) { + return isString(key) + ? (String) super.get(key) + : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a Boolean. + * @param key a String representing the key. + * @return The Boolean at the key or def value + */ + public Boolean optBoolean(String key, Boolean def) { + return isBoolean(key) + ? (Boolean) super.get(key) + : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a Number. + * @param key a String representing the key. + * @return The Number at the key or def value + */ + public Number optNumber(String key, Number def) { + return isNumber(key) + ? (Number) super.get(key) + : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not an ArrayList. + * @param key a String representing the key. + * @return The ArrayList at the key or def value + */ + public ArrayList optArrayList(String key, ArrayList def) { + return isArrayList(key) + ? (ArrayList) super.get(key) + : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a ConcurrentHashMap. + * @param key a String representing the key. + * @return The ConcurrentHashMap at the key or def value + */ + public KuzzleMap optMap( + String key, + ConcurrentHashMap def + ) { + return isMap(key) + ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) + : KuzzleMap.from(def); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java new file mode 100644 index 00000000..a529fa78 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java @@ -0,0 +1,64 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class KuzzleMapEntry implements Map.Entry { + final String key; + Object value; + final ConcurrentHashMap map; + + public KuzzleMapEntry(String key, Object value, ConcurrentHashMap map) { + this.key = key; + this.value = value; + this.map = map; + } + + public String getKey() { + return this.key; + } + + public Object getValue() { + if (this.value instanceof Null) { + return null; + } + return this.value; + } + + public int hashCode() { + return this.key.hashCode() ^ this.value.hashCode(); + } + + public String toString() { + return this.key + "=" + this.value; + } + + public boolean equals(Object object) { + Object key; + Object value; + Map.Entry entry; + + if (!(object instanceof Map.Entry)) { + return false; + } + + entry = (Map.Entry) object; + key = entry.getKey(); + value = entry.getValue(); + return key != null && (value == this.value || (value != null && value.equals(this.value))); + } + + public Object setValue(Object value) { + if (value == null) { + Object oldValue = this.value; + this.value = new Null(); + this.map.put(this.key, this.value); + return oldValue; + } else { + Object oldValue = this.value; + this.value = value; + this.map.put(this.key, value); + return oldValue; + } + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java new file mode 100644 index 00000000..d8e458da --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java @@ -0,0 +1,8 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +public class Null { + final int hashCode = 572487463; + public int hashCode() { + return hashCode; + } +} \ No newline at end of file diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java new file mode 100644 index 00000000..ac5c7fa8 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java @@ -0,0 +1,8 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.concurrent.ConcurrentHashMap; + +public interface Serializable { + void fromMap(ConcurrentHashMap map) throws Exception; + ConcurrentHashMap toMap() throws Exception; +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java new file mode 100644 index 00000000..1cde349c --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java @@ -0,0 +1,57 @@ +package io.kuzzle.sdk.CoreClasses.Responses; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Maps.Serializable; + +import java.util.concurrent.ConcurrentHashMap; + +public class ErrorResponse implements Serializable { + + public ErrorResponse() { + + } + + /** + * Response status, following HTTP status codes. + */ + public int status; + + /** + * Error message + */ + public String message; + + /** + * Error ID + */ + public String id; + + /** + * Error stack + */ + public String stack; + + @Override + public void fromMap(ConcurrentHashMap map) { + if (map == null) return; + + KuzzleMap kuzzleMap = KuzzleMap.from(map); + + status = kuzzleMap.optNumber("status", 0).intValue(); + message = kuzzleMap.getString("message"); + stack = kuzzleMap.getString("stack"); + id = kuzzleMap.getString("id"); + } + + @Override + public ConcurrentHashMap toMap() { + ConcurrentHashMap map = new KuzzleMap(); + + map.put("status", status); + map.put("message", message); + map.put("stack", stack); + map.put("id", id); + return map; + } +} + diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java new file mode 100644 index 00000000..16c633b2 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java @@ -0,0 +1,142 @@ +package io.kuzzle.sdk.CoreClasses.Responses; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Maps.Serializable; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.KuzzleException; +import io.kuzzle.sdk.Exceptions.KuzzleExceptionCode; + +import java.util.concurrent.ConcurrentHashMap; + +public class Response implements Serializable { + + public String room; + + /** + * Response payload (depends on the executed API action) + */ + public Object result; + + /** + * Error object (null if the request finished successfully) + */ + public ErrorResponse error; + + /** + * Request unique identifier. + */ + public String requestId; + + /** + * Response status, following HTTP status codes + */ + public int status; + + /** + * Executed Kuzzle API controller. + */ + public String controller; + + /** + * Executed Kuzzle API controller's action. + */ + public String action; + + /** + * Impacted data index. + */ + public String index; + + /** + * Impacted data collection. + */ + public String collection; + + /** + * Volatile data. + */ + public ConcurrentHashMap Volatile; + + // The following properties are specific to real-time notifications + + /** + * Network protocol at the origin of the real-time notification. + */ + public String protocol; + + /** + * Document scope ("in" or "out") + */ + public String scope; + + /** + * Document state + */ + public String state; + + /** + * Notification timestamp (UTC) + */ + public Long timestamp; + + /** + * Notification type + */ + public String type; + + @Override + public void fromMap(ConcurrentHashMap map) throws InternalException { + if (map == null) return; + + KuzzleMap kuzzleMap = KuzzleMap.from(map); + + room = kuzzleMap.getString("room"); + result = kuzzleMap.get("result"); + error = null; + if (kuzzleMap.isMap("error")) { + error = new ErrorResponse(); + error.fromMap(kuzzleMap.getMap("error")); + } + requestId = kuzzleMap.getString("requestId"); + if (requestId == null) { + throw new InternalException(KuzzleExceptionCode.MISSING_REQUESTID); + } + status = kuzzleMap.optNumber("status", 0).intValue(); + controller = kuzzleMap.getString("controller"); + action = kuzzleMap.getString("action"); + index = kuzzleMap.getString("index"); + collection = kuzzleMap.getString("collection"); + Volatile = kuzzleMap.optMap( + "volatile", + new ConcurrentHashMap<>() + ); + protocol = kuzzleMap.getString("protocol"); + scope = kuzzleMap.getString("scope"); + state = kuzzleMap.getString("state"); + timestamp = (Long) kuzzleMap.getNumber("timestamp"); + type = kuzzleMap.getString("type"); + } + + @Override + public ConcurrentHashMap toMap() { + ConcurrentHashMap map = new KuzzleMap(); + + map.put("room", room); + map.put("result", result); + map.put("error", error); + map.put("requestId", requestId); + map.put("status", status); + map.put("controller", controller); + map.put("action", action); + map.put("index", index); + map.put("collection", collection); + map.put("volatile", Volatile); + map.put("protocol", protocol); + map.put("scope", scope); + map.put("status", status); + map.put("timestamp", timestamp); + map.put("type", type); + + return map; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java new file mode 100644 index 00000000..f01c73cb --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java @@ -0,0 +1,100 @@ +package io.kuzzle.sdk.CoreClasses; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @param The object type that the task return. + */ +public class Task { + /** + * A countDownLatch used to lock the future. + */ + protected CountDownLatch countDownLatch; + /** + * A completable future. + */ + protected CompletableFuture future; + + /** + * The object instance to return. + */ + protected AtomicReference atomicReference; + + + /** + * Initializes a new instance of the Task. + */ + public Task() { + atomicReference = new AtomicReference(); + countDownLatch = new CountDownLatch(1); + future = CompletableFuture.supplyAsync(() -> { + try { + countDownLatch.await(); + + return atomicReference.get(); + } catch (InterruptedException e) { + return null; + } + }); + } + + /** + * @return The associated CompletableFuture. + */ + public CompletableFuture getFuture() { + return future; + } + + /** Set the exception of the CompletableFuture. + * @param exception + */ + public void setException(Exception exception) { + future.completeExceptionally(exception); + } + + /** + * @return true if future is cancelled. + */ + public boolean isCancelled() { + return future.isCancelled(); + } + + /** + * @return true if the future is done. + */ + public boolean isDone() { + return future.isDone(); + } + + /** + * @return true if the future has been completed exceptionally. + */ + public boolean isCompletedExceptionally() { + return future.isCompletedExceptionally(); + } + + /** Set if the future is cancelled. + * @param state + */ + public void setCancelled(boolean state) { + future.cancel(state); + } + + + /** + * Unlock the future. + */ + public void trigger() { + countDownLatch.countDown(); + } + + /** Unlock the future and set the object. + * @param object + */ + public void trigger(T object) { + atomicReference.set(object); + countDownLatch.countDown(); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java new file mode 100644 index 00000000..7cf5e829 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java @@ -0,0 +1,74 @@ +package io.kuzzle.sdk.Events; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +public class EventListener { + + /** + * Set of registered callbacks. + */ + protected Set callbacks; + + /** + * Initializes a new instance of the EventListener. + */ + public EventListener() { + callbacks = ConcurrentHashMap.newKeySet(); + } + + /** Register a callback that takes a parameter. + * @param callback + * @return If successfully registered. + */ + public boolean register(final Consumer callback) { + return callbacks.add(callback); + } + + /** Register a callback with no parameter. + * @param callback + * @return If successfully registered. + */ + public boolean register(final Runnable callback) { + return callbacks.add(callback); + } + + /** Unregister a callback that takes a parameter. + * @param callback + * @return If successfully unregistered. + */ + public boolean unregister(final Consumer callback) { + return callbacks.remove(callback); + } + + /** Unregister a callback with no parameter. + * @param callback + * @return If successfully unregistered. + */ + public boolean unregister(final Runnable callback) { + return callbacks.remove(callback); + } + + /** Triggers every callbacks that have a parameter with the given object. + * @param obj An Object. + */ + public void trigger(final T obj) { + for (Object callback : callbacks) { + if (callback instanceof Consumer) { + ((Consumer)callback).accept(obj); + } + } + } + + /** + * Triggers every callbacks that doesn't have a parameter. + */ + public void trigger() { + for (Object callback : callbacks) { + if (callback instanceof Runnable) { + ((Runnable)callback).run(); + } + } + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java new file mode 100644 index 00000000..91ad7d5f --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java @@ -0,0 +1,41 @@ +package io.kuzzle.sdk.Exceptions; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +/** + * Passed to async tasks when an API request returns an error. + */ +public class ApiErrorException extends KuzzleException { + /** + * Kuzzle API stack trace + */ + protected String stack; + + /** + * Kuzzle API error unique identifier + */ + protected String id; + + /** + * Initializes a new instance of the ApiErrorException + * @param response Kuzzle API Response. + */ + public ApiErrorException(Response response) { + super(response.error != null + ? response.error.message + : null, + response.status); + if (response.error != null) { + this.stack = response.error.stack; + this.id = response.error.id; + } + } + + public String getStack() { + return this.stack; + } + + public String getId() { + return this.id; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java new file mode 100644 index 00000000..47227103 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java @@ -0,0 +1,15 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Thrown to close ongoing API tasks, when the connection has been lost while + * waiting for a result. + */ +public class ConnectionLostException extends KuzzleException { + /** + * Initializes a new instance of the ConnectionLostException. + */ + public ConnectionLostException() { + super(KuzzleExceptionCode.CONNECTION_LOST); + } + +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java new file mode 100644 index 00000000..25d7d2b8 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java @@ -0,0 +1,19 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Passed to async tasks when an API request returns an error. + */ +public class InternalException extends KuzzleException { + + /** + * Initializes a new instance of the InternalException + */ + public InternalException(String message, KuzzleExceptionCode status) { + super(message, status); + } + + public InternalException(KuzzleExceptionCode status) { + super(status); + } + +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java new file mode 100644 index 00000000..b40d76db --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java @@ -0,0 +1,38 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Root of all Kuzzle exceptions. + */ +public class KuzzleException extends Exception { + + /** + * Kuzzle API error code. + */ + protected int status; + + /** Initializes a new instance of the KuzzleException. + * @param message Message. + * @param status Status. + */ + protected KuzzleException(String message, int status) { + super(message); + this.status = status; + } + + protected KuzzleException(String message, KuzzleExceptionCode status) { + super(message); + this.status = status.getCode(); + } + + protected KuzzleException(KuzzleExceptionCode status) { + super(status.getMessage()); + this.status = status.getCode(); + } + + /** + * @return The status code of the exception. + */ + public int getStatus() { + return status; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java new file mode 100644 index 00000000..ba7ad958 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java @@ -0,0 +1,30 @@ +package io.kuzzle.sdk.Exceptions; + +public enum KuzzleExceptionCode { + MISSING_REQUESTID(0, "Missing field requestId"), + MSSING_QUERY(400, "You must provide a query"), + NOT_CONNECTED(500, "Not connected."), + CONNECTION_LOST(500, "Connection lost"), + WRONG_VOLATILE_TYPE(400, "Volatile data must be a ConcurrentHashMap"); + + private final int code; + private final String message; + + KuzzleExceptionCode(final int code) { + this.code = code; + this.message = null; + } + + KuzzleExceptionCode(final int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return this.code; + } + + public String getMessage() { + return this.message; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java new file mode 100644 index 00000000..45e18656 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java @@ -0,0 +1,14 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Thrown when attempting to interact with the network while not connected. + */ +public class NotConnectedException extends KuzzleException { + + /** + * Initializes a new instance of the NotConnectedException. + */ + public NotConnectedException() { + super(KuzzleExceptionCode.NOT_CONNECTED); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java new file mode 100644 index 00000000..032609f9 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java @@ -0,0 +1,14 @@ +package io.kuzzle.sdk.Helpers; + +public class Default { + + /** Return the object or its default value in the case of the object is null. + * @param obj An object. + * @param defaultValue A default value in case your object is null. + * @param Object class. + * @return The object or the specified default value in case the object is null. + */ + public static T defaultValue(T obj, T defaultValue) { + return obj != null ? obj : defaultValue; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java new file mode 100644 index 00000000..a0e0a1e2 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -0,0 +1,292 @@ +package io.kuzzle.sdk; + +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Exceptions.*; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import io.kuzzle.sdk.CoreClasses.Responses.*; + +import static io.kuzzle.sdk.Helpers.Default.defaultValue; + +public class Kuzzle { + + protected EventListener tokenExpiredEvent; + protected EventListener unhandledResponseEvent; + + protected final AbstractProtocol networkProtocol; + + public final String version; + public final String instanceId; + public final String sdkName; + + /** + * Authentication token + */ + protected AtomicReference authenticationToken; + + + /** + * The maximum amount of elements that the queue can contains. + * If set to -1, the size is unlimited. + */ + protected AtomicInteger maxQueueSize; + + + /** + * The minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. + */ + protected AtomicInteger minTokenDuration; + + + /** + * The minimum duration of a Token after refresh. + * If set to -1 the SDK does not refresh the token automatically. + */ + protected AtomicInteger refreshedTokenDuration; + + /** + * The maximum delay between two requests to be replayed + */ + protected AtomicInteger maxRequestDelay; + + protected ConcurrentHashMap> + requests = new ConcurrentHashMap<>(); + + /** Initialize a new instance of Kuzzle + * @param networkProtocol The network protocol + * @throws IllegalArgumentException + */ + public Kuzzle(AbstractProtocol networkProtocol) + throws IllegalArgumentException { + this(networkProtocol, new KuzzleOptions()); + } + + /** Initialize a new instance of Kuzzle + * @param networkProtocol The network protocol + * @param options Kuzzle options + * @throws IllegalArgumentException + */ + public Kuzzle( + AbstractProtocol networkProtocol, + final KuzzleOptions options + ) throws IllegalArgumentException { + + if (networkProtocol == null) { + throw new IllegalArgumentException("networkProtocol can't be null"); + } + + KuzzleOptions kOptions = options != null + ? options + : new KuzzleOptions(); + + this.networkProtocol = networkProtocol; + this.networkProtocol.registerResponseEvent(this::onResponseReceived); + this.networkProtocol.registerStateChangeEvent(this::onStateChanged); + + this.maxQueueSize = new AtomicInteger(kOptions.getMaxQueueSize()); + this.minTokenDuration = new AtomicInteger(kOptions.getMinTokenDuration()); + this.refreshedTokenDuration = new AtomicInteger(kOptions.getRefreshedTokenDuration()); + this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); + + this.version = "3.0.0"; + this.instanceId = UUID.randomUUID().toString(); + this.sdkName = "java@"+version; + + this.tokenExpiredEvent = new EventListener(); + this.unhandledResponseEvent = new EventListener<>(); + } + + /** Establish a network connection + * @throws Exception + */ + public void connect() throws Exception { + networkProtocol.connect(); + } + + /** + * Disconnect this instance + */ + public void disconnect() { + networkProtocol.disconnect(); + } + + /** Handles the ResponseReceivedEvent from the network protocol + * @param payload Raw API Response + */ + protected void onResponseReceived(String payload) { + + Response response = new Response(); + try { + response.fromMap(JsonSerializer.deserialize(payload)); + } catch (InternalException e) { + e.printStackTrace(); + return; + } + + if (response.room == null + || !requests.containsKey(response.room) + ) { + unhandledResponseEvent.trigger(response); + return; + } + + if (response.error == null) { + Task task = requests.get(response.requestId); + + if (task != null) { + task.trigger(response); + } + + requests.remove(response.requestId); + return; + } + + if (response.error.id == null + || !response.error.id.equals("security.token.expired") + ) { + Task task = requests.get(response.requestId); + if (task != null) { + task.setException(new ApiErrorException(response)); + } + return; + } + + tokenExpiredEvent.trigger(); + } + + protected void onStateChanged(ProtocolState state) { + // If not connected anymore: close tasks and clean up the requests buffer + if (state == ProtocolState.CLOSE) { + for (Task task : requests.values()) { + task.setException(new ConnectionLostException()); + } + requests.clear(); + } + } + + /** Registers a callback to be called when the token expires + * @param callback A callback + * @return true if success + */ + public boolean registerTokenExpiredEvent(Runnable callback) { + return tokenExpiredEvent.register(callback); + } + + /** Unregisters a previously registered callback for the TokenExpired event + * @param callback A callback + * @return true if success + */ + public boolean unregisterTokenExpiredEvent(Runnable callback) { + return tokenExpiredEvent.unregister(callback); + } + + /** Registers a callback to be called when a response is unhandled + * @param callback A callback + * @return true if success + */ + public boolean registerUnhandledResponseEvent(Consumer callback) { + return unhandledResponseEvent.register(callback); + } + + /** + * @param callback Unregisters a previously registered callback for the UnhandledResponse event + * @return true if success + */ + public boolean unregisterUnhandledResponseEvent(Consumer callback) { + return unhandledResponseEvent.unregister(callback); + } + + /** + * Triggers the TokenExpired event + */ + public void dispatchTokenExpired() { + tokenExpiredEvent.trigger(); + } + + /** Sends an API request to Kuzzle and returns the corresponding API + * @param query Kuzzle API query + * @return A CompletableFuture + * @throws InternalException + * @throws NotConnectedException + */ + public CompletableFuture query(ConcurrentHashMap query) + throws InternalException, NotConnectedException { + if (query == null) { + throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); + } + + if (networkProtocol.getState() == ProtocolState.CLOSE) { + throw new NotConnectedException(); + } + + KuzzleMap queryMap = KuzzleMap.from(query); + + if (queryMap.contains("waitForRefresh")) { + if (queryMap.optBoolean("waitForRefresh", false).booleanValue()) { + queryMap.put("refresh", "wait_for"); + } + queryMap.remove("waitForRefresh"); + } + + if (authenticationToken != null) { + queryMap.put("jwt", authenticationToken); + } + + String requestId = UUID.randomUUID().toString(); + + queryMap.put("requestId", requestId); + + if (!queryMap.containsKey("volatile") + || queryMap.isNull("volatile") + ) { + queryMap.put("volatile", new KuzzleMap()); + } else if (!queryMap.isMap("volatile")) { + throw new InternalException(KuzzleExceptionCode.WRONG_VOLATILE_TYPE); + } + + queryMap.getMap("volatile") + .put("sdkVersion", version); + + queryMap.getMap("volatile") + .put("sdkInstanceId", instanceId); + + queryMap.getMap("volatile") + .put("sdkName", sdkName); + + Task task = new Task<>(); + requests.put(requestId, task); + + if (networkProtocol.getState() == ProtocolState.OPEN) { + networkProtocol.send(queryMap); + } + + return task.getFuture(); + } + + /** + * @return The authentication token + */ + public String getAuthenticationToken() { + return authenticationToken.get(); + } + + /** Set the authentication token + * @param token Authentication token + */ + public void setAuthenticationToken(String token) { + authenticationToken.set(token); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java new file mode 100644 index 00000000..e9f272dd --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java @@ -0,0 +1,140 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; + +import static io.kuzzle.sdk.Helpers.Default.defaultValue; + +public class KuzzleOptions { + + /** + * The maximum amount of elements that the queue can contains. + * If set to -1, the size is unlimited. + */ + private int maxQueueSize = -1; + + /** + * The minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. + */ + private int minTokenDuration = 3_600_000; + + /** + * The minimum duration of a Token after refresh. + * If set to -1 the SDK does not refresh the token automatically. + */ + private int refreshedTokenDuration = 3_600_000; + + /** + * The maximum delay between two requests to be replayed. + */ + private int maxRequestDelay = 1000; + + private Predicate> filter = (ConcurrentHashMap obj) -> true; + + /** + * Initialize a new KuzzleOptions instance. + */ + public KuzzleOptions() {} + + /** Initialize a new KuzzleOptions instance and copy other KuzzleOptions fields + * @param options + */ + public KuzzleOptions(KuzzleOptions options) { + this.maxQueueSize = options.maxQueueSize; + this.minTokenDuration = options.minTokenDuration; + this.refreshedTokenDuration = options.refreshedTokenDuration; + + this.maxRequestDelay = options.maxRequestDelay; + + this.filter = options.filter; + } + + /** + * @return The maximum amount of elements that the queue can contains. + * If set to -1, the size is unlimited. + */ + public int getMaxQueueSize() { + return maxQueueSize; + } + + /** Set the maximum amount of elements that the queue can contains. + * If set to -1, the size is unlimited. + * @param maxQueueSize + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMaxQueueSize(int maxQueueSize) { + this.maxQueueSize = maxQueueSize < 0 + ? -1 + : maxQueueSize; + + return this; + } + + /** + * @return The minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. + */ + public int getMinTokenDuration() { + return minTokenDuration; + } + + /** Set the minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. + * @param minTokenDuration + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMinTokenDuration(int minTokenDuration) { + this.minTokenDuration = minTokenDuration < 0 + ? -1 + : minTokenDuration; + + return this; + } + + /** + * @return The minimum duration of a Token after refresh. + * If set to -1 the SDK does not refresh the token automatically. + */ + public int getRefreshedTokenDuration() { + return refreshedTokenDuration; + } + + /** Set the minimum duration of a Token after refresh. + * If set to -1 the SDK does not refresh the token automatically. + * @param refreshedTokenDuration + * @return This KuzzleOptions instance + */ + public KuzzleOptions withRefreshedTokenDuration(int refreshedTokenDuration) { + this.refreshedTokenDuration = refreshedTokenDuration < 0 + ? -1 + : refreshedTokenDuration; + + return this; + } + + /** + * @return The maximum delay between two requests to be replayed. + */ + public int getMaxRequestDelay() { + return maxRequestDelay; + } + + /** Set the maximum delay between two requests to be replayed. + * @param maxRequestDelay + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMaxRequestDelay(int maxRequestDelay) { + this.maxRequestDelay = maxRequestDelay; + return this; + } + + public Predicate> getFilter() { + return filter; + } + + public KuzzleOptions withFilter(Predicate> filter) { + this.filter = defaultValue(filter, (ConcurrentHashMap obj) -> true); + return this; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java new file mode 100644 index 00000000..9db683a0 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java @@ -0,0 +1,113 @@ +package io.kuzzle.sdk.Options.Protocol; + +import io.kuzzle.sdk.Options.KuzzleOptions; + +public class WebSocketOptions { + + /** + * The port to use to connect. + */ + private int port = 7512; + + /** + * If we use SSL connection. + */ + private boolean ssl = false; + + /** + * The duration before the connection timeout. + */ + private int connectionTimeout = -1; + + /** + * If the websocket auto reconnects. + */ + private boolean autoReconnect = true; + + /** + * Initialize a new WebSocketOptions instance. + */ + public WebSocketOptions() {} + + + /** Initialize a new WebSocketOptions instance and copy other WebSocketOptions fields + * @param other + */ + public WebSocketOptions(WebSocketOptions other) { + this.port = other.port; + this.ssl = other.ssl; + this.connectionTimeout = other.connectionTimeout; + this.autoReconnect = other.autoReconnect; + } + + /** + * @return The port used to connect. + */ + public int getPort() { + return port; + } + + /** Set the port to use to connect. + * @param port + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withPort(int port) { + this.port = + port >= 0 + ? port + : 7512; + return this; + } + + /** + * @return If we use SSL connection. + */ + public boolean isSsl() { + return ssl; + } + + /** Set if we use SSL connection. + * @param ssl + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withSsl(boolean ssl) { + this.ssl = ssl; + return this; + } + + /** + * @return The duration before the connection timeout. + */ + public int getConnectionTimeout() { + return connectionTimeout; + } + + /** Set the duration before the connection timeout. + * @param connectionTimeout + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = + connectionTimeout < 0 + ? -1 + : connectionTimeout; + return this; + } + + + /** + * @return If the websocket auto reconnects. + */ + public boolean isAutoReconnect() { + return autoReconnect; + } + + /** Set if the websocket auto reconnects. + * @param autoReconnect + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withAutoReconnect(boolean autoReconnect) { + this.autoReconnect = autoReconnect; + return this; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java new file mode 100644 index 00000000..bfdf17b1 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java @@ -0,0 +1,79 @@ +package io.kuzzle.sdk.Protocol; + +import io.kuzzle.sdk.Events.EventListener; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +public abstract class AbstractProtocol { + protected EventListener stateChanged; + protected EventListener messageReceived; + + public AbstractProtocol() { + stateChanged = new EventListener<>(); + messageReceived = new EventListener<>(); + } + + /** Current connection state. + * @return The state. + */ + public abstract ProtocolState getState(); + + /** connect this instance. + * @throws Exception + */ + public abstract void connect() throws Exception; + + /** + * Disconnect this instance. + */ + public abstract void disconnect(); + + /** Send the specified payload to Kuzzle. + * @param payload + */ + public abstract void send(ConcurrentHashMap payload); + + + /** + * Register to the Response event + */ + public boolean registerResponseEvent(Consumer callback) { + return messageReceived.register(callback); + } + + /** + * Unregister from the Response event + */ + public boolean unregisterResponseEvent(Consumer callback) { + return messageReceived.unregister(callback); + } + + /** + * Register to the StateChange event + */ + public boolean registerStateChangeEvent(Consumer callback) { + return stateChanged.register(callback); + } + + /** + * Unregister from the StateChange event + */ + public boolean unregisterStateChangeEvent(Consumer callback) { + return stateChanged.unregister(callback); + } + + + /** Dispatch a state changed event. + * @param state The ProtocolState. + */ + protected void dispatchStateChangeEvent(ProtocolState state) { + stateChanged.trigger(state); + } + + /** Dispatch a message received from a Kuzzle server. + * @param message Kuzzle API response. + */ + protected void dispatchResponseEvent(String message) { + messageReceived.trigger(message); + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java new file mode 100644 index 00000000..4ecb67b2 --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java @@ -0,0 +1,6 @@ +package io.kuzzle.sdk.Protocol; + +public enum ProtocolState { + CLOSE, // The network protocol does not accept requests. + OPEN, // The network protocol accepts new requests. +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java new file mode 100644 index 00000000..1cbf482c --- /dev/null +++ b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java @@ -0,0 +1,186 @@ +package io.kuzzle.sdk.Protocol; + +import com.neovisionaries.ws.client.WebSocketAdapter; +import com.neovisionaries.ws.client.WebSocketFactory; +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; + +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.*; + +public class WebSocket extends AbstractProtocol { + + protected BlockingDeque> queue; + protected com.neovisionaries.ws.client.WebSocket socket; + protected ProtocolState state = ProtocolState.CLOSE; + protected URI uri; + + protected final boolean ssl; + protected final int port; + protected int connectionTimeout; + + public ProtocolState getState() { + return state; + } + + public WebSocket(URI uri) + throws Exception { + WebSocketOptions options = new WebSocketOptions(); + if (uri.getPort() > -1) { + options.withPort(uri.getPort()); + } + if (uri.getHost() == null || uri.getHost().isEmpty()) { + throw new URISyntaxException("Missing host", "Could not find host part"); + } + if (uri.getScheme() != null) { + options.withSsl(uri.getScheme().equals("wss")); + } + WebSocketOptions wsOptions = + options != null + ? new WebSocketOptions(options) + : new WebSocketOptions(); + + ssl = wsOptions.isSsl(); + port = wsOptions.getPort(); + connectionTimeout = wsOptions.getConnectionTimeout(); + + this.uri = new URI((ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); + this.queue = new LinkedBlockingDeque<>(); + } + + public WebSocket( + URI uri, + WebSocketOptions options + ) throws URISyntaxException, IllegalArgumentException { + this(uri.getHost(), options); + } + + public WebSocket(String host) + throws URISyntaxException, IllegalArgumentException { + this(host, new WebSocketOptions()); + } + + /** + * @param host Kuzzle host address + * @param options WebSocket options + * @throws URISyntaxException + * @throws IllegalArgumentException + */ + public WebSocket( + String host, + WebSocketOptions options + ) throws URISyntaxException, IllegalArgumentException { + super(); + + WebSocketOptions wsOptions = + options != null + ? new WebSocketOptions(options) + : new WebSocketOptions(); + + ssl = wsOptions.isSsl(); + port = wsOptions.getPort(); + connectionTimeout = wsOptions.getConnectionTimeout(); + + if (host == null || host.isEmpty()) { + throw new IllegalArgumentException("Host name/address can't be empty"); + } + this.uri = new URI((ssl ? "wss" : "ws") + "://" + host + ":" + port + "/"); + this.queue = new LinkedBlockingDeque<>(); + } + + @Override + public void send(ConcurrentHashMap payload) { + queue.add(payload); + } + + protected com.neovisionaries.ws.client.WebSocket createClientSocket() + throws IOException + { + WebSocketFactory wsFactory = new WebSocketFactory(); + + if (connectionTimeout > -1) { + wsFactory = wsFactory.setConnectionTimeout(connectionTimeout); + } + + if (ssl) { + + wsFactory.setSocketFactory(SSLSocketFactory.getDefault()); + } + + return wsFactory.createSocket(uri); + } + + /** Connects to a Kuzzle server. + * @throws Exception + */ + @Override + public void connect() throws Exception { + if (socket != null) { + return; + } + + socket = createClientSocket(); + + socket.connect(); + state = ProtocolState.OPEN; + dispatchStateChangeEvent(state); + Dequeue(); + + socket.addListener(new WebSocketAdapter() { + @Override + public void onTextMessage( + com.neovisionaries.ws.client.WebSocket websocket, + String text + ) throws Exception { + super.onTextMessage(websocket, text); + dispatchResponseEvent(text); + } + }); + } + + /** + * Disconnects this instance. + */ + @Override + public void disconnect() { + CloseState(); + } + + protected void CloseState() { + if (socket != null) { + socket.disconnect(); + state = ProtocolState.CLOSE; + socket = null; + dispatchStateChangeEvent(state); + } + } + + protected Thread Dequeue() { + Thread thread = new Thread(() -> { + while (state == ProtocolState.OPEN) { + ConcurrentHashMap payload = queue.poll(); + if (payload != null) { + String rawJson = JsonSerializer.serialize(payload); + socket.sendText(rawJson); + } + } + }); + thread.start(); + return thread; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = + connectionTimeout < 0 + ? -1 + : connectionTimeout; + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java new file mode 100644 index 00000000..8b46dff3 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java @@ -0,0 +1,239 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import com.sun.org.apache.xpath.internal.operations.Bool; +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.test.TestableKuzzle; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +public class KuzzleMapTest { + private KuzzleMap kuzzleMap; + + @Before + public void setup() throws URISyntaxException { + kuzzleMap = new KuzzleMap(); + kuzzleMap.put("String", "String"); + kuzzleMap.put("Number", 0); + kuzzleMap.put("Boolean", false); + kuzzleMap.put("ArrayList", new ArrayList<>()); + kuzzleMap.put("Map", new ConcurrentHashMap<>()); + kuzzleMap.put("KuzzleMap", new KuzzleMap()); + kuzzleMap.put("Null", null); + } + + @Test + public void isString() { + Assert.assertTrue(kuzzleMap.isString("String")); + Assert.assertFalse(kuzzleMap.isString("Number")); + Assert.assertFalse(kuzzleMap.isString("Boolean")); + Assert.assertFalse(kuzzleMap.isString("ArrayList")); + Assert.assertFalse(kuzzleMap.isString("Map")); + Assert.assertFalse(kuzzleMap.isString("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isString("Null")); + Assert.assertFalse(kuzzleMap.isString("UnknownKey")); + } + + @Test + public void isNumber() { + Assert.assertFalse(kuzzleMap.isNumber("String")); + Assert.assertTrue(kuzzleMap.isNumber("Number")); + Assert.assertFalse(kuzzleMap.isNumber("Boolean")); + Assert.assertFalse(kuzzleMap.isNumber("ArrayList")); + Assert.assertFalse(kuzzleMap.isNumber("Map")); + Assert.assertFalse(kuzzleMap.isNumber("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isNumber("Null")); + Assert.assertFalse(kuzzleMap.isNumber("UnknownKey")); + } + + @Test + public void isBoolean() throws Exception { + Assert.assertFalse(kuzzleMap.isBoolean("String")); + Assert.assertFalse(kuzzleMap.isBoolean("Number")); + Assert.assertTrue(kuzzleMap.isBoolean("Boolean")); + Assert.assertFalse(kuzzleMap.isBoolean("ArrayList")); + Assert.assertFalse(kuzzleMap.isBoolean("Map")); + Assert.assertFalse(kuzzleMap.isBoolean("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isBoolean("Null")); + Assert.assertFalse(kuzzleMap.isBoolean("UnknownKey")); + } + + @Test + public void isArrayList() { + Assert.assertFalse(kuzzleMap.isArrayList("String")); + Assert.assertFalse(kuzzleMap.isArrayList("Number")); + Assert.assertFalse(kuzzleMap.isArrayList("Boolean")); + Assert.assertTrue(kuzzleMap.isArrayList("ArrayList")); + Assert.assertFalse(kuzzleMap.isArrayList("Map")); + Assert.assertFalse(kuzzleMap.isArrayList("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isArrayList("Null")); + Assert.assertFalse(kuzzleMap.isArrayList("UnknownKey")); + } + + @Test + public void isMap() { + Assert.assertFalse(kuzzleMap.isMap("String")); + Assert.assertFalse(kuzzleMap.isMap("Number")); + Assert.assertFalse(kuzzleMap.isMap("Boolean")); + Assert.assertFalse(kuzzleMap.isMap("ArrayList")); + Assert.assertTrue(kuzzleMap.isMap("Map")); + Assert.assertTrue(kuzzleMap.isMap("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isMap("Null")); + Assert.assertFalse(kuzzleMap.isMap("UnknownKey")); + } + + @Test + public void isNull() { + Assert.assertFalse(kuzzleMap.isNull("String")); + Assert.assertFalse(kuzzleMap.isNull("Number")); + Assert.assertFalse(kuzzleMap.isNull("Boolean")); + Assert.assertFalse(kuzzleMap.isNull("ArrayList")); + Assert.assertFalse(kuzzleMap.isNull("Map")); + Assert.assertFalse(kuzzleMap.isNull("KuzzleMap")); + Assert.assertTrue(kuzzleMap.isNull("Null")); + Assert.assertFalse(kuzzleMap.isNull("UnknownKey")); + } + + @Test + public void getString() { + Assert.assertNotNull(kuzzleMap.getString("String")); + Assert.assertNull(kuzzleMap.getString("Number")); + Assert.assertNull(kuzzleMap.getString("Boolean")); + Assert.assertNull(kuzzleMap.getString("ArrayList")); + Assert.assertNull(kuzzleMap.getString("Map")); + Assert.assertNull(kuzzleMap.getString("KuzzleMap")); + Assert.assertNull(kuzzleMap.getString("Null")); + Assert.assertNull(kuzzleMap.getString("UnknownKey")); + } + + @Test + public void getNumber() { + Assert.assertNull(kuzzleMap.getNumber("String")); + Assert.assertNotNull(kuzzleMap.getNumber("Number")); + Assert.assertNull(kuzzleMap.getNumber("Boolean")); + Assert.assertNull(kuzzleMap.getNumber("ArrayList")); + Assert.assertNull(kuzzleMap.getNumber("Map")); + Assert.assertNull(kuzzleMap.getNumber("KuzzleMap")); + Assert.assertNull(kuzzleMap.getNumber("Null")); + Assert.assertNull(kuzzleMap.getNumber("UnknownKey")); + } + + @Test + public void getBoolean() { + Assert.assertNull(kuzzleMap.getBoolean("String")); + Assert.assertNull(kuzzleMap.getBoolean("Number")); + Assert.assertNotNull(kuzzleMap.getBoolean("Boolean")); + Assert.assertNull(kuzzleMap.getBoolean("ArrayList")); + Assert.assertNull(kuzzleMap.getBoolean("Map")); + Assert.assertNull(kuzzleMap.getBoolean("KuzzleMap")); + Assert.assertNull(kuzzleMap.getBoolean("Null")); + Assert.assertNull(kuzzleMap.getBoolean("UnknownKey")); + } + + @Test + public void getArrayList() { + Assert.assertNull(kuzzleMap.getArrayList("String")); + Assert.assertNull(kuzzleMap.getArrayList("Number")); + Assert.assertNull(kuzzleMap.getArrayList("Boolean")); + Assert.assertNotNull(kuzzleMap.getArrayList("ArrayList")); + Assert.assertNull(kuzzleMap.getArrayList("Map")); + Assert.assertNull(kuzzleMap.getArrayList("KuzzleMap")); + Assert.assertNull(kuzzleMap.getArrayList("Null")); + Assert.assertNull(kuzzleMap.getArrayList("UnknownKey")); + } + + @Test + public void getMap() { + Assert.assertNull(kuzzleMap.getMap("String")); + Assert.assertNull(kuzzleMap.getMap("Number")); + Assert.assertNull(kuzzleMap.getMap("Boolean")); + Assert.assertNull(kuzzleMap.getMap("ArrayList")); + Assert.assertNotNull(kuzzleMap.getMap("Map")); + Assert.assertNotNull(kuzzleMap.getMap("KuzzleMap")); + Assert.assertNull(kuzzleMap.getMap("Null")); + Assert.assertNull(kuzzleMap.getMap("UnknownKey")); + } + + @Test + public void get() { + Assert.assertTrue(kuzzleMap.get("String") instanceof String); + Assert.assertTrue(kuzzleMap.get("Number") instanceof Number); + Assert.assertTrue(kuzzleMap.get("Boolean") instanceof Boolean); + Assert.assertTrue(kuzzleMap.get("ArrayList") instanceof ArrayList); + Assert.assertTrue(kuzzleMap.get("Map") instanceof ConcurrentHashMap); + Assert.assertTrue(kuzzleMap.get("KuzzleMap") instanceof ConcurrentHashMap); + Assert.assertTrue(kuzzleMap.get("Null") == null); + Assert.assertTrue(kuzzleMap.get("UnknownKey") == null); + } + + @Test + public void optString() { + Assert.assertTrue(kuzzleMap.optString("String", "foo").equals("String")); + Assert.assertTrue(kuzzleMap.optString("Number", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Boolean", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("ArrayList", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Map", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("KuzzleMap", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Null", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("UnknownKey", "foo").equals("foo")); + } + + @Test + public void optNumber() { + Assert.assertTrue(kuzzleMap.optNumber("String", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Number", 42).equals(0)); + Assert.assertTrue(kuzzleMap.optNumber("Boolean", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("ArrayList", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Map", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("KuzzleMap", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Null", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("UnknownKey", 42).equals(42)); + } + + @Test + public void optBoolean() { + Assert.assertTrue(kuzzleMap.optBoolean("String", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Number", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Boolean", true).equals(false)); + Assert.assertTrue(kuzzleMap.optBoolean("ArrayList", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Map", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("KuzzleMap", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Null", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("UnknownKey", true).equals(true)); + } + + @Test + public void optArrayList() { + ArrayList list = new ArrayList<>(); + list.add(1); + + Assert.assertEquals(kuzzleMap.optArrayList("String", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Number", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Boolean", list).hashCode(), list.hashCode()); + Assert.assertNotEquals(kuzzleMap.optArrayList("ArrayList", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Map", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("KuzzleMap", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Null", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("UnknownKey", list).hashCode(), list.hashCode()); + } + + @Test + public void optMap() { + KuzzleMap map = new KuzzleMap(); + map.put("Data", 1); + + Assert.assertEquals(kuzzleMap.optMap("String", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Number", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Boolean", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("ArrayList", map).hashCode(), map.hashCode()); + Assert.assertNotEquals(kuzzleMap.optMap("Map", map).hashCode(), map.hashCode()); + Assert.assertNotEquals(kuzzleMap.optMap("KuzzleMap", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Null", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("UnknownKey", map).hashCode(), map.hashCode()); + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java new file mode 100644 index 00000000..21c6d0c9 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java @@ -0,0 +1,151 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import io.kuzzle.sdk.CoreClasses.Task; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + +public class TaskTests { + + @Test + public void constructorTest() { + TestableTask task = new TestableTask<>(); + Assert.assertNotNull(task.getAtomicReference()); + Assert.assertEquals( + AtomicReference.class, + task.getAtomicReference().getClass() + ); + Assert.assertNotNull(task.getCountDownLatch()); + Assert.assertEquals( + CountDownLatch.class, + task.getCountDownLatch().getClass() + ); + Assert.assertNotNull(task.getFuture()); + } + + @Test + public void getFutureTest() { + Task task = new Task<>(); + + Assert.assertEquals( + CompletableFuture.class, + task.getFuture().getClass() + ); + } + + @Test + public void setExceptionTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + task.setException(new Exception("foobar")); + + verify( + task.mockedFuture, + times(1) + ).completeExceptionally(any(Exception.class)); + } + + @Test + public void isCancelledTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isCancelled()) + .thenReturn(true); + + Assert.assertTrue(task.isCancelled()); + + verify( + task.mockedFuture, + times(1) + ).isCancelled(); + } + + @Test + public void isDoneTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isDone()) + .thenReturn(true); + + Assert.assertTrue(task.isDone()); + + verify( + task.mockedFuture, + times(1) + ).isDone(); + } + + @Test + public void isCompletedExceptionallyTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isCompletedExceptionally()) + .thenReturn(true); + + Assert.assertTrue(task.isCompletedExceptionally()); + + verify( + task.mockedFuture, + times(1) + ).isCompletedExceptionally(); + } + + @Test + public void setCancelledTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + task.setCancelled(true); + + verify( + task.mockedFuture, + times(1) + ).cancel(anyBoolean()); + } + + @Test + public void triggerTest() { + Task task = new Task(); + + final AtomicBoolean success = new AtomicBoolean(false); + + CompletableFuture taskChain = task.getFuture().thenRun(() -> { + success.set(true); + }); + + task.trigger(); + + taskChain.join(); + + Assert.assertTrue(success.get()); + + } + + @Test + public void triggerWithObjectTest() { + Task task = new Task(); + + final AtomicBoolean success = new AtomicBoolean(false); + + CompletableFuture taskChain = task.getFuture().thenAccept((str) -> { + success.set(str.equals("foobar")); + }); + + task.trigger("foobar"); + + taskChain.join(); + + Assert.assertTrue(success.get()); + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java new file mode 100644 index 00000000..51852112 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java @@ -0,0 +1,32 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import io.kuzzle.sdk.CoreClasses.Task; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.Mockito.mock; + +public class TestableTask extends Task { + public CountDownLatch mockedCountDownLatch = mock(CountDownLatch.class); + public CompletableFuture mockedFuture = mock(CompletableFuture.class); + + public TestableTask() { + super(); + } + + public void applyMockFuture() { + super.future = mockedFuture; + } + + public CountDownLatch getCountDownLatch() { + return super.countDownLatch; + } + + public AtomicReference getAtomicReference() { + return super.atomicReference; + } + + +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java new file mode 100644 index 00000000..ec22a31f --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java @@ -0,0 +1,159 @@ +package io.kuzzle.test.EventsTest; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class EventListenerTests { + + @Test + public void registerRunnableTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.register(() -> {}); + + verify( + eventListener.mockedCallbacks, + times(1) + ).add(any(Runnable.class)); + } + + @Test + public void unregisterRunnableTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.unregister(() -> {}); + + verify( + eventListener.mockedCallbacks, + times(1) + ).remove(any(Runnable.class)); + } + + @Test + public void registerConsumerTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.register((obj) -> {}); + + verify( + eventListener.mockedCallbacks, + times(1) + ).add(any(Consumer.class)); + } + + @Test + public void unregisterConsumerTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.unregister((obj) -> {}); + + verify( + eventListener.mockedCallbacks, + times(1) + ).remove(any(Consumer.class)); + } + + @Test + public void registerDuplicateTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + + Runnable runnable1 = () -> {}; + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(() -> {}); + + Assert.assertEquals(2, eventListener.getCallbacks().size()); + } + + @Test + public void triggerRunnableTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + + AtomicBoolean success = new AtomicBoolean(false); + eventListener.register(() -> success.set(true)); + + Assert.assertFalse(success.get()); + + eventListener.trigger(); + + Assert.assertTrue(success.get()); + } + + @Test + public void triggerConsumerTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + + AtomicBoolean success = new AtomicBoolean(false); + eventListener.register((str) -> success.set(str.equals("foobar"))); + + Assert.assertFalse(success.get()); + + eventListener.trigger("foobar"); + + Assert.assertTrue(success.get()); + } + + @Test + public void triggerOnlyConsumerTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + + AtomicBoolean consumerSuccess = new AtomicBoolean(false); + AtomicBoolean runnableSuccess = new AtomicBoolean(false); + + eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); + eventListener.register(() -> runnableSuccess.set(true)); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + + eventListener.trigger("foobar"); + + Assert.assertTrue(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + } + + @Test + public void triggerOnlyRunnableTest() { + TestableEventListener + eventListener = new TestableEventListener<>(); + + AtomicBoolean consumerSuccess = new AtomicBoolean(false); + AtomicBoolean runnableSuccess = new AtomicBoolean(false); + + eventListener.register( + (str) -> consumerSuccess.set(str.equals("foobar")) + ); + eventListener.register(() -> runnableSuccess.set(true)); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + + eventListener.trigger(); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertTrue(runnableSuccess.get()); + } + +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java new file mode 100644 index 00000000..3d1af9e3 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java @@ -0,0 +1,22 @@ +package io.kuzzle.test.EventsTest; + +import io.kuzzle.sdk.Events.EventListener; + +import java.util.Set; + +import static org.mockito.Mockito.mock; + +public class TestableEventListener extends EventListener { + public Set mockedCallbacks = mock(Set.class); + public TestableEventListener() { + super(); + } + + public void applyMock() { + super.callbacks = mockedCallbacks; + } + + public Set getCallbacks() { + return super.callbacks; + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java new file mode 100644 index 00000000..a15fa8e2 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java @@ -0,0 +1,24 @@ +package io.kuzzle.test.Helpers; + +import io.kuzzle.sdk.Helpers.Default; +import org.junit.Assert; +import org.junit.Test; + +public class DefaultTests { + + @Test + public void notNullTest() { + String str1 = Default.defaultValue(null, "foobar"); + String str2 = Default.defaultValue("SomeString", "foobar"); + + Integer int1 = Default.defaultValue(null, 42); + Integer int2 = Default.defaultValue(10, 42); + + Assert.assertEquals("foobar", str1); + Assert.assertEquals("SomeString", str2); + + Assert.assertEquals(42, int1.intValue()); + Assert.assertEquals(10, int2.intValue()); + } + +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java new file mode 100644 index 00000000..2b817d41 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java @@ -0,0 +1,177 @@ +package io.kuzzle.test; + +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.CoreClasses.Responses.ErrorResponse; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import java.net.URISyntaxException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +public class KuzzleTests { + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + private EventListener + tokenExpiredEventListener = Mockito.mock(EventListener.class); + private EventListener + unhandledResponseEventListener = Mockito.mock(EventListener.class); + private TestableKuzzle kuzzle; + + @Before + public void setup() throws URISyntaxException { + kuzzle = new TestableKuzzle(networkProtocol); + kuzzle.setTokenExpiredEventListener(tokenExpiredEventListener); + kuzzle.setUnhandledResponseEventListener(unhandledResponseEventListener); + } + + @Test + public void connect() throws Exception { + kuzzle.connect(); + Mockito.verify( + networkProtocol, + Mockito.times(1) + ).connect(); + } + + @Test + public void disconnect() throws Exception { + kuzzle.disconnect(); + Mockito.verify( + networkProtocol, + Mockito.times(1) + ).disconnect(); + } + + + @Test + public void registerTokenExpiredEvent() throws Exception { + kuzzle.registerTokenExpiredEvent(() -> {}); + Mockito.verify(tokenExpiredEventListener, + Mockito.times(1) + ).register(Matchers.any(Runnable.class)); + } + + @Test + public void unregisterTokenExpiredEvent() throws Exception { + kuzzle.unregisterTokenExpiredEvent(() -> {}); + Mockito.verify( + tokenExpiredEventListener, + Mockito.times(1) + ).unregister(Matchers.any(Runnable.class)); + } + + @Test + public void onStateChanged() { + ConcurrentHashMap> + requests = kuzzle.getRequests(); + + Task response = new Task<>(); + requests.put("foobar", response); + kuzzle.onStateChanged(ProtocolState.CLOSE); + Assert.assertEquals(0, requests.size()); + Assert.assertTrue(response.isCompletedExceptionally()); + } + + @Test(expected = NotConnectedException.class) + public void queryShouldThrowWhenNotConnected() + throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()) + .thenAnswer( + (Answer) invocation -> ProtocolState.CLOSE + ); + + kuzzle.query(new ConcurrentHashMap<>()); + } + + @Test + public void querySuccess() throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()) + .thenAnswer( + (Answer) invocation -> ProtocolState.OPEN + ); + + CompletableFuture + response = kuzzle.query( + new ConcurrentHashMap<>() + ); + + Assert.assertNotNull(response); + Mockito.verify( + networkProtocol, + Mockito.times(1) + ).send(Matchers.any(ConcurrentHashMap.class)); + } + + @Test(expected = InternalException.class) + public void queryShouldThrowWhenVolatileIsNotConcurrentHashMap() + throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()) + .thenAnswer( + (Answer) invocation -> ProtocolState.OPEN + ); + + ConcurrentHashMap payload = new ConcurrentHashMap<>(); + payload.put("volatile", "foobar"); + + kuzzle.query(payload); + } + + @Test + public void onResponseReceivedAndTokenIsExpired() { + ConcurrentHashMap> + requests = kuzzle.getRequests(); + + Response response = new Response(); + response.requestId = "foobar"; + response.error = new ErrorResponse(); + response.error.id = "security.token.expired"; + response.error.status = 42; + response.room = "room-id"; + + Task task = new Task<>(); + + requests.put("room-id", task); + + kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); + + Mockito.verify( + tokenExpiredEventListener, + Mockito.times(1) + ).trigger(); + } + + @Test + public void onResponseReceivedAndResponseIsUnhandled() { + ConcurrentHashMap> + requests = kuzzle.getRequests(); + + AtomicBoolean success = new AtomicBoolean(false); + Response response = new Response(); + response.requestId = "foobar"; + + Task task = new Task<>(); + + requests.put("request-id", task); + + kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); + + Mockito.verify( + unhandledResponseEventListener, + Mockito.times(1) + ).trigger(Matchers.any(Response.class)); + } + +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java new file mode 100644 index 00000000..daae19df --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java @@ -0,0 +1,38 @@ +package io.kuzzle.test.ProtocolTest; + +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; +import java.net.URISyntaxException; + +import static org.mockito.Mockito.mock; + +public class TestableWebSocket extends WebSocket { + public int stateChangedCount = 0; + public ProtocolState lastStateDispatched = ProtocolState.CLOSE; + public com.neovisionaries.ws.client.WebSocket + mockedSocket = mock(com.neovisionaries.ws.client.WebSocket.class); + + public TestableWebSocket(String host) + throws URISyntaxException, IllegalArgumentException { + super(host); + } + + public TestableWebSocket(String host, WebSocketOptions options) + throws URISyntaxException, IllegalArgumentException { + super(host, options); + super.stateChanged.register((ProtocolState state) -> { + stateChangedCount += 1; + lastStateDispatched = state; + }); + } + + public com.neovisionaries.ws.client.WebSocket getSocket() { + return super.socket; + } + + @Override + protected com.neovisionaries.ws.client.WebSocket createClientSocket() { + return mockedSocket; + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java new file mode 100644 index 00000000..ed6e1252 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java @@ -0,0 +1,90 @@ +package io.kuzzle.test.ProtocolTest; + +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.ProtocolState; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.net.URISyntaxException; + +import static org.mockito.Mockito.*; + +public class WebSocketTests { + + private TestableWebSocket socket; + private String host; + private WebSocketOptions options; + + @Before + public void setup() throws URISyntaxException { + host = "foo"; + options = new WebSocketOptions() + .withPort(1234) + .withSsl(true); + socket = new TestableWebSocket(host, options); + } + + @Test + public void constructorNotConnected() throws URISyntaxException { + TestableWebSocket ws = new TestableWebSocket(host, options); + + Assert.assertEquals(ProtocolState.CLOSE, ws.getState()); + Assert.assertNull(ws.getSocket()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorRejectsNullHost() throws URISyntaxException { + TestableWebSocket ws = new TestableWebSocket(null, options); + } + + @Test + public void connectTest() throws Exception { + when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); + + socket.connect(); + + Assert.assertNotNull(socket.getSocket()); + + socket.connect(); + socket.connect(); + socket.connect(); + + verify(socket.mockedSocket, times(1)).connect(); + + Assert.assertEquals(ProtocolState.OPEN, socket.getState()); + Assert.assertEquals(1, socket.stateChangedCount); + Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); + } + + @Test + public void disconnectTest() throws Exception { + when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); + + socket.connect(); + + Assert.assertEquals(ProtocolState.OPEN, socket.getState()); + Assert.assertEquals(1, socket.stateChangedCount); + Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); + + socket.disconnect(); + socket.disconnect(); + socket.disconnect(); + + verify( + socket.mockedSocket, + times(1) + ).disconnect(); + } + + @Test + public void disconnectWithoutEverConnecting() throws Exception { + Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); + Assert.assertEquals(0, socket.stateChangedCount); + + socket.disconnect(); + + Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); + Assert.assertEquals(0, socket.stateChangedCount); + } +} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java new file mode 100644 index 00000000..f42d8137 --- /dev/null +++ b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java @@ -0,0 +1,51 @@ +package io.kuzzle.test; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; + +import java.net.URISyntaxException; +import java.util.concurrent.ConcurrentHashMap; + +public class TestableKuzzle extends Kuzzle { + + public TestableKuzzle(AbstractProtocol networkProtocol) throws URISyntaxException, IllegalArgumentException { + super(networkProtocol); + } + + public TestableKuzzle(AbstractProtocol networkProtocol, KuzzleOptions options) throws IllegalArgumentException { + super(networkProtocol, options); + } + + public void setTokenExpiredEventListener(EventListener eventListener) { + super.tokenExpiredEvent = eventListener; + } + + public EventListener getTokenExpiredEventListener() { + return super.tokenExpiredEvent; + } + + public void setUnhandledResponseEventListener(EventListener eventListener) { + super.unhandledResponseEvent = eventListener; + } + + public EventListener getUnhandledResponseEventListener() { + return super.unhandledResponseEvent; + } + + public void onStateChanged(ProtocolState state) { + super.onStateChanged(state); + } + + public void onResponseReceived(String payload) { + super.onResponseReceived(payload); + } + + public ConcurrentHashMap> getRequests() { + return super.requests; + } +} diff --git a/package.json b/package.json deleted file mode 100644 index 29bb7059..00000000 --- a/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "scripts": { - "doc-prepare": "cd doc && bash doc.sh prepare", - "doc-dev": "cd doc && bash doc.sh dev", - "doc-build": "cd doc && bash doc.sh build", - "doc-upload": "cd doc && bash doc.sh upload", - "doc-cloudfront": "cd doc && bash doc.sh cloudfront", - "doc-deploy": "npm run doc-upload && npm run doc-cloudfront", - "doc-netlify": "npm run doc-prepare && cd doc && bash doc.sh build-netlify" - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 7b986f12..00000000 --- a/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user guide at https://docs.gradle.org/4.5.1/userguide/multi_project_builds.html - */ - -rootProject.name = 'sdk-java' diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java deleted file mode 100644 index 4b4eb234..00000000 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.kuzzle.sdk; - -public class Kuzzle { - -} From 5a2b366a5d1829b2e03e4b82a0b86c587e6c5b90 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Fri, 10 Jan 2020 17:06:37 +0100 Subject: [PATCH 007/134] Migrate the ci (V3) to use KuzDoc --- .gitignore | 3 +- .travis.yml | 58 +- package-lock.json | 1727 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 14 + 4 files changed, 1784 insertions(+), 18 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 2407ed41..151f1041 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ bin .project .settings -doc/framework \ No newline at end of file +doc/framework +node_modules diff --git a/.travis.yml b/.travis.yml index 5a99cb79..b6241cd1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,15 @@ ---- -# ----------------- -# YAML Templates -# ----------------- +env: + global: + # BINTRAY_USER + - secure: "LxONQZ8tHhxTqgu+kqx9fMCubCfTQHZsy/3ibE+l72xG8sOAYfj4hB5k1p4kklnv3skeFQEiL6B++B2qRITOEAPRdD8FExkc+UF/TM1rY5aUtjIjoA3uH4n9hYjHirTO5qNKf4KxDr1Zbcn4ISGebJ0EYwE0SG/ptrd06wPp1G8AHshc8XaZgen6gDaik66OWpQkOkmGsRz2EPmIBVgo7L2LGK21DSxE4/PTo+ou0WYCyxyyWSKLTLt1xZpt9LOtk7IckrHl+Nenl6IbV/CjHb3+5vwdifyFQd+K6AVe32iTIVjdxj7rDhEHYD0EqKb79ey+u8p9HquLnGH03gcVBeFQu/qhhQStsiwrD/S9c8jwBjWOOUnVI4bEbqjqxFaRlPfVnRaAjQZLRKHdqxyTJCdC2Ls79LmkqSCyTxM7WBwwgu4Slf6RJSbKJb5naHYlwDuKPbeyHLAYrxgjEHC28bxQiTr5wwBWxE9BLxUcnkFAXzsy3qE74FQOIjvQbtrruLIOGwRGRYtzyfygGA3MfTHug6JwZGngqFf3k+kbznE8fZe7zxMwT63P6/54rR5fU/plLoTNFqdQsZGAfGOSYuHIEzWXOkWxffqsOwxPa1VxQTLD32O95oBcrcvmw4toC2NeFTe/+zZRMfGMbu7QIi0AL3qFpky3j12zcyA/M2I=" + # BINTRAY_KEY + - secure: "Iqn4ImAwFmQeoXXDb5JOsfcunSiSeLvdp4+AEsIeniMhpIk++ZJPDSxecC+NrvndTrxOXVqHEsFUfHnZYvPHMuvg9nhXvz/rmmyYH0hZqkKg2q2qM+Sz2UJBCvs6D1sJv3ZEVi8d6fVx5bbKXMzSE023XFBBK7l8nBsG5ObXBOzTzrus9UP+fk4FXif/QKJNcUSN7rLejUIxMCk36gMQYqYGiiqL3VE60aTpaUh7Vqj/8nCEPcO3K3gXTVybcGBcmsvinV5YEc+5s5ue8eX10ONY0oYF5GFd7aEsrKEFzT2d7MVq0a29cH1rWrxt6q7vXGZNKAdAQrDyRZUz9rMFtqH+2xOgagm22UiUYNlzrn2eDYRBd08X0y043gumdgmOq/CsyaI5bcUSKMr+rsZ2XIzBjefl8MU0xBhtKMO9g9WRfGBxjRbdg0ivRQoVGJbcUXTDl2WrLMgMjt8DT4nQP+PHdIV2FjZVNioqucqmEzfHIJt+hiw7EonGDnZ9uqkW6hm6b4JpGr5QF1yY6kKVCUQxLueUBAVdiZpULdevL7uYEUzdWIES2wTFE7LaWpHqnCOHYVpkIQpdole6+R0OhINhSHK0FW858xhZ2QGjtL1SSh5yzK4th6dpGKCiwMUSGSj5frpIeWPi+GqYoUQz+TvMGLGG2XGfihx74kQE0FA=" + - AWS_ACCESS_KEY_ID=AKIAIYAXFUAHXOWP2MJA + # AWS_SECRET_ACCESS_KEY + - secure: "dIcQzFpHKRf92cAiMA+SYsudtHWNcbYadVDb7zlJayWGUGy0i4CGwwOoOOrUcWgHxYhdN9XGwvFJTSswjHLRiHEyPFBwW8x/VfaCRS+jAcblMXyWNajvm0930S/3fRv5LA+4UKNmeXMuCGSf35ZqyEIEeuThkIomYvB/tBD1wcMpBUtQfmilLm3sUTaGUnFB651jBHshlYOZ8BAGLLmX1PAfT1wCrpVcrjq5kayNOIilJkwKGSr6q9C0p7+ULNZ4bHsATKLlYNs7Xcs+9a66p1EtKetP72DQsHrr8x3wB2Hhk3U425kmjIoE3gYnF7x3h3EpO5m0rGessbgdRF1SF7XK7Bsj4ukLb4HoktA8G7734ox4848RpH60aKUHRCsiebX7JKgJe1eEwU5BZK8+PFPGH6bI1YG1HQNqthzotTHFXu058uMHnyLv2PmDWWEYMM79fCyuRo8gJJ8GJhDgaGLgtizzEb6grcNW+QwunjA6nP4o7F9o+9b3lfGlsgL595V/CeWLNnHvENkSr67RN2NkDZm6q6EHbOk8AWtQc24mVawCwCbcJjp0sPkbQdCHUXSBNXjdwrvJLA3h94A2uVEmrV7mzMdfj+i9X3IS/HXRLeQk6Ivq2s/b1W6c7rBfz4zZUO7Uu5iYpVzT71yNFra13JkW3REFgHgETEvGkko=" + +sudo: true -# ------------------------ -# Jobs configuration -# ------------------------ jobs: include: - stage: Tests @@ -15,11 +19,13 @@ jobs: node_js: 12 before_script: - - bash -c "cd kuzzle-sdk-java && npm run doc-prepare" - - npm run --prefix $TRAVIS_BUILD_DIR/doc/framework clone-repos + - npm ci + - npm run doc-prepare + - $(npm bin)/kuzdoc iterate-repos:install --repos_path doc/framework/.repos/ + - $(npm bin)/kuzdoc framework:link -d /sdk/java/3/ -v 3 script: - gem install typhoeus - - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links + - cd doc/framework/ && HYDRA_MAX_CONCURRENCY=20 ruby .ci/dead-links.rb -p src/sdk/java/3/ - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io @@ -27,6 +33,7 @@ jobs: language: node_js node_js: 12 env: + - BRANCH=dev - NODE_ENV=production - S3_BUCKET=docs-next.kuzzle.io - CLOUDFRONT_DISTRIBUTION_ID=E2ZCCEK9GRB49U @@ -41,6 +48,9 @@ jobs: install: - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java - gradle assemble + - pip install awscli --upgrade --user + - npm ci + script: - cd kuzzle-sdk-java && npm run doc-prepare - npm run doc-build && cd - @@ -72,12 +82,27 @@ jobs: - python-pip install: - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java - - gradle assemble - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java - - gradle assemble - script: - - gradle check + provider: script + script: + - npm run doc-upload + skip_cleanup: true + + after_deploy: + - npm run doc-cloudfront + + - stage: Deployment + name: Deploy to Bintray + if: branch = master AND tag IS present AND type != cron + language: java + + jdk: + - openjdk8 + + script: bash gradlew test jacocoTestReport + + notifications: + email: false + after_success: - bash <(curl -s https://codecov.io/bash) @@ -86,7 +111,6 @@ jobs: # --------------------------------------- - stage: Builds name: Build SDK Java - language: java jdk: openjdk8 sudo: false before_cache: diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..d1ac30d1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1727 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/runtime": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz", + "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@oclif/command": { + "version": "1.5.19", + "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.5.19.tgz", + "integrity": "sha512-6+iaCMh/JXJaB2QWikqvGE9//wLEVYYwZd5sud8aLoLKog1Q75naZh2vlGVtg5Mq/NqpqGQvdIjJb3Bm+64AUQ==", + "dev": true, + "requires": { + "@oclif/config": "^1", + "@oclif/errors": "^1.2.2", + "@oclif/parser": "^3.8.3", + "@oclif/plugin-help": "^2", + "debug": "^4.1.1", + "semver": "^5.6.0" + } + }, + "@oclif/config": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.13.3.tgz", + "integrity": "sha512-qs5XvGRw+1M41abOKCjd0uoeHCgsMxa2MurD2g2K8CtQlzlMXl0rW5idVeimIg5208LLuxkfzQo8TKAhhRCWLg==", + "dev": true, + "requires": { + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "tslib": "^1.9.3" + } + }, + "@oclif/errors": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.2.2.tgz", + "integrity": "sha512-Eq8BFuJUQcbAPVofDxwdE0bL14inIiwt5EaKRVY9ZDIG11jwdXZqiQEECJx0VfnLyUZdYfRd/znDI/MytdJoKg==", + "dev": true, + "requires": { + "clean-stack": "^1.3.0", + "fs-extra": "^7.0.0", + "indent-string": "^3.2.0", + "strip-ansi": "^5.0.0", + "wrap-ansi": "^4.0.0" + } + }, + "@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==", + "dev": true + }, + "@oclif/parser": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.4.tgz", + "integrity": "sha512-cyP1at3l42kQHZtqDS3KfTeyMvxITGwXwH1qk9ktBYvqgMp5h4vHT+cOD74ld3RqJUOZY/+Zi9lb4Tbza3BtuA==", + "dev": true, + "requires": { + "@oclif/linewrap": "^1.0.0", + "chalk": "^2.4.2", + "tslib": "^1.9.3" + } + }, + "@oclif/plugin-help": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-2.2.3.tgz", + "integrity": "sha512-bGHUdo5e7DjPJ0vTeRBMIrfqTRDBfyR5w0MP41u0n3r7YG5p14lvMmiCXxi6WDaP2Hw5nqx3PnkAIntCKZZN7g==", + "dev": true, + "requires": { + "@oclif/command": "^1.5.13", + "chalk": "^2.4.1", + "indent-string": "^4.0.0", + "lodash.template": "^4.4.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0", + "widest-line": "^2.0.1", + "wrap-ansi": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "@oclif/screen": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", + "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==", + "dev": true + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/listr": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@types/listr/-/listr-0.14.2.tgz", + "integrity": "sha512-wCipMbQr3t2UHTm90LldVp+oTBj1TX6zvpkCJcWS4o8nn6kS8SN93oUvKJAgueIRZ5M36yOlFmScqBxYH8Ajig==", + "dev": true, + "requires": { + "@types/node": "*", + "rxjs": "^6.5.1" + } + }, + "@types/node": { + "version": "13.1.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.6.tgz", + "integrity": "sha512-Jg1F+bmxcpENHP23sVKkNuU3uaxPnsBMW0cLjleiikFKomJQbsn0Cqk2yDvQArqzZN6ABfBkZ0To7pQ8sLdWDg==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", + "dev": true + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "axios": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.1.tgz", + "integrity": "sha512-Yl+7nfreYKaLRvAvjNPkvfjnQHJM1yLBY3zhqAwcJSwR/6ETkanUgylgtIvkvz0xJ+p/vZuNw8X7Hnb7Whsbpw==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "clean-stack": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", + "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-progress": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.5.0.tgz", + "integrity": "sha512-S1wR4xfcfLWbVBH6RwYat1nMCm2UsuygxNoiRYVAXQsuWKjCRgWRZVohXLmsWfiuAK0FFf7t9OyZ2JBmDWaQGA==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "string-width": "^2.1.1" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "cli-ux": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.4.1.tgz", + "integrity": "sha512-x5CJXJPKBrEo6o8Uy/Upajb9OWYMhTzOpRvKZyZ68kkHysiGd9phGP71WyHZfLUkhwdvpNUFkY2tsDr0ogyocg==", + "dev": true, + "requires": { + "@oclif/command": "^1.5.1", + "@oclif/errors": "^1.2.1", + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^1.0.3", + "ansi-escapes": "^3.1.0", + "ansi-styles": "^3.2.1", + "cardinal": "^2.1.1", + "chalk": "^2.4.1", + "clean-stack": "^2.0.0", + "cli-progress": "^3.4.0", + "extract-stack": "^1.0.0", + "fs-extra": "^7.0.1", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^1.1.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.11", + "natural-orderby": "^2.0.1", + "password-prompt": "^1.1.2", + "semver": "^5.6.0", + "string-width": "^3.1.0", + "strip-ansi": "^5.1.0", + "supports-color": "^5.5.0", + "supports-hyperlinks": "^1.0.1", + "treeify": "^1.1.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "execa": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.0.tgz", + "integrity": "sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "extract-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-1.0.0.tgz", + "integrity": "sha1-uXrK+UQe6iMyUpYktzL8WhyBZfo=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kuzdoc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/kuzdoc/-/kuzdoc-1.2.2.tgz", + "integrity": "sha512-QXw4dVIh4dRoD/9Vz9tbpfKNT9Y0AEORJyRHIwKuHaxH65Ccr7KHwxSTbJokK/PV4PebRDO96sPodEc/4NrxbQ==", + "dev": true, + "requires": { + "@oclif/command": "^1.5.19", + "@oclif/config": "^1.13.3", + "@oclif/plugin-help": "^2.2.3", + "@types/listr": "^0.14.2", + "axios": "^0.19.0", + "cli-ux": "^5.4.1", + "execa": "^4.0.0", + "express": "^4.17.1", + "listr": "^0.14.3", + "tslib": "^1.10.0", + "yaml": "^1.7.2" + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "dev": true, + "requires": { + "mime-db": "1.43.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + }, + "dependencies": { + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + } + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "dev": true, + "requires": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "wrap-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz", + "integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..4f47616a --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "scripts": { + "doc-prepare": "kuzdoc framework:install", + "doc-dev": "kuzdoc repo:dev -d /sdk/java/3/ -v 3", + "doc-build": "kuzdoc repo:build -d /sdk/java/3/ -v 3", + "doc-upload": "kuzdoc repo:deploy -d /sdk/java/3/ -v 3", + "doc-cloudfront": "kuzdoc repo:cloudfront -d /sdk/java/3/", + "doc-deploy": "npm run doc-upload && npm run doc-cloudfront", + "doc-netlify": "npm run doc-prepare && kuzdoc repo:build -d / -v 3" + }, + "devDependencies": { + "kuzdoc": "^1.2.2" + } +} From 6a574a741543ccf588cd3d91be2cbc34135c1692 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Mon, 13 Jan 2020 14:04:32 +0100 Subject: [PATCH 008/134] [doc] fix link to framework --- doc/3/.vuepress | 1 + 1 file changed, 1 insertion(+) create mode 120000 doc/3/.vuepress diff --git a/doc/3/.vuepress b/doc/3/.vuepress new file mode 120000 index 00000000..c7af454d --- /dev/null +++ b/doc/3/.vuepress @@ -0,0 +1 @@ +../framework/src/.vuepress \ No newline at end of file From 4d7dc7d37a58bf6d3e7f003d4d070c5d1e04b719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Fri, 17 Jan 2020 09:59:55 +0100 Subject: [PATCH 009/134] Move the kuzzle-sdk-java directory to / (#46) ## What does this PR do ? Move the `kuzzle-sdk-java` directory to / --- .travis.yml | 18 +- README.md | 6 +- kuzzle-sdk-java/build.gradle => build.gradle | 0 .../wrapper/gradle-wrapper.jar | Bin kuzzle-sdk-java/.project | 23 -- .../gradle/wrapper/gradle-wrapper.properties | 5 - kuzzle-sdk-java/gradlew | 172 ----------- kuzzle-sdk-java/gradlew.bat | 84 ----- kuzzle-sdk-java/package.json | 11 - kuzzle-sdk-java/settings.gradle | 2 - .../Json/ConcurrentHashMapTypeAdapter.java | 155 ---------- .../sdk/CoreClasses/Json/JsonSerializer.java | 30 -- .../sdk/CoreClasses/Maps/KuzzleMap.java | 251 --------------- .../sdk/CoreClasses/Maps/KuzzleMapEntry.java | 64 ---- .../io/kuzzle/sdk/CoreClasses/Maps/Null.java | 8 - .../sdk/CoreClasses/Maps/Serializable.java | 8 - .../CoreClasses/Responses/ErrorResponse.java | 57 ---- .../sdk/CoreClasses/Responses/Response.java | 142 --------- .../java/io/kuzzle/sdk/CoreClasses/Task.java | 100 ------ .../io/kuzzle/sdk/Events/EventListener.java | 74 ----- .../sdk/Exceptions/ApiErrorException.java | 41 --- .../sdk/Exceptions/InternalException.java | 19 -- .../sdk/Exceptions/KuzzleException.java | 38 --- .../sdk/Exceptions/KuzzleExceptionCode.java | 30 -- .../java/io/kuzzle/sdk/Helpers/Default.java | 14 - .../src/main/java/io/kuzzle/sdk/Kuzzle.java | 292 ------------------ .../io/kuzzle/sdk/Options/KuzzleOptions.java | 140 --------- .../Options/Protocol/WebSocketOptions.java | 113 ------- .../kuzzle/sdk/Protocol/AbstractProtocol.java | 79 ----- .../io/kuzzle/sdk/Protocol/ProtocolState.java | 6 - .../io/kuzzle/sdk/Protocol/WebSocket.java | 186 ----------- .../CoreClasses/TaskTest/KuzzleMapTest.java | 239 -------------- .../test/CoreClasses/TaskTest/TaskTests.java | 151 --------- .../CoreClasses/TaskTest/TestableTask.java | 32 -- .../test/EventsTest/EventListenerTests.java | 159 ---------- .../EventsTest/TestableEventListener.java | 22 -- .../io/kuzzle/test/Helpers/DefaultTests.java | 24 -- .../test/java/io/kuzzle/test/KuzzleTests.java | 177 ----------- .../test/ProtocolTest/TestableWebSocket.java | 38 --- .../test/ProtocolTest/WebSocketTests.java | 90 ------ .../java/io/kuzzle/test/TestableKuzzle.java | 51 --- package.json | 11 + settings.gradle | 1 + .../Json/ConcurrentHashMapTypeAdapter.java | 150 +++++++++ .../sdk/CoreClasses/Json/JsonSerializer.java | 23 ++ .../sdk/CoreClasses/Maps/KuzzleMap.java | 253 +++++++++++++++ .../sdk/CoreClasses/Maps/KuzzleMapEntry.java | 64 ++++ .../io/kuzzle/sdk/CoreClasses/Maps/Null.java | 9 + .../sdk/CoreClasses/Maps/Serializable.java | 9 + .../CoreClasses/Responses/ErrorResponse.java | 57 ++++ .../sdk/CoreClasses/Responses/Response.java | 140 +++++++++ .../java/io/kuzzle/sdk/CoreClasses/Task.java | 104 +++++++ .../io/kuzzle/sdk/Events/EventListener.java | 84 +++++ .../sdk/Exceptions/ApiErrorException.java | 39 +++ .../Exceptions/ConnectionLostException.java | 12 +- .../sdk/Exceptions/InternalException.java | 19 ++ .../sdk/Exceptions/KuzzleException.java | 40 +++ .../sdk/Exceptions/KuzzleExceptionCode.java | 28 ++ .../sdk/Exceptions/NotConnectedException.java | 12 +- .../java/io/kuzzle/sdk/Helpers/Default.java | 16 + src/main/java/io/kuzzle/sdk/Kuzzle.java | 292 ++++++++++++++++++ .../io/kuzzle/sdk/Options/KuzzleOptions.java | 145 +++++++++ .../Options/Protocol/WebSocketOptions.java | 117 +++++++ .../kuzzle/sdk/Protocol/AbstractProtocol.java | 87 ++++++ .../io/kuzzle/sdk/Protocol/ProtocolState.java | 6 + .../io/kuzzle/sdk/Protocol/WebSocket.java | 166 ++++++++++ .../CoreClasses/TaskTest/KuzzleMapTest.java | 236 ++++++++++++++ .../test/CoreClasses/TaskTest/TaskTests.java | 124 ++++++++ .../CoreClasses/TaskTest/TestableTask.java | 31 ++ .../test/EventsTest/EventListenerTests.java | 142 +++++++++ .../EventsTest/TestableEventListener.java | 23 ++ .../io/kuzzle/test/Helpers/DefaultTests.java | 24 ++ src/test/java/io/kuzzle/test/KuzzleTests.java | 139 +++++++++ .../test/ProtocolTest/TestableWebSocket.java | 35 +++ .../test/ProtocolTest/WebSocketTests.java | 85 +++++ .../java/io/kuzzle/test/TestableKuzzle.java | 51 +++ 76 files changed, 2774 insertions(+), 3151 deletions(-) rename kuzzle-sdk-java/build.gradle => build.gradle (100%) rename {kuzzle-sdk-java/gradle => gradle}/wrapper/gradle-wrapper.jar (100%) delete mode 100644 kuzzle-sdk-java/.project delete mode 100644 kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.properties delete mode 100755 kuzzle-sdk-java/gradlew delete mode 100644 kuzzle-sdk-java/gradlew.bat delete mode 100644 kuzzle-sdk-java/package.json delete mode 100644 kuzzle-sdk-java/settings.gradle delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java delete mode 100644 kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java delete mode 100644 kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java create mode 100644 package.json create mode 100644 settings.gradle create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/Task.java create mode 100644 src/main/java/io/kuzzle/sdk/Events/EventListener.java create mode 100644 src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java rename {kuzzle-sdk-java/src => src}/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java (54%) create mode 100644 src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java create mode 100644 src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java create mode 100644 src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java rename {kuzzle-sdk-java/src => src}/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java (51%) create mode 100644 src/main/java/io/kuzzle/sdk/Helpers/Default.java create mode 100644 src/main/java/io/kuzzle/sdk/Kuzzle.java create mode 100644 src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java create mode 100644 src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java create mode 100644 src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java create mode 100644 src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java create mode 100644 src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java create mode 100644 src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java create mode 100644 src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java create mode 100644 src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java create mode 100644 src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java create mode 100644 src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java create mode 100644 src/test/java/io/kuzzle/test/Helpers/DefaultTests.java create mode 100644 src/test/java/io/kuzzle/test/KuzzleTests.java create mode 100644 src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java create mode 100644 src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java create mode 100644 src/test/java/io/kuzzle/test/TestableKuzzle.java diff --git a/.travis.yml b/.travis.yml index 5a99cb79..7f0c1e3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ jobs: node_js: 12 before_script: - - bash -c "cd kuzzle-sdk-java && npm run doc-prepare" + - bash -c "npm run doc-prepare" - npm run --prefix $TRAVIS_BUILD_DIR/doc/framework clone-repos script: - gem install typhoeus @@ -39,20 +39,20 @@ jobs: - python-pip install: - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - cd $TRAVIS_BUILD_DIR/ - gradle assemble script: - - cd kuzzle-sdk-java && npm run doc-prepare + - npm run doc-prepare - npm run doc-build && cd - deploy: provider: script script: - - cd kuzzle-sdk-java && npm run doc-upload && cd - + - npm run doc-upload && cd - skip_cleanup: true after_deploy: - - cd kuzzle-sdk-java && npm run doc-cloudfront && cd - + - npm run doc-cloudfront && cd - - stage: Deployment Doc Prod name: Deploy docs.kuzzle.io @@ -72,9 +72,9 @@ jobs: - python-pip install: - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - cd $TRAVIS_BUILD_DIR/ - gradle assemble - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - cd $TRAVIS_BUILD_DIR/ - gradle assemble script: - gradle check @@ -97,9 +97,9 @@ jobs: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ install: - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - cd $TRAVIS_BUILD_DIR/ - gradle assemble - - cd $TRAVIS_BUILD_DIR/kuzzle-sdk-java + - cd $TRAVIS_BUILD_DIR/ - gradle assemble script: - gradle build diff --git a/README.md b/README.md index a5e7b9fd..0d236d14 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ https://bintray.com/kuzzle/maven ```xml io.kuzzle - kuzzle-sdk-java + sdk-java 2.0.0 pom @@ -52,11 +52,11 @@ https://bintray.com/kuzzle/maven ### Gradle ```groovy -compile 'io.kuzzle:kuzzle-sdk-java:2.0.0' +compile 'io.kuzzle:sdk-java:2.0.0' ``` For amd64: ```groovy -compile 'io.kuzzle:kuzzle-sdk-java:2.0.0' +compile 'io.kuzzle:sdk-java:2.0.0' ``` diff --git a/kuzzle-sdk-java/build.gradle b/build.gradle similarity index 100% rename from kuzzle-sdk-java/build.gradle rename to build.gradle diff --git a/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.jar rename to gradle/wrapper/gradle-wrapper.jar diff --git a/kuzzle-sdk-java/.project b/kuzzle-sdk-java/.project deleted file mode 100644 index 1a097e23..00000000 --- a/kuzzle-sdk-java/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - kuzzle-sdk-java - Project kuzzle-sdk-java created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.properties b/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 44e7c4d1..00000000 --- a/kuzzle-sdk-java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/kuzzle-sdk-java/gradlew b/kuzzle-sdk-java/gradlew deleted file mode 100755 index af6708ff..00000000 --- a/kuzzle-sdk-java/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/kuzzle-sdk-java/gradlew.bat b/kuzzle-sdk-java/gradlew.bat deleted file mode 100644 index 0f8d5937..00000000 --- a/kuzzle-sdk-java/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/kuzzle-sdk-java/package.json b/kuzzle-sdk-java/package.json deleted file mode 100644 index 85f535a9..00000000 --- a/kuzzle-sdk-java/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "scripts": { - "doc-prepare": "cd ../doc && bash doc.sh prepare", - "doc-dev": "cd ../doc && bash doc.sh dev", - "doc-build": "cd ../doc && bash doc.sh build", - "doc-upload": "cd ../doc && bash doc.sh upload", - "doc-cloudfront": "cd ../doc && bash doc.sh cloudfront", - "doc-deploy": "npm run doc-upload && npm run doc-cloudfront", - "doc-netlify": "npm run doc-prepare && cd doc && bash doc.sh build-netlify" - } -} diff --git a/kuzzle-sdk-java/settings.gradle b/kuzzle-sdk-java/settings.gradle deleted file mode 100644 index b9be651a..00000000 --- a/kuzzle-sdk-java/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'kuzzle-sdk-java' - diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java deleted file mode 100644 index b471bf60..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java +++ /dev/null @@ -1,155 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Json; - -import com.google.gson.JsonSyntaxException; -import com.google.gson.TypeAdapter; -import com.google.gson.internal.LazilyParsedNumber; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.CoreClasses.Maps.Serializable; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class ConcurrentHashMapTypeAdapter extends TypeAdapter> { - - - @Override - public void write(JsonWriter out, ConcurrentHashMap map) throws IOException { - if (map == null) { - out.nullValue(); - } else { - out.beginObject(); - Iterator> iterator = map.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - out.name(String.valueOf(entry.getKey())); - writeObject(out, entry.getValue()); - } - - out.endObject(); - } - } - - @Override - public ConcurrentHashMap read(JsonReader in) throws IOException { - JsonToken peek = in.peek(); - if (peek == JsonToken.NULL) { - in.nextNull(); - return null; - } else if (peek == JsonToken.BEGIN_OBJECT) { - KuzzleMap map = new KuzzleMap(); - Object key; - Object value; - - in.beginObject(); - - while(in.hasNext()) { - key = in.nextName(); - value = readObject(in); - if (!map.containsKey(key)) { - map.put((String) key, value); - } else { - throw new JsonSyntaxException("duplicate key: " + key); - } - } - - in.endObject(); - - return map; - } - return null; - } - - private void writeObject(JsonWriter out, Object value) throws IOException { - if (value instanceof Number) { - out.value((Number)value); - } else if (value instanceof Boolean) { - out.value((Boolean)value); - } else if (value instanceof String) { - out.value((String)value); - } else if (value instanceof ArrayList) { - out.beginArray(); - Iterator - iterator = ((ArrayList)value).iterator(); - - while(iterator.hasNext()) { - writeObject(out, iterator.next()); - } - - out.endArray(); - } else if (value instanceof ConcurrentHashMap) { - out.beginObject(); - Iterator> - iterator = ((ConcurrentHashMap)value) - .entrySet() - .iterator(); - - while(iterator.hasNext()) { - Map.Entry e = iterator.next(); - out.name(e.getKey()); - writeObject(out, e.getValue()); - } - - out.endObject(); - } else if (value instanceof Serializable) { - try { - writeObject(out, ((Serializable)value).toMap()); - } catch (Exception e) { - throw new IOException(e); - } - } else if (value == null) { - out.nullValue(); - } - } - - private Object readObject(JsonReader in) throws IOException { - switch(in.peek()) { - case NUMBER: - String number = in.nextString(); - return new LazilyParsedNumber(number); - case BOOLEAN: - return in.nextBoolean(); - case STRING: - return in.nextString(); - case NULL: - in.nextNull(); - return null; - case BEGIN_ARRAY: - ArrayList array = new ArrayList<>(); - in.beginArray(); - - while(in.hasNext()) { - array.add(readObject(in)); - } - - in.endArray(); - return array; - case BEGIN_OBJECT: - KuzzleMap map = new KuzzleMap(); - in.beginObject(); - - while(in.hasNext()) { - String key = in.nextName(); - Object object = readObject(in); - if (object != null) { - map.put(key, object); - } - } - - in.endObject(); - return map; - case END_DOCUMENT: - case NAME: - case END_OBJECT: - case END_ARRAY: - default: - throw new IllegalArgumentException(); - } - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java deleted file mode 100644 index 7af35c7b..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Json; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import java.util.concurrent.ConcurrentHashMap; - -public class JsonSerializer { - private static Gson gson; - - static { - gson = new GsonBuilder() - .disableHtmlEscaping() - .disableInnerClassSerialization() - .serializeNulls() - .registerTypeAdapter( - ConcurrentHashMap.class, - new ConcurrentHashMapTypeAdapter() - ) - .create(); - } - - public static ConcurrentHashMap deserialize(String rawJson) { - return gson.fromJson(rawJson, ConcurrentHashMap.class); - } - - public static String serialize(ConcurrentHashMap map) { - return gson.toJson(map, ConcurrentHashMap.class); - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java deleted file mode 100644 index da2fe35e..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java +++ /dev/null @@ -1,251 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Maps; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -/** - * CustomMap is a Class that extends ConcurrentHashMap to be ThreadSafe - * and that has the purpose of giving a wrapper on top of ConcurrentHashMap to easily - * manipulate them. - */ -public class KuzzleMap extends ConcurrentHashMap { - - /** - * Convert à ConcurrentHashMap to a CustomMap - * @param map ConcurrentHashMap representing JSON. - * @return a CustomMap instance - */ - public static KuzzleMap from(ConcurrentHashMap map) { - if (map == null) { - return null; - } - if (map instanceof KuzzleMap) { - return (KuzzleMap) map; - } - return new KuzzleMap(map); - } - - /** - * Create a new instance of CustomMap - */ - public KuzzleMap() { - super(); - } - - /** - * Create a new instance of CustomMap from a ConcurrentHashMap. - * @param map ConcurrentHashMap representing JSON. - */ - public KuzzleMap(ConcurrentHashMap map) { - super(); - Iterator> it = map.entrySet().iterator(); - - while(it.hasNext()) { - Entry entry = it.next(); - this.put(entry.getKey(), entry.getValue()); - } - } - - @Override - public Object put(String s, Object o) { - Object obj = null; - if (o != null) { - obj = super.put(s, o); - } else { - obj = super.put(s, new Null()); - } - if (obj instanceof Null) { - return null; - } - return obj; - } - - @Override - public Object get(Object key) { - Object value = super.get(key); - if (value instanceof Null) { - return null; - } - return value; - } - - @Override - public Set> entrySet() { - Set> entrySet = super.entrySet(); - return entrySet.parallelStream().map((Entry entry) -> { - if (entry.getValue() instanceof Null) { - return new KuzzleMapEntry(entry.getKey(), entry.getValue(), this); - } - return entry; - }).collect(Collectors.toSet()); - } - - /** - * Check whether the key value is null or not. - * @param key a String representing the key. - * @return true if the value is null. - */ - public boolean isNull(String key) { - return super.get(key) instanceof Null; - } - /** - * Check whether the key value is a String or not. - * @param key a String representing the key. - * @return true if the key is a String. - */ - public boolean isString(String key) { - return super.get(key) instanceof String; - } - - /** - * Check whether the key value is a Boolean or not. - * @param key a String representing the key. - * @return true if the key is a Boolean. - */ - public boolean isBoolean(String key) { - return super.get(key) instanceof Boolean; - } - - /** - * Check whether the key value is a Number or not. - * @param key a String representing the key. - * @return true if the key is a Number. - */ - public boolean isNumber(String key) { - return super.get(key) instanceof Number; - } - - /** - * Check whether the key value is an ArrayList or not. - * @param key a String representing the key. - * @return true if the key is an ArrayList. - */ - public boolean isArrayList(String key) { - return super.get(key) instanceof ArrayList; - } - - /** - * Check whether the key value is a ConcurrentHashMap or not. - * @param key a String representing the key. - * @return true if the key is a ConcurrentHashMap. - */ - public boolean isMap(String key) { - return super.get(key) instanceof ConcurrentHashMap; - } - - /** - * Return the specified key value or null if the value is not a String. - * @param key a String representing the key. - * @return The String at the key or null - */ - public String getString(String key) { - return isString(key) - ? (String) super.get(key) - : null; - } - - /** - * Return the specified key value or null if the value is not a Boolean. - * @param key a String representing the key. - * @return The Boolean at the key or null - */ - public Boolean getBoolean(String key) { - return isBoolean(key) - ? (Boolean) super.get(key) - : null; - } - - /** - * Return the specified key value or null if the value is not a Number. - * @param key a String representing the key. - * @return The Number at the key or null - */ - public Number getNumber(String key) { - return isNumber(key) - ? (Number) super.get(key) - : null; - } - - /** - * Return the specified key value or null if the value is not an ArrayList. - * @param key a String representing the key. - * @return The ArrayList at the key or null - */ - public ArrayList getArrayList(String key) { - return isArrayList(key) - ? (ArrayList) super.get(key) - : null; - } - - /** - * Return the specified key value or null if the value is not a ConcurrentHashMap. - * @param key a String representing the key. - * @return The ConcurrentHashMap at the key or null - */ - public KuzzleMap getMap(String key) { - return isMap(key) - ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) - : null; - } - - /** - * Return the specified key value or the def value if the value is nul or not a String. - * @param key a String representing the key. - * @return The String at the key or def value - */ - public String optString(String key, String def) { - return isString(key) - ? (String) super.get(key) - : def; - } - - /** - * Return the specified key value or the def value if the value is nul or not a Boolean. - * @param key a String representing the key. - * @return The Boolean at the key or def value - */ - public Boolean optBoolean(String key, Boolean def) { - return isBoolean(key) - ? (Boolean) super.get(key) - : def; - } - - /** - * Return the specified key value or the def value if the value is nul or not a Number. - * @param key a String representing the key. - * @return The Number at the key or def value - */ - public Number optNumber(String key, Number def) { - return isNumber(key) - ? (Number) super.get(key) - : def; - } - - /** - * Return the specified key value or the def value if the value is nul or not an ArrayList. - * @param key a String representing the key. - * @return The ArrayList at the key or def value - */ - public ArrayList optArrayList(String key, ArrayList def) { - return isArrayList(key) - ? (ArrayList) super.get(key) - : def; - } - - /** - * Return the specified key value or the def value if the value is nul or not a ConcurrentHashMap. - * @param key a String representing the key. - * @return The ConcurrentHashMap at the key or def value - */ - public KuzzleMap optMap( - String key, - ConcurrentHashMap def - ) { - return isMap(key) - ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) - : KuzzleMap.from(def); - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java deleted file mode 100644 index a529fa78..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Maps; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class KuzzleMapEntry implements Map.Entry { - final String key; - Object value; - final ConcurrentHashMap map; - - public KuzzleMapEntry(String key, Object value, ConcurrentHashMap map) { - this.key = key; - this.value = value; - this.map = map; - } - - public String getKey() { - return this.key; - } - - public Object getValue() { - if (this.value instanceof Null) { - return null; - } - return this.value; - } - - public int hashCode() { - return this.key.hashCode() ^ this.value.hashCode(); - } - - public String toString() { - return this.key + "=" + this.value; - } - - public boolean equals(Object object) { - Object key; - Object value; - Map.Entry entry; - - if (!(object instanceof Map.Entry)) { - return false; - } - - entry = (Map.Entry) object; - key = entry.getKey(); - value = entry.getValue(); - return key != null && (value == this.value || (value != null && value.equals(this.value))); - } - - public Object setValue(Object value) { - if (value == null) { - Object oldValue = this.value; - this.value = new Null(); - this.map.put(this.key, this.value); - return oldValue; - } else { - Object oldValue = this.value; - this.value = value; - this.map.put(this.key, value); - return oldValue; - } - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java deleted file mode 100644 index d8e458da..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Maps; - -public class Null { - final int hashCode = 572487463; - public int hashCode() { - return hashCode; - } -} \ No newline at end of file diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java deleted file mode 100644 index ac5c7fa8..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Maps; - -import java.util.concurrent.ConcurrentHashMap; - -public interface Serializable { - void fromMap(ConcurrentHashMap map) throws Exception; - ConcurrentHashMap toMap() throws Exception; -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java deleted file mode 100644 index 1cde349c..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Responses; - -import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.CoreClasses.Maps.Serializable; - -import java.util.concurrent.ConcurrentHashMap; - -public class ErrorResponse implements Serializable { - - public ErrorResponse() { - - } - - /** - * Response status, following HTTP status codes. - */ - public int status; - - /** - * Error message - */ - public String message; - - /** - * Error ID - */ - public String id; - - /** - * Error stack - */ - public String stack; - - @Override - public void fromMap(ConcurrentHashMap map) { - if (map == null) return; - - KuzzleMap kuzzleMap = KuzzleMap.from(map); - - status = kuzzleMap.optNumber("status", 0).intValue(); - message = kuzzleMap.getString("message"); - stack = kuzzleMap.getString("stack"); - id = kuzzleMap.getString("id"); - } - - @Override - public ConcurrentHashMap toMap() { - ConcurrentHashMap map = new KuzzleMap(); - - map.put("status", status); - map.put("message", message); - map.put("stack", stack); - map.put("id", id); - return map; - } -} - diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java deleted file mode 100644 index 16c633b2..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java +++ /dev/null @@ -1,142 +0,0 @@ -package io.kuzzle.sdk.CoreClasses.Responses; - -import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.CoreClasses.Maps.Serializable; -import io.kuzzle.sdk.Exceptions.InternalException; -import io.kuzzle.sdk.Exceptions.KuzzleException; -import io.kuzzle.sdk.Exceptions.KuzzleExceptionCode; - -import java.util.concurrent.ConcurrentHashMap; - -public class Response implements Serializable { - - public String room; - - /** - * Response payload (depends on the executed API action) - */ - public Object result; - - /** - * Error object (null if the request finished successfully) - */ - public ErrorResponse error; - - /** - * Request unique identifier. - */ - public String requestId; - - /** - * Response status, following HTTP status codes - */ - public int status; - - /** - * Executed Kuzzle API controller. - */ - public String controller; - - /** - * Executed Kuzzle API controller's action. - */ - public String action; - - /** - * Impacted data index. - */ - public String index; - - /** - * Impacted data collection. - */ - public String collection; - - /** - * Volatile data. - */ - public ConcurrentHashMap Volatile; - - // The following properties are specific to real-time notifications - - /** - * Network protocol at the origin of the real-time notification. - */ - public String protocol; - - /** - * Document scope ("in" or "out") - */ - public String scope; - - /** - * Document state - */ - public String state; - - /** - * Notification timestamp (UTC) - */ - public Long timestamp; - - /** - * Notification type - */ - public String type; - - @Override - public void fromMap(ConcurrentHashMap map) throws InternalException { - if (map == null) return; - - KuzzleMap kuzzleMap = KuzzleMap.from(map); - - room = kuzzleMap.getString("room"); - result = kuzzleMap.get("result"); - error = null; - if (kuzzleMap.isMap("error")) { - error = new ErrorResponse(); - error.fromMap(kuzzleMap.getMap("error")); - } - requestId = kuzzleMap.getString("requestId"); - if (requestId == null) { - throw new InternalException(KuzzleExceptionCode.MISSING_REQUESTID); - } - status = kuzzleMap.optNumber("status", 0).intValue(); - controller = kuzzleMap.getString("controller"); - action = kuzzleMap.getString("action"); - index = kuzzleMap.getString("index"); - collection = kuzzleMap.getString("collection"); - Volatile = kuzzleMap.optMap( - "volatile", - new ConcurrentHashMap<>() - ); - protocol = kuzzleMap.getString("protocol"); - scope = kuzzleMap.getString("scope"); - state = kuzzleMap.getString("state"); - timestamp = (Long) kuzzleMap.getNumber("timestamp"); - type = kuzzleMap.getString("type"); - } - - @Override - public ConcurrentHashMap toMap() { - ConcurrentHashMap map = new KuzzleMap(); - - map.put("room", room); - map.put("result", result); - map.put("error", error); - map.put("requestId", requestId); - map.put("status", status); - map.put("controller", controller); - map.put("action", action); - map.put("index", index); - map.put("collection", collection); - map.put("volatile", Volatile); - map.put("protocol", protocol); - map.put("scope", scope); - map.put("status", status); - map.put("timestamp", timestamp); - map.put("type", type); - - return map; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java deleted file mode 100644 index f01c73cb..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java +++ /dev/null @@ -1,100 +0,0 @@ -package io.kuzzle.sdk.CoreClasses; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @param The object type that the task return. - */ -public class Task { - /** - * A countDownLatch used to lock the future. - */ - protected CountDownLatch countDownLatch; - /** - * A completable future. - */ - protected CompletableFuture future; - - /** - * The object instance to return. - */ - protected AtomicReference atomicReference; - - - /** - * Initializes a new instance of the Task. - */ - public Task() { - atomicReference = new AtomicReference(); - countDownLatch = new CountDownLatch(1); - future = CompletableFuture.supplyAsync(() -> { - try { - countDownLatch.await(); - - return atomicReference.get(); - } catch (InterruptedException e) { - return null; - } - }); - } - - /** - * @return The associated CompletableFuture. - */ - public CompletableFuture getFuture() { - return future; - } - - /** Set the exception of the CompletableFuture. - * @param exception - */ - public void setException(Exception exception) { - future.completeExceptionally(exception); - } - - /** - * @return true if future is cancelled. - */ - public boolean isCancelled() { - return future.isCancelled(); - } - - /** - * @return true if the future is done. - */ - public boolean isDone() { - return future.isDone(); - } - - /** - * @return true if the future has been completed exceptionally. - */ - public boolean isCompletedExceptionally() { - return future.isCompletedExceptionally(); - } - - /** Set if the future is cancelled. - * @param state - */ - public void setCancelled(boolean state) { - future.cancel(state); - } - - - /** - * Unlock the future. - */ - public void trigger() { - countDownLatch.countDown(); - } - - /** Unlock the future and set the object. - * @param object - */ - public void trigger(T object) { - atomicReference.set(object); - countDownLatch.countDown(); - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java deleted file mode 100644 index 7cf5e829..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Events/EventListener.java +++ /dev/null @@ -1,74 +0,0 @@ -package io.kuzzle.sdk.Events; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class EventListener { - - /** - * Set of registered callbacks. - */ - protected Set callbacks; - - /** - * Initializes a new instance of the EventListener. - */ - public EventListener() { - callbacks = ConcurrentHashMap.newKeySet(); - } - - /** Register a callback that takes a parameter. - * @param callback - * @return If successfully registered. - */ - public boolean register(final Consumer callback) { - return callbacks.add(callback); - } - - /** Register a callback with no parameter. - * @param callback - * @return If successfully registered. - */ - public boolean register(final Runnable callback) { - return callbacks.add(callback); - } - - /** Unregister a callback that takes a parameter. - * @param callback - * @return If successfully unregistered. - */ - public boolean unregister(final Consumer callback) { - return callbacks.remove(callback); - } - - /** Unregister a callback with no parameter. - * @param callback - * @return If successfully unregistered. - */ - public boolean unregister(final Runnable callback) { - return callbacks.remove(callback); - } - - /** Triggers every callbacks that have a parameter with the given object. - * @param obj An Object. - */ - public void trigger(final T obj) { - for (Object callback : callbacks) { - if (callback instanceof Consumer) { - ((Consumer)callback).accept(obj); - } - } - } - - /** - * Triggers every callbacks that doesn't have a parameter. - */ - public void trigger() { - for (Object callback : callbacks) { - if (callback instanceof Runnable) { - ((Runnable)callback).run(); - } - } - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java deleted file mode 100644 index 91ad7d5f..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.kuzzle.sdk.Exceptions; - -import io.kuzzle.sdk.CoreClasses.Responses.Response; - -/** - * Passed to async tasks when an API request returns an error. - */ -public class ApiErrorException extends KuzzleException { - /** - * Kuzzle API stack trace - */ - protected String stack; - - /** - * Kuzzle API error unique identifier - */ - protected String id; - - /** - * Initializes a new instance of the ApiErrorException - * @param response Kuzzle API Response. - */ - public ApiErrorException(Response response) { - super(response.error != null - ? response.error.message - : null, - response.status); - if (response.error != null) { - this.stack = response.error.stack; - this.id = response.error.id; - } - } - - public String getStack() { - return this.stack; - } - - public String getId() { - return this.id; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java deleted file mode 100644 index 25d7d2b8..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.kuzzle.sdk.Exceptions; - -/** - * Passed to async tasks when an API request returns an error. - */ -public class InternalException extends KuzzleException { - - /** - * Initializes a new instance of the InternalException - */ - public InternalException(String message, KuzzleExceptionCode status) { - super(message, status); - } - - public InternalException(KuzzleExceptionCode status) { - super(status); - } - -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java deleted file mode 100644 index b40d76db..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.kuzzle.sdk.Exceptions; - -/** - * Root of all Kuzzle exceptions. - */ -public class KuzzleException extends Exception { - - /** - * Kuzzle API error code. - */ - protected int status; - - /** Initializes a new instance of the KuzzleException. - * @param message Message. - * @param status Status. - */ - protected KuzzleException(String message, int status) { - super(message); - this.status = status; - } - - protected KuzzleException(String message, KuzzleExceptionCode status) { - super(message); - this.status = status.getCode(); - } - - protected KuzzleException(KuzzleExceptionCode status) { - super(status.getMessage()); - this.status = status.getCode(); - } - - /** - * @return The status code of the exception. - */ - public int getStatus() { - return status; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java deleted file mode 100644 index ba7ad958..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.kuzzle.sdk.Exceptions; - -public enum KuzzleExceptionCode { - MISSING_REQUESTID(0, "Missing field requestId"), - MSSING_QUERY(400, "You must provide a query"), - NOT_CONNECTED(500, "Not connected."), - CONNECTION_LOST(500, "Connection lost"), - WRONG_VOLATILE_TYPE(400, "Volatile data must be a ConcurrentHashMap"); - - private final int code; - private final String message; - - KuzzleExceptionCode(final int code) { - this.code = code; - this.message = null; - } - - KuzzleExceptionCode(final int code, String message) { - this.code = code; - this.message = message; - } - - public int getCode() { - return this.code; - } - - public String getMessage() { - return this.message; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java deleted file mode 100644 index 032609f9..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Helpers/Default.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.kuzzle.sdk.Helpers; - -public class Default { - - /** Return the object or its default value in the case of the object is null. - * @param obj An object. - * @param defaultValue A default value in case your object is null. - * @param Object class. - * @return The object or the specified default value in case the object is null. - */ - public static T defaultValue(T obj, T defaultValue) { - return obj != null ? obj : defaultValue; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java deleted file mode 100644 index a0e0a1e2..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ /dev/null @@ -1,292 +0,0 @@ -package io.kuzzle.sdk; - -import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; -import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.CoreClasses.Task; -import io.kuzzle.sdk.Events.EventListener; -import io.kuzzle.sdk.Exceptions.*; -import io.kuzzle.sdk.Options.KuzzleOptions; -import io.kuzzle.sdk.Protocol.AbstractProtocol; -import io.kuzzle.sdk.Protocol.ProtocolState; - -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import io.kuzzle.sdk.CoreClasses.Responses.*; - -import static io.kuzzle.sdk.Helpers.Default.defaultValue; - -public class Kuzzle { - - protected EventListener tokenExpiredEvent; - protected EventListener unhandledResponseEvent; - - protected final AbstractProtocol networkProtocol; - - public final String version; - public final String instanceId; - public final String sdkName; - - /** - * Authentication token - */ - protected AtomicReference authenticationToken; - - - /** - * The maximum amount of elements that the queue can contains. - * If set to -1, the size is unlimited. - */ - protected AtomicInteger maxQueueSize; - - - /** - * The minimum duration of a Token before being automatically refreshed. - * If set to -1 the SDK does not refresh the token automatically. - */ - protected AtomicInteger minTokenDuration; - - - /** - * The minimum duration of a Token after refresh. - * If set to -1 the SDK does not refresh the token automatically. - */ - protected AtomicInteger refreshedTokenDuration; - - /** - * The maximum delay between two requests to be replayed - */ - protected AtomicInteger maxRequestDelay; - - protected ConcurrentHashMap> - requests = new ConcurrentHashMap<>(); - - /** Initialize a new instance of Kuzzle - * @param networkProtocol The network protocol - * @throws IllegalArgumentException - */ - public Kuzzle(AbstractProtocol networkProtocol) - throws IllegalArgumentException { - this(networkProtocol, new KuzzleOptions()); - } - - /** Initialize a new instance of Kuzzle - * @param networkProtocol The network protocol - * @param options Kuzzle options - * @throws IllegalArgumentException - */ - public Kuzzle( - AbstractProtocol networkProtocol, - final KuzzleOptions options - ) throws IllegalArgumentException { - - if (networkProtocol == null) { - throw new IllegalArgumentException("networkProtocol can't be null"); - } - - KuzzleOptions kOptions = options != null - ? options - : new KuzzleOptions(); - - this.networkProtocol = networkProtocol; - this.networkProtocol.registerResponseEvent(this::onResponseReceived); - this.networkProtocol.registerStateChangeEvent(this::onStateChanged); - - this.maxQueueSize = new AtomicInteger(kOptions.getMaxQueueSize()); - this.minTokenDuration = new AtomicInteger(kOptions.getMinTokenDuration()); - this.refreshedTokenDuration = new AtomicInteger(kOptions.getRefreshedTokenDuration()); - this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); - - this.version = "3.0.0"; - this.instanceId = UUID.randomUUID().toString(); - this.sdkName = "java@"+version; - - this.tokenExpiredEvent = new EventListener(); - this.unhandledResponseEvent = new EventListener<>(); - } - - /** Establish a network connection - * @throws Exception - */ - public void connect() throws Exception { - networkProtocol.connect(); - } - - /** - * Disconnect this instance - */ - public void disconnect() { - networkProtocol.disconnect(); - } - - /** Handles the ResponseReceivedEvent from the network protocol - * @param payload Raw API Response - */ - protected void onResponseReceived(String payload) { - - Response response = new Response(); - try { - response.fromMap(JsonSerializer.deserialize(payload)); - } catch (InternalException e) { - e.printStackTrace(); - return; - } - - if (response.room == null - || !requests.containsKey(response.room) - ) { - unhandledResponseEvent.trigger(response); - return; - } - - if (response.error == null) { - Task task = requests.get(response.requestId); - - if (task != null) { - task.trigger(response); - } - - requests.remove(response.requestId); - return; - } - - if (response.error.id == null - || !response.error.id.equals("security.token.expired") - ) { - Task task = requests.get(response.requestId); - if (task != null) { - task.setException(new ApiErrorException(response)); - } - return; - } - - tokenExpiredEvent.trigger(); - } - - protected void onStateChanged(ProtocolState state) { - // If not connected anymore: close tasks and clean up the requests buffer - if (state == ProtocolState.CLOSE) { - for (Task task : requests.values()) { - task.setException(new ConnectionLostException()); - } - requests.clear(); - } - } - - /** Registers a callback to be called when the token expires - * @param callback A callback - * @return true if success - */ - public boolean registerTokenExpiredEvent(Runnable callback) { - return tokenExpiredEvent.register(callback); - } - - /** Unregisters a previously registered callback for the TokenExpired event - * @param callback A callback - * @return true if success - */ - public boolean unregisterTokenExpiredEvent(Runnable callback) { - return tokenExpiredEvent.unregister(callback); - } - - /** Registers a callback to be called when a response is unhandled - * @param callback A callback - * @return true if success - */ - public boolean registerUnhandledResponseEvent(Consumer callback) { - return unhandledResponseEvent.register(callback); - } - - /** - * @param callback Unregisters a previously registered callback for the UnhandledResponse event - * @return true if success - */ - public boolean unregisterUnhandledResponseEvent(Consumer callback) { - return unhandledResponseEvent.unregister(callback); - } - - /** - * Triggers the TokenExpired event - */ - public void dispatchTokenExpired() { - tokenExpiredEvent.trigger(); - } - - /** Sends an API request to Kuzzle and returns the corresponding API - * @param query Kuzzle API query - * @return A CompletableFuture - * @throws InternalException - * @throws NotConnectedException - */ - public CompletableFuture query(ConcurrentHashMap query) - throws InternalException, NotConnectedException { - if (query == null) { - throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); - } - - if (networkProtocol.getState() == ProtocolState.CLOSE) { - throw new NotConnectedException(); - } - - KuzzleMap queryMap = KuzzleMap.from(query); - - if (queryMap.contains("waitForRefresh")) { - if (queryMap.optBoolean("waitForRefresh", false).booleanValue()) { - queryMap.put("refresh", "wait_for"); - } - queryMap.remove("waitForRefresh"); - } - - if (authenticationToken != null) { - queryMap.put("jwt", authenticationToken); - } - - String requestId = UUID.randomUUID().toString(); - - queryMap.put("requestId", requestId); - - if (!queryMap.containsKey("volatile") - || queryMap.isNull("volatile") - ) { - queryMap.put("volatile", new KuzzleMap()); - } else if (!queryMap.isMap("volatile")) { - throw new InternalException(KuzzleExceptionCode.WRONG_VOLATILE_TYPE); - } - - queryMap.getMap("volatile") - .put("sdkVersion", version); - - queryMap.getMap("volatile") - .put("sdkInstanceId", instanceId); - - queryMap.getMap("volatile") - .put("sdkName", sdkName); - - Task task = new Task<>(); - requests.put(requestId, task); - - if (networkProtocol.getState() == ProtocolState.OPEN) { - networkProtocol.send(queryMap); - } - - return task.getFuture(); - } - - /** - * @return The authentication token - */ - public String getAuthenticationToken() { - return authenticationToken.get(); - } - - /** Set the authentication token - * @param token Authentication token - */ - public void setAuthenticationToken(String token) { - authenticationToken.set(token); - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java deleted file mode 100644 index e9f272dd..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java +++ /dev/null @@ -1,140 +0,0 @@ -package io.kuzzle.sdk.Options; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Predicate; - -import static io.kuzzle.sdk.Helpers.Default.defaultValue; - -public class KuzzleOptions { - - /** - * The maximum amount of elements that the queue can contains. - * If set to -1, the size is unlimited. - */ - private int maxQueueSize = -1; - - /** - * The minimum duration of a Token before being automatically refreshed. - * If set to -1 the SDK does not refresh the token automatically. - */ - private int minTokenDuration = 3_600_000; - - /** - * The minimum duration of a Token after refresh. - * If set to -1 the SDK does not refresh the token automatically. - */ - private int refreshedTokenDuration = 3_600_000; - - /** - * The maximum delay between two requests to be replayed. - */ - private int maxRequestDelay = 1000; - - private Predicate> filter = (ConcurrentHashMap obj) -> true; - - /** - * Initialize a new KuzzleOptions instance. - */ - public KuzzleOptions() {} - - /** Initialize a new KuzzleOptions instance and copy other KuzzleOptions fields - * @param options - */ - public KuzzleOptions(KuzzleOptions options) { - this.maxQueueSize = options.maxQueueSize; - this.minTokenDuration = options.minTokenDuration; - this.refreshedTokenDuration = options.refreshedTokenDuration; - - this.maxRequestDelay = options.maxRequestDelay; - - this.filter = options.filter; - } - - /** - * @return The maximum amount of elements that the queue can contains. - * If set to -1, the size is unlimited. - */ - public int getMaxQueueSize() { - return maxQueueSize; - } - - /** Set the maximum amount of elements that the queue can contains. - * If set to -1, the size is unlimited. - * @param maxQueueSize - * @return This KuzzleOptions instance - */ - public KuzzleOptions withMaxQueueSize(int maxQueueSize) { - this.maxQueueSize = maxQueueSize < 0 - ? -1 - : maxQueueSize; - - return this; - } - - /** - * @return The minimum duration of a Token before being automatically refreshed. - * If set to -1 the SDK does not refresh the token automatically. - */ - public int getMinTokenDuration() { - return minTokenDuration; - } - - /** Set the minimum duration of a Token before being automatically refreshed. - * If set to -1 the SDK does not refresh the token automatically. - * @param minTokenDuration - * @return This KuzzleOptions instance - */ - public KuzzleOptions withMinTokenDuration(int minTokenDuration) { - this.minTokenDuration = minTokenDuration < 0 - ? -1 - : minTokenDuration; - - return this; - } - - /** - * @return The minimum duration of a Token after refresh. - * If set to -1 the SDK does not refresh the token automatically. - */ - public int getRefreshedTokenDuration() { - return refreshedTokenDuration; - } - - /** Set the minimum duration of a Token after refresh. - * If set to -1 the SDK does not refresh the token automatically. - * @param refreshedTokenDuration - * @return This KuzzleOptions instance - */ - public KuzzleOptions withRefreshedTokenDuration(int refreshedTokenDuration) { - this.refreshedTokenDuration = refreshedTokenDuration < 0 - ? -1 - : refreshedTokenDuration; - - return this; - } - - /** - * @return The maximum delay between two requests to be replayed. - */ - public int getMaxRequestDelay() { - return maxRequestDelay; - } - - /** Set the maximum delay between two requests to be replayed. - * @param maxRequestDelay - * @return This KuzzleOptions instance - */ - public KuzzleOptions withMaxRequestDelay(int maxRequestDelay) { - this.maxRequestDelay = maxRequestDelay; - return this; - } - - public Predicate> getFilter() { - return filter; - } - - public KuzzleOptions withFilter(Predicate> filter) { - this.filter = defaultValue(filter, (ConcurrentHashMap obj) -> true); - return this; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java deleted file mode 100644 index 9db683a0..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java +++ /dev/null @@ -1,113 +0,0 @@ -package io.kuzzle.sdk.Options.Protocol; - -import io.kuzzle.sdk.Options.KuzzleOptions; - -public class WebSocketOptions { - - /** - * The port to use to connect. - */ - private int port = 7512; - - /** - * If we use SSL connection. - */ - private boolean ssl = false; - - /** - * The duration before the connection timeout. - */ - private int connectionTimeout = -1; - - /** - * If the websocket auto reconnects. - */ - private boolean autoReconnect = true; - - /** - * Initialize a new WebSocketOptions instance. - */ - public WebSocketOptions() {} - - - /** Initialize a new WebSocketOptions instance and copy other WebSocketOptions fields - * @param other - */ - public WebSocketOptions(WebSocketOptions other) { - this.port = other.port; - this.ssl = other.ssl; - this.connectionTimeout = other.connectionTimeout; - this.autoReconnect = other.autoReconnect; - } - - /** - * @return The port used to connect. - */ - public int getPort() { - return port; - } - - /** Set the port to use to connect. - * @param port - * @return This WebSocketOptions instance. - */ - public WebSocketOptions withPort(int port) { - this.port = - port >= 0 - ? port - : 7512; - return this; - } - - /** - * @return If we use SSL connection. - */ - public boolean isSsl() { - return ssl; - } - - /** Set if we use SSL connection. - * @param ssl - * @return This WebSocketOptions instance. - */ - public WebSocketOptions withSsl(boolean ssl) { - this.ssl = ssl; - return this; - } - - /** - * @return The duration before the connection timeout. - */ - public int getConnectionTimeout() { - return connectionTimeout; - } - - /** Set the duration before the connection timeout. - * @param connectionTimeout - * @return This WebSocketOptions instance. - */ - public WebSocketOptions withConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = - connectionTimeout < 0 - ? -1 - : connectionTimeout; - return this; - } - - - /** - * @return If the websocket auto reconnects. - */ - public boolean isAutoReconnect() { - return autoReconnect; - } - - /** Set if the websocket auto reconnects. - * @param autoReconnect - * @return This WebSocketOptions instance. - */ - public WebSocketOptions withAutoReconnect(boolean autoReconnect) { - this.autoReconnect = autoReconnect; - return this; - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java deleted file mode 100644 index bfdf17b1..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java +++ /dev/null @@ -1,79 +0,0 @@ -package io.kuzzle.sdk.Protocol; - -import io.kuzzle.sdk.Events.EventListener; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public abstract class AbstractProtocol { - protected EventListener stateChanged; - protected EventListener messageReceived; - - public AbstractProtocol() { - stateChanged = new EventListener<>(); - messageReceived = new EventListener<>(); - } - - /** Current connection state. - * @return The state. - */ - public abstract ProtocolState getState(); - - /** connect this instance. - * @throws Exception - */ - public abstract void connect() throws Exception; - - /** - * Disconnect this instance. - */ - public abstract void disconnect(); - - /** Send the specified payload to Kuzzle. - * @param payload - */ - public abstract void send(ConcurrentHashMap payload); - - - /** - * Register to the Response event - */ - public boolean registerResponseEvent(Consumer callback) { - return messageReceived.register(callback); - } - - /** - * Unregister from the Response event - */ - public boolean unregisterResponseEvent(Consumer callback) { - return messageReceived.unregister(callback); - } - - /** - * Register to the StateChange event - */ - public boolean registerStateChangeEvent(Consumer callback) { - return stateChanged.register(callback); - } - - /** - * Unregister from the StateChange event - */ - public boolean unregisterStateChangeEvent(Consumer callback) { - return stateChanged.unregister(callback); - } - - - /** Dispatch a state changed event. - * @param state The ProtocolState. - */ - protected void dispatchStateChangeEvent(ProtocolState state) { - stateChanged.trigger(state); - } - - /** Dispatch a message received from a Kuzzle server. - * @param message Kuzzle API response. - */ - protected void dispatchResponseEvent(String message) { - messageReceived.trigger(message); - } -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java deleted file mode 100644 index 4ecb67b2..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.kuzzle.sdk.Protocol; - -public enum ProtocolState { - CLOSE, // The network protocol does not accept requests. - OPEN, // The network protocol accepts new requests. -} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java b/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java deleted file mode 100644 index 1cbf482c..00000000 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java +++ /dev/null @@ -1,186 +0,0 @@ -package io.kuzzle.sdk.Protocol; - -import com.neovisionaries.ws.client.WebSocketAdapter; -import com.neovisionaries.ws.client.WebSocketFactory; -import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; -import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; - -import javax.net.ssl.SSLSocketFactory; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.concurrent.*; - -public class WebSocket extends AbstractProtocol { - - protected BlockingDeque> queue; - protected com.neovisionaries.ws.client.WebSocket socket; - protected ProtocolState state = ProtocolState.CLOSE; - protected URI uri; - - protected final boolean ssl; - protected final int port; - protected int connectionTimeout; - - public ProtocolState getState() { - return state; - } - - public WebSocket(URI uri) - throws Exception { - WebSocketOptions options = new WebSocketOptions(); - if (uri.getPort() > -1) { - options.withPort(uri.getPort()); - } - if (uri.getHost() == null || uri.getHost().isEmpty()) { - throw new URISyntaxException("Missing host", "Could not find host part"); - } - if (uri.getScheme() != null) { - options.withSsl(uri.getScheme().equals("wss")); - } - WebSocketOptions wsOptions = - options != null - ? new WebSocketOptions(options) - : new WebSocketOptions(); - - ssl = wsOptions.isSsl(); - port = wsOptions.getPort(); - connectionTimeout = wsOptions.getConnectionTimeout(); - - this.uri = new URI((ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); - this.queue = new LinkedBlockingDeque<>(); - } - - public WebSocket( - URI uri, - WebSocketOptions options - ) throws URISyntaxException, IllegalArgumentException { - this(uri.getHost(), options); - } - - public WebSocket(String host) - throws URISyntaxException, IllegalArgumentException { - this(host, new WebSocketOptions()); - } - - /** - * @param host Kuzzle host address - * @param options WebSocket options - * @throws URISyntaxException - * @throws IllegalArgumentException - */ - public WebSocket( - String host, - WebSocketOptions options - ) throws URISyntaxException, IllegalArgumentException { - super(); - - WebSocketOptions wsOptions = - options != null - ? new WebSocketOptions(options) - : new WebSocketOptions(); - - ssl = wsOptions.isSsl(); - port = wsOptions.getPort(); - connectionTimeout = wsOptions.getConnectionTimeout(); - - if (host == null || host.isEmpty()) { - throw new IllegalArgumentException("Host name/address can't be empty"); - } - this.uri = new URI((ssl ? "wss" : "ws") + "://" + host + ":" + port + "/"); - this.queue = new LinkedBlockingDeque<>(); - } - - @Override - public void send(ConcurrentHashMap payload) { - queue.add(payload); - } - - protected com.neovisionaries.ws.client.WebSocket createClientSocket() - throws IOException - { - WebSocketFactory wsFactory = new WebSocketFactory(); - - if (connectionTimeout > -1) { - wsFactory = wsFactory.setConnectionTimeout(connectionTimeout); - } - - if (ssl) { - - wsFactory.setSocketFactory(SSLSocketFactory.getDefault()); - } - - return wsFactory.createSocket(uri); - } - - /** Connects to a Kuzzle server. - * @throws Exception - */ - @Override - public void connect() throws Exception { - if (socket != null) { - return; - } - - socket = createClientSocket(); - - socket.connect(); - state = ProtocolState.OPEN; - dispatchStateChangeEvent(state); - Dequeue(); - - socket.addListener(new WebSocketAdapter() { - @Override - public void onTextMessage( - com.neovisionaries.ws.client.WebSocket websocket, - String text - ) throws Exception { - super.onTextMessage(websocket, text); - dispatchResponseEvent(text); - } - }); - } - - /** - * Disconnects this instance. - */ - @Override - public void disconnect() { - CloseState(); - } - - protected void CloseState() { - if (socket != null) { - socket.disconnect(); - state = ProtocolState.CLOSE; - socket = null; - dispatchStateChangeEvent(state); - } - } - - protected Thread Dequeue() { - Thread thread = new Thread(() -> { - while (state == ProtocolState.OPEN) { - ConcurrentHashMap payload = queue.poll(); - if (payload != null) { - String rawJson = JsonSerializer.serialize(payload); - socket.sendText(rawJson); - } - } - }); - thread.start(); - return thread; - } - - public int getConnectionTimeout() { - return connectionTimeout; - } - - public void setConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = - connectionTimeout < 0 - ? -1 - : connectionTimeout; - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java deleted file mode 100644 index 8b46dff3..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java +++ /dev/null @@ -1,239 +0,0 @@ -package io.kuzzle.test.CoreClasses.TaskTest; - -import com.sun.org.apache.xpath.internal.operations.Bool; -import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.test.TestableKuzzle; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -public class KuzzleMapTest { - private KuzzleMap kuzzleMap; - - @Before - public void setup() throws URISyntaxException { - kuzzleMap = new KuzzleMap(); - kuzzleMap.put("String", "String"); - kuzzleMap.put("Number", 0); - kuzzleMap.put("Boolean", false); - kuzzleMap.put("ArrayList", new ArrayList<>()); - kuzzleMap.put("Map", new ConcurrentHashMap<>()); - kuzzleMap.put("KuzzleMap", new KuzzleMap()); - kuzzleMap.put("Null", null); - } - - @Test - public void isString() { - Assert.assertTrue(kuzzleMap.isString("String")); - Assert.assertFalse(kuzzleMap.isString("Number")); - Assert.assertFalse(kuzzleMap.isString("Boolean")); - Assert.assertFalse(kuzzleMap.isString("ArrayList")); - Assert.assertFalse(kuzzleMap.isString("Map")); - Assert.assertFalse(kuzzleMap.isString("KuzzleMap")); - Assert.assertFalse(kuzzleMap.isString("Null")); - Assert.assertFalse(kuzzleMap.isString("UnknownKey")); - } - - @Test - public void isNumber() { - Assert.assertFalse(kuzzleMap.isNumber("String")); - Assert.assertTrue(kuzzleMap.isNumber("Number")); - Assert.assertFalse(kuzzleMap.isNumber("Boolean")); - Assert.assertFalse(kuzzleMap.isNumber("ArrayList")); - Assert.assertFalse(kuzzleMap.isNumber("Map")); - Assert.assertFalse(kuzzleMap.isNumber("KuzzleMap")); - Assert.assertFalse(kuzzleMap.isNumber("Null")); - Assert.assertFalse(kuzzleMap.isNumber("UnknownKey")); - } - - @Test - public void isBoolean() throws Exception { - Assert.assertFalse(kuzzleMap.isBoolean("String")); - Assert.assertFalse(kuzzleMap.isBoolean("Number")); - Assert.assertTrue(kuzzleMap.isBoolean("Boolean")); - Assert.assertFalse(kuzzleMap.isBoolean("ArrayList")); - Assert.assertFalse(kuzzleMap.isBoolean("Map")); - Assert.assertFalse(kuzzleMap.isBoolean("KuzzleMap")); - Assert.assertFalse(kuzzleMap.isBoolean("Null")); - Assert.assertFalse(kuzzleMap.isBoolean("UnknownKey")); - } - - @Test - public void isArrayList() { - Assert.assertFalse(kuzzleMap.isArrayList("String")); - Assert.assertFalse(kuzzleMap.isArrayList("Number")); - Assert.assertFalse(kuzzleMap.isArrayList("Boolean")); - Assert.assertTrue(kuzzleMap.isArrayList("ArrayList")); - Assert.assertFalse(kuzzleMap.isArrayList("Map")); - Assert.assertFalse(kuzzleMap.isArrayList("KuzzleMap")); - Assert.assertFalse(kuzzleMap.isArrayList("Null")); - Assert.assertFalse(kuzzleMap.isArrayList("UnknownKey")); - } - - @Test - public void isMap() { - Assert.assertFalse(kuzzleMap.isMap("String")); - Assert.assertFalse(kuzzleMap.isMap("Number")); - Assert.assertFalse(kuzzleMap.isMap("Boolean")); - Assert.assertFalse(kuzzleMap.isMap("ArrayList")); - Assert.assertTrue(kuzzleMap.isMap("Map")); - Assert.assertTrue(kuzzleMap.isMap("KuzzleMap")); - Assert.assertFalse(kuzzleMap.isMap("Null")); - Assert.assertFalse(kuzzleMap.isMap("UnknownKey")); - } - - @Test - public void isNull() { - Assert.assertFalse(kuzzleMap.isNull("String")); - Assert.assertFalse(kuzzleMap.isNull("Number")); - Assert.assertFalse(kuzzleMap.isNull("Boolean")); - Assert.assertFalse(kuzzleMap.isNull("ArrayList")); - Assert.assertFalse(kuzzleMap.isNull("Map")); - Assert.assertFalse(kuzzleMap.isNull("KuzzleMap")); - Assert.assertTrue(kuzzleMap.isNull("Null")); - Assert.assertFalse(kuzzleMap.isNull("UnknownKey")); - } - - @Test - public void getString() { - Assert.assertNotNull(kuzzleMap.getString("String")); - Assert.assertNull(kuzzleMap.getString("Number")); - Assert.assertNull(kuzzleMap.getString("Boolean")); - Assert.assertNull(kuzzleMap.getString("ArrayList")); - Assert.assertNull(kuzzleMap.getString("Map")); - Assert.assertNull(kuzzleMap.getString("KuzzleMap")); - Assert.assertNull(kuzzleMap.getString("Null")); - Assert.assertNull(kuzzleMap.getString("UnknownKey")); - } - - @Test - public void getNumber() { - Assert.assertNull(kuzzleMap.getNumber("String")); - Assert.assertNotNull(kuzzleMap.getNumber("Number")); - Assert.assertNull(kuzzleMap.getNumber("Boolean")); - Assert.assertNull(kuzzleMap.getNumber("ArrayList")); - Assert.assertNull(kuzzleMap.getNumber("Map")); - Assert.assertNull(kuzzleMap.getNumber("KuzzleMap")); - Assert.assertNull(kuzzleMap.getNumber("Null")); - Assert.assertNull(kuzzleMap.getNumber("UnknownKey")); - } - - @Test - public void getBoolean() { - Assert.assertNull(kuzzleMap.getBoolean("String")); - Assert.assertNull(kuzzleMap.getBoolean("Number")); - Assert.assertNotNull(kuzzleMap.getBoolean("Boolean")); - Assert.assertNull(kuzzleMap.getBoolean("ArrayList")); - Assert.assertNull(kuzzleMap.getBoolean("Map")); - Assert.assertNull(kuzzleMap.getBoolean("KuzzleMap")); - Assert.assertNull(kuzzleMap.getBoolean("Null")); - Assert.assertNull(kuzzleMap.getBoolean("UnknownKey")); - } - - @Test - public void getArrayList() { - Assert.assertNull(kuzzleMap.getArrayList("String")); - Assert.assertNull(kuzzleMap.getArrayList("Number")); - Assert.assertNull(kuzzleMap.getArrayList("Boolean")); - Assert.assertNotNull(kuzzleMap.getArrayList("ArrayList")); - Assert.assertNull(kuzzleMap.getArrayList("Map")); - Assert.assertNull(kuzzleMap.getArrayList("KuzzleMap")); - Assert.assertNull(kuzzleMap.getArrayList("Null")); - Assert.assertNull(kuzzleMap.getArrayList("UnknownKey")); - } - - @Test - public void getMap() { - Assert.assertNull(kuzzleMap.getMap("String")); - Assert.assertNull(kuzzleMap.getMap("Number")); - Assert.assertNull(kuzzleMap.getMap("Boolean")); - Assert.assertNull(kuzzleMap.getMap("ArrayList")); - Assert.assertNotNull(kuzzleMap.getMap("Map")); - Assert.assertNotNull(kuzzleMap.getMap("KuzzleMap")); - Assert.assertNull(kuzzleMap.getMap("Null")); - Assert.assertNull(kuzzleMap.getMap("UnknownKey")); - } - - @Test - public void get() { - Assert.assertTrue(kuzzleMap.get("String") instanceof String); - Assert.assertTrue(kuzzleMap.get("Number") instanceof Number); - Assert.assertTrue(kuzzleMap.get("Boolean") instanceof Boolean); - Assert.assertTrue(kuzzleMap.get("ArrayList") instanceof ArrayList); - Assert.assertTrue(kuzzleMap.get("Map") instanceof ConcurrentHashMap); - Assert.assertTrue(kuzzleMap.get("KuzzleMap") instanceof ConcurrentHashMap); - Assert.assertTrue(kuzzleMap.get("Null") == null); - Assert.assertTrue(kuzzleMap.get("UnknownKey") == null); - } - - @Test - public void optString() { - Assert.assertTrue(kuzzleMap.optString("String", "foo").equals("String")); - Assert.assertTrue(kuzzleMap.optString("Number", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("Boolean", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("ArrayList", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("Map", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("KuzzleMap", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("Null", "foo").equals("foo")); - Assert.assertTrue(kuzzleMap.optString("UnknownKey", "foo").equals("foo")); - } - - @Test - public void optNumber() { - Assert.assertTrue(kuzzleMap.optNumber("String", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("Number", 42).equals(0)); - Assert.assertTrue(kuzzleMap.optNumber("Boolean", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("ArrayList", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("Map", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("KuzzleMap", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("Null", 42).equals(42)); - Assert.assertTrue(kuzzleMap.optNumber("UnknownKey", 42).equals(42)); - } - - @Test - public void optBoolean() { - Assert.assertTrue(kuzzleMap.optBoolean("String", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("Number", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("Boolean", true).equals(false)); - Assert.assertTrue(kuzzleMap.optBoolean("ArrayList", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("Map", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("KuzzleMap", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("Null", true).equals(true)); - Assert.assertTrue(kuzzleMap.optBoolean("UnknownKey", true).equals(true)); - } - - @Test - public void optArrayList() { - ArrayList list = new ArrayList<>(); - list.add(1); - - Assert.assertEquals(kuzzleMap.optArrayList("String", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("Number", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("Boolean", list).hashCode(), list.hashCode()); - Assert.assertNotEquals(kuzzleMap.optArrayList("ArrayList", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("Map", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("KuzzleMap", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("Null", list).hashCode(), list.hashCode()); - Assert.assertEquals(kuzzleMap.optArrayList("UnknownKey", list).hashCode(), list.hashCode()); - } - - @Test - public void optMap() { - KuzzleMap map = new KuzzleMap(); - map.put("Data", 1); - - Assert.assertEquals(kuzzleMap.optMap("String", map).hashCode(), map.hashCode()); - Assert.assertEquals(kuzzleMap.optMap("Number", map).hashCode(), map.hashCode()); - Assert.assertEquals(kuzzleMap.optMap("Boolean", map).hashCode(), map.hashCode()); - Assert.assertEquals(kuzzleMap.optMap("ArrayList", map).hashCode(), map.hashCode()); - Assert.assertNotEquals(kuzzleMap.optMap("Map", map).hashCode(), map.hashCode()); - Assert.assertNotEquals(kuzzleMap.optMap("KuzzleMap", map).hashCode(), map.hashCode()); - Assert.assertEquals(kuzzleMap.optMap("Null", map).hashCode(), map.hashCode()); - Assert.assertEquals(kuzzleMap.optMap("UnknownKey", map).hashCode(), map.hashCode()); - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java deleted file mode 100644 index 21c6d0c9..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java +++ /dev/null @@ -1,151 +0,0 @@ -package io.kuzzle.test.CoreClasses.TaskTest; - -import io.kuzzle.sdk.CoreClasses.Task; -import org.junit.Assert; -import org.junit.Test; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; - -public class TaskTests { - - @Test - public void constructorTest() { - TestableTask task = new TestableTask<>(); - Assert.assertNotNull(task.getAtomicReference()); - Assert.assertEquals( - AtomicReference.class, - task.getAtomicReference().getClass() - ); - Assert.assertNotNull(task.getCountDownLatch()); - Assert.assertEquals( - CountDownLatch.class, - task.getCountDownLatch().getClass() - ); - Assert.assertNotNull(task.getFuture()); - } - - @Test - public void getFutureTest() { - Task task = new Task<>(); - - Assert.assertEquals( - CompletableFuture.class, - task.getFuture().getClass() - ); - } - - @Test - public void setExceptionTest() { - TestableTask task = new TestableTask<>(); - task.applyMockFuture(); - - task.setException(new Exception("foobar")); - - verify( - task.mockedFuture, - times(1) - ).completeExceptionally(any(Exception.class)); - } - - @Test - public void isCancelledTest() { - TestableTask task = new TestableTask<>(); - task.applyMockFuture(); - - when(task.mockedFuture.isCancelled()) - .thenReturn(true); - - Assert.assertTrue(task.isCancelled()); - - verify( - task.mockedFuture, - times(1) - ).isCancelled(); - } - - @Test - public void isDoneTest() { - TestableTask task = new TestableTask<>(); - task.applyMockFuture(); - - when(task.mockedFuture.isDone()) - .thenReturn(true); - - Assert.assertTrue(task.isDone()); - - verify( - task.mockedFuture, - times(1) - ).isDone(); - } - - @Test - public void isCompletedExceptionallyTest() { - TestableTask task = new TestableTask<>(); - task.applyMockFuture(); - - when(task.mockedFuture.isCompletedExceptionally()) - .thenReturn(true); - - Assert.assertTrue(task.isCompletedExceptionally()); - - verify( - task.mockedFuture, - times(1) - ).isCompletedExceptionally(); - } - - @Test - public void setCancelledTest() { - TestableTask task = new TestableTask<>(); - task.applyMockFuture(); - - task.setCancelled(true); - - verify( - task.mockedFuture, - times(1) - ).cancel(anyBoolean()); - } - - @Test - public void triggerTest() { - Task task = new Task(); - - final AtomicBoolean success = new AtomicBoolean(false); - - CompletableFuture taskChain = task.getFuture().thenRun(() -> { - success.set(true); - }); - - task.trigger(); - - taskChain.join(); - - Assert.assertTrue(success.get()); - - } - - @Test - public void triggerWithObjectTest() { - Task task = new Task(); - - final AtomicBoolean success = new AtomicBoolean(false); - - CompletableFuture taskChain = task.getFuture().thenAccept((str) -> { - success.set(str.equals("foobar")); - }); - - task.trigger("foobar"); - - taskChain.join(); - - Assert.assertTrue(success.get()); - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java deleted file mode 100644 index 51852112..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.kuzzle.test.CoreClasses.TaskTest; - -import io.kuzzle.sdk.CoreClasses.Task; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -import static org.mockito.Mockito.mock; - -public class TestableTask extends Task { - public CountDownLatch mockedCountDownLatch = mock(CountDownLatch.class); - public CompletableFuture mockedFuture = mock(CompletableFuture.class); - - public TestableTask() { - super(); - } - - public void applyMockFuture() { - super.future = mockedFuture; - } - - public CountDownLatch getCountDownLatch() { - return super.countDownLatch; - } - - public AtomicReference getAtomicReference() { - return super.atomicReference; - } - - -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java deleted file mode 100644 index ec22a31f..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java +++ /dev/null @@ -1,159 +0,0 @@ -package io.kuzzle.test.EventsTest; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class EventListenerTests { - - @Test - public void registerRunnableTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.register(() -> {}); - - verify( - eventListener.mockedCallbacks, - times(1) - ).add(any(Runnable.class)); - } - - @Test - public void unregisterRunnableTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.unregister(() -> {}); - - verify( - eventListener.mockedCallbacks, - times(1) - ).remove(any(Runnable.class)); - } - - @Test - public void registerConsumerTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.register((obj) -> {}); - - verify( - eventListener.mockedCallbacks, - times(1) - ).add(any(Consumer.class)); - } - - @Test - public void unregisterConsumerTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.unregister((obj) -> {}); - - verify( - eventListener.mockedCallbacks, - times(1) - ).remove(any(Consumer.class)); - } - - @Test - public void registerDuplicateTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - - Runnable runnable1 = () -> {}; - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(() -> {}); - - Assert.assertEquals(2, eventListener.getCallbacks().size()); - } - - @Test - public void triggerRunnableTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - - AtomicBoolean success = new AtomicBoolean(false); - eventListener.register(() -> success.set(true)); - - Assert.assertFalse(success.get()); - - eventListener.trigger(); - - Assert.assertTrue(success.get()); - } - - @Test - public void triggerConsumerTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - - AtomicBoolean success = new AtomicBoolean(false); - eventListener.register((str) -> success.set(str.equals("foobar"))); - - Assert.assertFalse(success.get()); - - eventListener.trigger("foobar"); - - Assert.assertTrue(success.get()); - } - - @Test - public void triggerOnlyConsumerTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - - AtomicBoolean consumerSuccess = new AtomicBoolean(false); - AtomicBoolean runnableSuccess = new AtomicBoolean(false); - - eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); - eventListener.register(() -> runnableSuccess.set(true)); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - - eventListener.trigger("foobar"); - - Assert.assertTrue(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - } - - @Test - public void triggerOnlyRunnableTest() { - TestableEventListener - eventListener = new TestableEventListener<>(); - - AtomicBoolean consumerSuccess = new AtomicBoolean(false); - AtomicBoolean runnableSuccess = new AtomicBoolean(false); - - eventListener.register( - (str) -> consumerSuccess.set(str.equals("foobar")) - ); - eventListener.register(() -> runnableSuccess.set(true)); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - - eventListener.trigger(); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertTrue(runnableSuccess.get()); - } - -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java deleted file mode 100644 index 3d1af9e3..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.kuzzle.test.EventsTest; - -import io.kuzzle.sdk.Events.EventListener; - -import java.util.Set; - -import static org.mockito.Mockito.mock; - -public class TestableEventListener extends EventListener { - public Set mockedCallbacks = mock(Set.class); - public TestableEventListener() { - super(); - } - - public void applyMock() { - super.callbacks = mockedCallbacks; - } - - public Set getCallbacks() { - return super.callbacks; - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java deleted file mode 100644 index a15fa8e2..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.kuzzle.test.Helpers; - -import io.kuzzle.sdk.Helpers.Default; -import org.junit.Assert; -import org.junit.Test; - -public class DefaultTests { - - @Test - public void notNullTest() { - String str1 = Default.defaultValue(null, "foobar"); - String str2 = Default.defaultValue("SomeString", "foobar"); - - Integer int1 = Default.defaultValue(null, 42); - Integer int2 = Default.defaultValue(10, 42); - - Assert.assertEquals("foobar", str1); - Assert.assertEquals("SomeString", str2); - - Assert.assertEquals(42, int1.intValue()); - Assert.assertEquals(10, int2.intValue()); - } - -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java deleted file mode 100644 index 2b817d41..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/KuzzleTests.java +++ /dev/null @@ -1,177 +0,0 @@ -package io.kuzzle.test; - -import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; -import io.kuzzle.sdk.CoreClasses.Task; -import io.kuzzle.sdk.Events.EventListener; -import io.kuzzle.sdk.Exceptions.InternalException; -import io.kuzzle.sdk.Exceptions.NotConnectedException; -import io.kuzzle.sdk.Protocol.AbstractProtocol; -import io.kuzzle.sdk.Protocol.ProtocolState; -import io.kuzzle.sdk.CoreClasses.Responses.ErrorResponse; -import io.kuzzle.sdk.CoreClasses.Responses.Response; -import io.kuzzle.sdk.Protocol.WebSocket; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Matchers; -import org.mockito.Mockito; -import org.mockito.stubbing.Answer; - -import java.net.URISyntaxException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - -public class KuzzleTests { - private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - private EventListener - tokenExpiredEventListener = Mockito.mock(EventListener.class); - private EventListener - unhandledResponseEventListener = Mockito.mock(EventListener.class); - private TestableKuzzle kuzzle; - - @Before - public void setup() throws URISyntaxException { - kuzzle = new TestableKuzzle(networkProtocol); - kuzzle.setTokenExpiredEventListener(tokenExpiredEventListener); - kuzzle.setUnhandledResponseEventListener(unhandledResponseEventListener); - } - - @Test - public void connect() throws Exception { - kuzzle.connect(); - Mockito.verify( - networkProtocol, - Mockito.times(1) - ).connect(); - } - - @Test - public void disconnect() throws Exception { - kuzzle.disconnect(); - Mockito.verify( - networkProtocol, - Mockito.times(1) - ).disconnect(); - } - - - @Test - public void registerTokenExpiredEvent() throws Exception { - kuzzle.registerTokenExpiredEvent(() -> {}); - Mockito.verify(tokenExpiredEventListener, - Mockito.times(1) - ).register(Matchers.any(Runnable.class)); - } - - @Test - public void unregisterTokenExpiredEvent() throws Exception { - kuzzle.unregisterTokenExpiredEvent(() -> {}); - Mockito.verify( - tokenExpiredEventListener, - Mockito.times(1) - ).unregister(Matchers.any(Runnable.class)); - } - - @Test - public void onStateChanged() { - ConcurrentHashMap> - requests = kuzzle.getRequests(); - - Task response = new Task<>(); - requests.put("foobar", response); - kuzzle.onStateChanged(ProtocolState.CLOSE); - Assert.assertEquals(0, requests.size()); - Assert.assertTrue(response.isCompletedExceptionally()); - } - - @Test(expected = NotConnectedException.class) - public void queryShouldThrowWhenNotConnected() - throws NotConnectedException, InternalException { - Mockito.when(networkProtocol.getState()) - .thenAnswer( - (Answer) invocation -> ProtocolState.CLOSE - ); - - kuzzle.query(new ConcurrentHashMap<>()); - } - - @Test - public void querySuccess() throws NotConnectedException, InternalException { - Mockito.when(networkProtocol.getState()) - .thenAnswer( - (Answer) invocation -> ProtocolState.OPEN - ); - - CompletableFuture - response = kuzzle.query( - new ConcurrentHashMap<>() - ); - - Assert.assertNotNull(response); - Mockito.verify( - networkProtocol, - Mockito.times(1) - ).send(Matchers.any(ConcurrentHashMap.class)); - } - - @Test(expected = InternalException.class) - public void queryShouldThrowWhenVolatileIsNotConcurrentHashMap() - throws NotConnectedException, InternalException { - Mockito.when(networkProtocol.getState()) - .thenAnswer( - (Answer) invocation -> ProtocolState.OPEN - ); - - ConcurrentHashMap payload = new ConcurrentHashMap<>(); - payload.put("volatile", "foobar"); - - kuzzle.query(payload); - } - - @Test - public void onResponseReceivedAndTokenIsExpired() { - ConcurrentHashMap> - requests = kuzzle.getRequests(); - - Response response = new Response(); - response.requestId = "foobar"; - response.error = new ErrorResponse(); - response.error.id = "security.token.expired"; - response.error.status = 42; - response.room = "room-id"; - - Task task = new Task<>(); - - requests.put("room-id", task); - - kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); - - Mockito.verify( - tokenExpiredEventListener, - Mockito.times(1) - ).trigger(); - } - - @Test - public void onResponseReceivedAndResponseIsUnhandled() { - ConcurrentHashMap> - requests = kuzzle.getRequests(); - - AtomicBoolean success = new AtomicBoolean(false); - Response response = new Response(); - response.requestId = "foobar"; - - Task task = new Task<>(); - - requests.put("request-id", task); - - kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); - - Mockito.verify( - unhandledResponseEventListener, - Mockito.times(1) - ).trigger(Matchers.any(Response.class)); - } - -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java deleted file mode 100644 index daae19df..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.kuzzle.test.ProtocolTest; - -import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; -import io.kuzzle.sdk.Protocol.ProtocolState; -import io.kuzzle.sdk.Protocol.WebSocket; -import java.net.URISyntaxException; - -import static org.mockito.Mockito.mock; - -public class TestableWebSocket extends WebSocket { - public int stateChangedCount = 0; - public ProtocolState lastStateDispatched = ProtocolState.CLOSE; - public com.neovisionaries.ws.client.WebSocket - mockedSocket = mock(com.neovisionaries.ws.client.WebSocket.class); - - public TestableWebSocket(String host) - throws URISyntaxException, IllegalArgumentException { - super(host); - } - - public TestableWebSocket(String host, WebSocketOptions options) - throws URISyntaxException, IllegalArgumentException { - super(host, options); - super.stateChanged.register((ProtocolState state) -> { - stateChangedCount += 1; - lastStateDispatched = state; - }); - } - - public com.neovisionaries.ws.client.WebSocket getSocket() { - return super.socket; - } - - @Override - protected com.neovisionaries.ws.client.WebSocket createClientSocket() { - return mockedSocket; - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java deleted file mode 100644 index ed6e1252..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java +++ /dev/null @@ -1,90 +0,0 @@ -package io.kuzzle.test.ProtocolTest; - -import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; -import io.kuzzle.sdk.Protocol.ProtocolState; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.net.URISyntaxException; - -import static org.mockito.Mockito.*; - -public class WebSocketTests { - - private TestableWebSocket socket; - private String host; - private WebSocketOptions options; - - @Before - public void setup() throws URISyntaxException { - host = "foo"; - options = new WebSocketOptions() - .withPort(1234) - .withSsl(true); - socket = new TestableWebSocket(host, options); - } - - @Test - public void constructorNotConnected() throws URISyntaxException { - TestableWebSocket ws = new TestableWebSocket(host, options); - - Assert.assertEquals(ProtocolState.CLOSE, ws.getState()); - Assert.assertNull(ws.getSocket()); - } - - @Test(expected = IllegalArgumentException.class) - public void constructorRejectsNullHost() throws URISyntaxException { - TestableWebSocket ws = new TestableWebSocket(null, options); - } - - @Test - public void connectTest() throws Exception { - when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); - - socket.connect(); - - Assert.assertNotNull(socket.getSocket()); - - socket.connect(); - socket.connect(); - socket.connect(); - - verify(socket.mockedSocket, times(1)).connect(); - - Assert.assertEquals(ProtocolState.OPEN, socket.getState()); - Assert.assertEquals(1, socket.stateChangedCount); - Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); - } - - @Test - public void disconnectTest() throws Exception { - when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); - - socket.connect(); - - Assert.assertEquals(ProtocolState.OPEN, socket.getState()); - Assert.assertEquals(1, socket.stateChangedCount); - Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); - - socket.disconnect(); - socket.disconnect(); - socket.disconnect(); - - verify( - socket.mockedSocket, - times(1) - ).disconnect(); - } - - @Test - public void disconnectWithoutEverConnecting() throws Exception { - Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); - Assert.assertEquals(0, socket.stateChangedCount); - - socket.disconnect(); - - Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); - Assert.assertEquals(0, socket.stateChangedCount); - } -} diff --git a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java b/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java deleted file mode 100644 index f42d8137..00000000 --- a/kuzzle-sdk-java/src/test/java/io/kuzzle/test/TestableKuzzle.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.kuzzle.test; - -import io.kuzzle.sdk.CoreClasses.Responses.Response; -import io.kuzzle.sdk.CoreClasses.Task; -import io.kuzzle.sdk.Events.EventListener; -import io.kuzzle.sdk.Kuzzle; -import io.kuzzle.sdk.Options.KuzzleOptions; -import io.kuzzle.sdk.Protocol.AbstractProtocol; -import io.kuzzle.sdk.Protocol.ProtocolState; - -import java.net.URISyntaxException; -import java.util.concurrent.ConcurrentHashMap; - -public class TestableKuzzle extends Kuzzle { - - public TestableKuzzle(AbstractProtocol networkProtocol) throws URISyntaxException, IllegalArgumentException { - super(networkProtocol); - } - - public TestableKuzzle(AbstractProtocol networkProtocol, KuzzleOptions options) throws IllegalArgumentException { - super(networkProtocol, options); - } - - public void setTokenExpiredEventListener(EventListener eventListener) { - super.tokenExpiredEvent = eventListener; - } - - public EventListener getTokenExpiredEventListener() { - return super.tokenExpiredEvent; - } - - public void setUnhandledResponseEventListener(EventListener eventListener) { - super.unhandledResponseEvent = eventListener; - } - - public EventListener getUnhandledResponseEventListener() { - return super.unhandledResponseEvent; - } - - public void onStateChanged(ProtocolState state) { - super.onStateChanged(state); - } - - public void onResponseReceived(String payload) { - super.onResponseReceived(payload); - } - - public ConcurrentHashMap> getRequests() { - return super.requests; - } -} diff --git a/package.json b/package.json new file mode 100644 index 00000000..947f07b4 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "scripts": { + "doc-prepare": "cd doc && bash doc.sh prepare", + "doc-dev": "cd doc && bash doc.sh dev", + "doc-build": "cd doc && bash doc.sh build", + "doc-upload": "cd doc && bash doc.sh upload", + "doc-cloudfront": "cd doc && bash doc.sh cloudfront", + "doc-deploy": "npm run doc-upload && npm run doc-cloudfront", + "doc-netlify": "npm run doc-prepare && cd doc && bash doc.sh build-netlify" + } +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..e71b73bc --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'sdk-java' diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java new file mode 100644 index 00000000..5b34a171 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java @@ -0,0 +1,150 @@ +package io.kuzzle.sdk.CoreClasses.Json; + +import com.google.gson.JsonSyntaxException; +import com.google.gson.TypeAdapter; +import com.google.gson.internal.LazilyParsedNumber; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Maps.Serializable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ConcurrentHashMapTypeAdapter extends TypeAdapter> { + + @Override + public void write(JsonWriter out, ConcurrentHashMap map) throws IOException { + if (map == null) { + out.nullValue(); + } else { + out.beginObject(); + Iterator> iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + out.name(String.valueOf(entry.getKey())); + writeObject(out, entry.getValue()); + } + + out.endObject(); + } + } + + @Override + public ConcurrentHashMap read(JsonReader in) throws IOException { + JsonToken peek = in.peek(); + if (peek == JsonToken.NULL) { + in.nextNull(); + return null; + } else if (peek == JsonToken.BEGIN_OBJECT) { + KuzzleMap map = new KuzzleMap(); + Object key; + Object value; + + in.beginObject(); + + while (in.hasNext()) { + key = in.nextName(); + value = readObject(in); + if (!map.containsKey(key)) { + map.put((String) key, value); + } else { + throw new JsonSyntaxException("duplicate key: " + key); + } + } + + in.endObject(); + + return map; + } + return null; + } + + private void writeObject(JsonWriter out, Object value) throws IOException { + if (value instanceof Number) { + out.value((Number) value); + } else if (value instanceof Boolean) { + out.value((Boolean) value); + } else if (value instanceof String) { + out.value((String) value); + } else if (value instanceof ArrayList) { + out.beginArray(); + Iterator iterator = ((ArrayList) value).iterator(); + + while (iterator.hasNext()) { + writeObject(out, iterator.next()); + } + + out.endArray(); + } else if (value instanceof ConcurrentHashMap) { + out.beginObject(); + Iterator> iterator = ((ConcurrentHashMap) value).entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry e = iterator.next(); + out.name(e.getKey()); + writeObject(out, e.getValue()); + } + + out.endObject(); + } else if (value instanceof Serializable) { + try { + writeObject(out, ((Serializable) value).toMap()); + } catch (Exception e) { + throw new IOException(e); + } + } else if (value == null) { + out.nullValue(); + } + } + + private Object readObject(JsonReader in) throws IOException { + switch (in.peek()) { + case NUMBER: + String number = in.nextString(); + return new LazilyParsedNumber(number); + case BOOLEAN: + return in.nextBoolean(); + case STRING: + return in.nextString(); + case NULL: + in.nextNull(); + return null; + case BEGIN_ARRAY: + ArrayList array = new ArrayList<>(); + in.beginArray(); + + while (in.hasNext()) { + array.add(readObject(in)); + } + + in.endArray(); + return array; + case BEGIN_OBJECT: + KuzzleMap map = new KuzzleMap(); + in.beginObject(); + + while (in.hasNext()) { + String key = in.nextName(); + Object object = readObject(in); + if (object != null) { + map.put(key, object); + } + } + + in.endObject(); + return map; + case END_DOCUMENT: + case NAME: + case END_OBJECT: + case END_ARRAY: + default: + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java new file mode 100644 index 00000000..b0235b58 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java @@ -0,0 +1,23 @@ +package io.kuzzle.sdk.CoreClasses.Json; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.concurrent.ConcurrentHashMap; + +public class JsonSerializer { + private static Gson gson; + + static { + gson = new GsonBuilder().disableHtmlEscaping().disableInnerClassSerialization().serializeNulls() + .registerTypeAdapter(ConcurrentHashMap.class, new ConcurrentHashMapTypeAdapter()).create(); + } + + public static ConcurrentHashMap deserialize(String rawJson) { + return gson.fromJson(rawJson, ConcurrentHashMap.class); + } + + public static String serialize(ConcurrentHashMap map) { + return gson.toJson(map, ConcurrentHashMap.class); + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java new file mode 100644 index 00000000..fc29d682 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java @@ -0,0 +1,253 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * CustomMap is a Class that extends ConcurrentHashMap to be ThreadSafe and that + * has the purpose of giving a wrapper on top of ConcurrentHashMap to easily + * manipulate them. + */ +public class KuzzleMap extends ConcurrentHashMap { + + /** + * Convert à ConcurrentHashMap to a CustomMap + * + * @param map ConcurrentHashMap representing JSON. + * @return a CustomMap instance + */ + public static KuzzleMap from(ConcurrentHashMap map) { + if (map == null) { + return null; + } + if (map instanceof KuzzleMap) { + return (KuzzleMap) map; + } + return new KuzzleMap(map); + } + + /** + * Create a new instance of CustomMap + */ + public KuzzleMap() { + super(); + } + + /** + * Create a new instance of CustomMap from a ConcurrentHashMap. + * + * @param map ConcurrentHashMap representing JSON. + */ + public KuzzleMap(ConcurrentHashMap map) { + super(); + Iterator> it = map.entrySet().iterator(); + + while (it.hasNext()) { + Entry entry = it.next(); + this.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public Object put(String s, Object o) { + Object obj = null; + if (o != null) { + obj = super.put(s, o); + } else { + obj = super.put(s, new Null()); + } + if (obj instanceof Null) { + return null; + } + return obj; + } + + @Override + public Object get(Object key) { + Object value = super.get(key); + if (value instanceof Null) { + return null; + } + return value; + } + + @Override + public Set> entrySet() { + Set> entrySet = super.entrySet(); + return entrySet.parallelStream().map((Entry entry) -> { + if (entry.getValue() instanceof Null) { + return new KuzzleMapEntry(entry.getKey(), entry.getValue(), this); + } + return entry; + }).collect(Collectors.toSet()); + } + + /** + * Check whether the key value is null or not. + * + * @param key a String representing the key. + * @return true if the value is null. + */ + public boolean isNull(String key) { + return super.get(key) instanceof Null; + } + + /** + * Check whether the key value is a String or not. + * + * @param key a String representing the key. + * @return true if the key is a String. + */ + public boolean isString(String key) { + return super.get(key) instanceof String; + } + + /** + * Check whether the key value is a Boolean or not. + * + * @param key a String representing the key. + * @return true if the key is a Boolean. + */ + public boolean isBoolean(String key) { + return super.get(key) instanceof Boolean; + } + + /** + * Check whether the key value is a Number or not. + * + * @param key a String representing the key. + * @return true if the key is a Number. + */ + public boolean isNumber(String key) { + return super.get(key) instanceof Number; + } + + /** + * Check whether the key value is an ArrayList or not. + * + * @param key a String representing the key. + * @return true if the key is an ArrayList. + */ + public boolean isArrayList(String key) { + return super.get(key) instanceof ArrayList; + } + + /** + * Check whether the key value is a ConcurrentHashMap or not. + * + * @param key a String representing the key. + * @return true if the key is a ConcurrentHashMap. + */ + public boolean isMap(String key) { + return super.get(key) instanceof ConcurrentHashMap; + } + + /** + * Return the specified key value or null if the value is not a String. + * + * @param key a String representing the key. + * @return The String at the key or null + */ + public String getString(String key) { + return isString(key) ? (String) super.get(key) : null; + } + + /** + * Return the specified key value or null if the value is not a Boolean. + * + * @param key a String representing the key. + * @return The Boolean at the key or null + */ + public Boolean getBoolean(String key) { + return isBoolean(key) ? (Boolean) super.get(key) : null; + } + + /** + * Return the specified key value or null if the value is not a Number. + * + * @param key a String representing the key. + * @return The Number at the key or null + */ + public Number getNumber(String key) { + return isNumber(key) ? (Number) super.get(key) : null; + } + + /** + * Return the specified key value or null if the value is not an ArrayList. + * + * @param key a String representing the key. + * @return The ArrayList at the key or null + */ + public ArrayList getArrayList(String key) { + return isArrayList(key) ? (ArrayList) super.get(key) : null; + } + + /** + * Return the specified key value or null if the value is not a + * ConcurrentHashMap. + * + * @param key a String representing the key. + * @return The ConcurrentHashMap at the key or null + */ + public KuzzleMap getMap(String key) { + return isMap(key) ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) : null; + } + + /** + * Return the specified key value or the def value if the value is nul or not a + * String. + * + * @param key a String representing the key. + * @return The String at the key or def value + */ + public String optString(String key, String def) { + return isString(key) ? (String) super.get(key) : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a + * Boolean. + * + * @param key a String representing the key. + * @return The Boolean at the key or def value + */ + public Boolean optBoolean(String key, Boolean def) { + return isBoolean(key) ? (Boolean) super.get(key) : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a + * Number. + * + * @param key a String representing the key. + * @return The Number at the key or def value + */ + public Number optNumber(String key, Number def) { + return isNumber(key) ? (Number) super.get(key) : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not an + * ArrayList. + * + * @param key a String representing the key. + * @return The ArrayList at the key or def value + */ + public ArrayList optArrayList(String key, ArrayList def) { + return isArrayList(key) ? (ArrayList) super.get(key) : def; + } + + /** + * Return the specified key value or the def value if the value is nul or not a + * ConcurrentHashMap. + * + * @param key a String representing the key. + * @return The ConcurrentHashMap at the key or def value + */ + public KuzzleMap optMap(String key, ConcurrentHashMap def) { + return isMap(key) ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) : KuzzleMap.from(def); + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java new file mode 100644 index 00000000..65b8548b --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMapEntry.java @@ -0,0 +1,64 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class KuzzleMapEntry implements Map.Entry { + final String key; + Object value; + final ConcurrentHashMap map; + + public KuzzleMapEntry(String key, Object value, ConcurrentHashMap map) { + this.key = key; + this.value = value; + this.map = map; + } + + public String getKey() { + return this.key; + } + + public Object getValue() { + if (this.value instanceof Null) { + return null; + } + return this.value; + } + + public int hashCode() { + return this.key.hashCode() ^ this.value.hashCode(); + } + + public String toString() { + return this.key + "=" + this.value; + } + + public boolean equals(Object object) { + Object key; + Object value; + Map.Entry entry; + + if (!(object instanceof Map.Entry)) { + return false; + } + + entry = (Map.Entry) object; + key = entry.getKey(); + value = entry.getValue(); + return key != null && (value == this.value || (value != null && value.equals(this.value))); + } + + public Object setValue(Object value) { + if (value == null) { + Object oldValue = this.value; + this.value = new Null(); + this.map.put(this.key, this.value); + return oldValue; + } else { + Object oldValue = this.value; + this.value = value; + this.map.put(this.key, value); + return oldValue; + } + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java new file mode 100644 index 00000000..bd295eaf --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java @@ -0,0 +1,9 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +public class Null { + final int hashCode = 572487463; + + public int hashCode() { + return hashCode; + } +} \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java new file mode 100644 index 00000000..ebc0c7af --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Serializable.java @@ -0,0 +1,9 @@ +package io.kuzzle.sdk.CoreClasses.Maps; + +import java.util.concurrent.ConcurrentHashMap; + +public interface Serializable { + void fromMap(ConcurrentHashMap map) throws Exception; + + ConcurrentHashMap toMap() throws Exception; +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java new file mode 100644 index 00000000..ae989dce --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/ErrorResponse.java @@ -0,0 +1,57 @@ +package io.kuzzle.sdk.CoreClasses.Responses; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Maps.Serializable; + +import java.util.concurrent.ConcurrentHashMap; + +public class ErrorResponse implements Serializable { + + public ErrorResponse() { + + } + + /** + * Response status, following HTTP status codes. + */ + public int status; + + /** + * Error message + */ + public String message; + + /** + * Error ID + */ + public String id; + + /** + * Error stack + */ + public String stack; + + @Override + public void fromMap(ConcurrentHashMap map) { + if (map == null) + return; + + KuzzleMap kuzzleMap = KuzzleMap.from(map); + + status = kuzzleMap.optNumber("status", 0).intValue(); + message = kuzzleMap.getString("message"); + stack = kuzzleMap.getString("stack"); + id = kuzzleMap.getString("id"); + } + + @Override + public ConcurrentHashMap toMap() { + ConcurrentHashMap map = new KuzzleMap(); + + map.put("status", status); + map.put("message", message); + map.put("stack", stack); + map.put("id", id); + return map; + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java new file mode 100644 index 00000000..1478c5fb --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java @@ -0,0 +1,140 @@ +package io.kuzzle.sdk.CoreClasses.Responses; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Maps.Serializable; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.KuzzleException; +import io.kuzzle.sdk.Exceptions.KuzzleExceptionCode; + +import java.util.concurrent.ConcurrentHashMap; + +public class Response implements Serializable { + + public String room; + + /** + * Response payload (depends on the executed API action) + */ + public Object result; + + /** + * Error object (null if the request finished successfully) + */ + public ErrorResponse error; + + /** + * Request unique identifier. + */ + public String requestId; + + /** + * Response status, following HTTP status codes + */ + public int status; + + /** + * Executed Kuzzle API controller. + */ + public String controller; + + /** + * Executed Kuzzle API controller's action. + */ + public String action; + + /** + * Impacted data index. + */ + public String index; + + /** + * Impacted data collection. + */ + public String collection; + + /** + * Volatile data. + */ + public ConcurrentHashMap Volatile; + + // The following properties are specific to real-time notifications + + /** + * Network protocol at the origin of the real-time notification. + */ + public String protocol; + + /** + * Document scope ("in" or "out") + */ + public String scope; + + /** + * Document state + */ + public String state; + + /** + * Notification timestamp (UTC) + */ + public Long timestamp; + + /** + * Notification type + */ + public String type; + + @Override + public void fromMap(ConcurrentHashMap map) throws InternalException { + if (map == null) + return; + + KuzzleMap kuzzleMap = KuzzleMap.from(map); + + room = kuzzleMap.getString("room"); + result = kuzzleMap.get("result"); + error = null; + if (kuzzleMap.isMap("error")) { + error = new ErrorResponse(); + error.fromMap(kuzzleMap.getMap("error")); + } + requestId = kuzzleMap.getString("requestId"); + if (requestId == null) { + throw new InternalException(KuzzleExceptionCode.MISSING_REQUESTID); + } + status = kuzzleMap.optNumber("status", 0).intValue(); + controller = kuzzleMap.getString("controller"); + action = kuzzleMap.getString("action"); + index = kuzzleMap.getString("index"); + collection = kuzzleMap.getString("collection"); + Volatile = kuzzleMap.optMap("volatile", new ConcurrentHashMap<>()); + protocol = kuzzleMap.getString("protocol"); + scope = kuzzleMap.getString("scope"); + state = kuzzleMap.getString("state"); + timestamp = (Long) kuzzleMap.getNumber("timestamp"); + type = kuzzleMap.getString("type"); + } + + @Override + public ConcurrentHashMap toMap() { + ConcurrentHashMap map = new KuzzleMap(); + + map.put("room", room); + map.put("result", result); + map.put("error", error); + map.put("requestId", requestId); + map.put("status", status); + map.put("controller", controller); + map.put("action", action); + map.put("index", index); + map.put("collection", collection); + map.put("volatile", Volatile); + map.put("protocol", protocol); + map.put("scope", scope); + map.put("status", status); + map.put("timestamp", timestamp); + map.put("type", type); + + return map; + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java new file mode 100644 index 00000000..7980ecdf --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java @@ -0,0 +1,104 @@ +package io.kuzzle.sdk.CoreClasses; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @param The object type that the task return. + */ +public class Task { + /** + * A countDownLatch used to lock the future. + */ + protected CountDownLatch countDownLatch; + /** + * A completable future. + */ + protected CompletableFuture future; + + /** + * The object instance to return. + */ + protected AtomicReference atomicReference; + + /** + * Initializes a new instance of the Task. + */ + public Task() { + atomicReference = new AtomicReference(); + countDownLatch = new CountDownLatch(1); + future = CompletableFuture.supplyAsync(() -> { + try { + countDownLatch.await(); + + return atomicReference.get(); + } catch (InterruptedException e) { + return null; + } + }); + } + + /** + * @return The associated CompletableFuture. + */ + public CompletableFuture getFuture() { + return future; + } + + /** + * Set the exception of the CompletableFuture. + * + * @param exception + */ + public void setException(Exception exception) { + future.completeExceptionally(exception); + } + + /** + * @return true if future is cancelled. + */ + public boolean isCancelled() { + return future.isCancelled(); + } + + /** + * @return true if the future is done. + */ + public boolean isDone() { + return future.isDone(); + } + + /** + * @return true if the future has been completed exceptionally. + */ + public boolean isCompletedExceptionally() { + return future.isCompletedExceptionally(); + } + + /** + * Set if the future is cancelled. + * + * @param state + */ + public void setCancelled(boolean state) { + future.cancel(state); + } + + /** + * Unlock the future. + */ + public void trigger() { + countDownLatch.countDown(); + } + + /** + * Unlock the future and set the object. + * + * @param object + */ + public void trigger(T object) { + atomicReference.set(object); + countDownLatch.countDown(); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Events/EventListener.java b/src/main/java/io/kuzzle/sdk/Events/EventListener.java new file mode 100644 index 00000000..acb2b8a1 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Events/EventListener.java @@ -0,0 +1,84 @@ +package io.kuzzle.sdk.Events; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +public class EventListener { + + /** + * Set of registered callbacks. + */ + protected Set callbacks; + + /** + * Initializes a new instance of the EventListener. + */ + public EventListener() { + callbacks = ConcurrentHashMap.newKeySet(); + } + + /** + * Register a callback that takes a parameter. + * + * @param callback + * @return If successfully registered. + */ + public boolean register(final Consumer callback) { + return callbacks.add(callback); + } + + /** + * Register a callback with no parameter. + * + * @param callback + * @return If successfully registered. + */ + public boolean register(final Runnable callback) { + return callbacks.add(callback); + } + + /** + * Unregister a callback that takes a parameter. + * + * @param callback + * @return If successfully unregistered. + */ + public boolean unregister(final Consumer callback) { + return callbacks.remove(callback); + } + + /** + * Unregister a callback with no parameter. + * + * @param callback + * @return If successfully unregistered. + */ + public boolean unregister(final Runnable callback) { + return callbacks.remove(callback); + } + + /** + * Triggers every callbacks that have a parameter with the given object. + * + * @param obj An Object. + */ + public void trigger(final T obj) { + for (Object callback : callbacks) { + if (callback instanceof Consumer) { + ((Consumer) callback).accept(obj); + } + } + } + + /** + * Triggers every callbacks that doesn't have a parameter. + */ + public void trigger() { + for (Object callback : callbacks) { + if (callback instanceof Runnable) { + ((Runnable) callback).run(); + } + } + } +} diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java b/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java new file mode 100644 index 00000000..8b800868 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java @@ -0,0 +1,39 @@ +package io.kuzzle.sdk.Exceptions; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +/** + * Passed to async tasks when an API request returns an error. + */ +public class ApiErrorException extends KuzzleException { + /** + * Kuzzle API stack trace + */ + protected String stack; + + /** + * Kuzzle API error unique identifier + */ + protected String id; + + /** + * Initializes a new instance of the ApiErrorException + * + * @param response Kuzzle API Response. + */ + public ApiErrorException(Response response) { + super(response.error != null ? response.error.message : null, response.status); + if (response.error != null) { + this.stack = response.error.stack; + this.id = response.error.id; + } + } + + public String getStack() { + return this.stack; + } + + public String getId() { + return this.id; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java b/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java similarity index 54% rename from kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java rename to src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java index 47227103..dbd2bbb3 100644 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java @@ -5,11 +5,11 @@ * waiting for a result. */ public class ConnectionLostException extends KuzzleException { - /** - * Initializes a new instance of the ConnectionLostException. - */ - public ConnectionLostException() { - super(KuzzleExceptionCode.CONNECTION_LOST); - } + /** + * Initializes a new instance of the ConnectionLostException. + */ + public ConnectionLostException() { + super(KuzzleExceptionCode.CONNECTION_LOST); + } } diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java b/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java new file mode 100644 index 00000000..7791fa64 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java @@ -0,0 +1,19 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Passed to async tasks when an API request returns an error. + */ +public class InternalException extends KuzzleException { + + /** + * Initializes a new instance of the InternalException + */ + public InternalException(String message, KuzzleExceptionCode status) { + super(message, status); + } + + public InternalException(KuzzleExceptionCode status) { + super(status); + } + +} diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java new file mode 100644 index 00000000..d905b5d7 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java @@ -0,0 +1,40 @@ +package io.kuzzle.sdk.Exceptions; + +/** + * Root of all Kuzzle exceptions. + */ +public class KuzzleException extends Exception { + + /** + * Kuzzle API error code. + */ + protected int status; + + /** + * Initializes a new instance of the KuzzleException. + * + * @param message Message. + * @param status Status. + */ + protected KuzzleException(String message, int status) { + super(message); + this.status = status; + } + + protected KuzzleException(String message, KuzzleExceptionCode status) { + super(message); + this.status = status.getCode(); + } + + protected KuzzleException(KuzzleExceptionCode status) { + super(status.getMessage()); + this.status = status.getCode(); + } + + /** + * @return The status code of the exception. + */ + public int getStatus() { + return status; + } +} diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java new file mode 100644 index 00000000..88872b11 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java @@ -0,0 +1,28 @@ +package io.kuzzle.sdk.Exceptions; + +public enum KuzzleExceptionCode { + MISSING_REQUESTID(0, "Missing field requestId"), MSSING_QUERY(400, "You must provide a query"), + NOT_CONNECTED(500, "Not connected."), CONNECTION_LOST(500, "Connection lost"), + WRONG_VOLATILE_TYPE(400, "Volatile data must be a ConcurrentHashMap"); + + private final int code; + private final String message; + + KuzzleExceptionCode(final int code) { + this.code = code; + this.message = null; + } + + KuzzleExceptionCode(final int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return this.code; + } + + public String getMessage() { + return this.message; + } +} diff --git a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java b/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java similarity index 51% rename from kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java rename to src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java index 45e18656..1f695ccd 100644 --- a/kuzzle-sdk-java/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java @@ -5,10 +5,10 @@ */ public class NotConnectedException extends KuzzleException { - /** - * Initializes a new instance of the NotConnectedException. - */ - public NotConnectedException() { - super(KuzzleExceptionCode.NOT_CONNECTED); - } + /** + * Initializes a new instance of the NotConnectedException. + */ + public NotConnectedException() { + super(KuzzleExceptionCode.NOT_CONNECTED); + } } diff --git a/src/main/java/io/kuzzle/sdk/Helpers/Default.java b/src/main/java/io/kuzzle/sdk/Helpers/Default.java new file mode 100644 index 00000000..fc582719 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Helpers/Default.java @@ -0,0 +1,16 @@ +package io.kuzzle.sdk.Helpers; + +public class Default { + + /** + * Return the object or its default value in the case of the object is null. + * + * @param obj An object. + * @param defaultValue A default value in case your object is null. + * @param Object class. + * @return The object or the specified default value in case the object is null. + */ + public static T defaultValue(T obj, T defaultValue) { + return obj != null ? obj : defaultValue; + } +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java new file mode 100644 index 00000000..b47eeb8d --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -0,0 +1,292 @@ +package io.kuzzle.sdk; + +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Exceptions.*; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import io.kuzzle.sdk.CoreClasses.Responses.*; + +import static io.kuzzle.sdk.Helpers.Default.defaultValue; + +public class Kuzzle { + + protected EventListener tokenExpiredEvent; + protected EventListener unhandledResponseEvent; + + protected final AbstractProtocol networkProtocol; + + public final String version; + public final String instanceId; + public final String sdkName; + + /** + * Authentication token + */ + protected AtomicReference authenticationToken; + + /** + * The maximum amount of elements that the queue can contains. If set to -1, the + * size is unlimited. + */ + protected AtomicInteger maxQueueSize; + + /** + * The minimum duration of a Token before being automatically refreshed. If set + * to -1 the SDK does not refresh the token automatically. + */ + protected AtomicInteger minTokenDuration; + + /** + * The minimum duration of a Token after refresh. If set to -1 the SDK does not + * refresh the token automatically. + */ + protected AtomicInteger refreshedTokenDuration; + + /** + * The maximum delay between two requests to be replayed + */ + protected AtomicInteger maxRequestDelay; + + protected ConcurrentHashMap> requests = new ConcurrentHashMap<>(); + + /** + * Initialize a new instance of Kuzzle + * + * @param networkProtocol The network protocol + * @throws IllegalArgumentException + */ + public Kuzzle(AbstractProtocol networkProtocol) throws IllegalArgumentException { + this(networkProtocol, new KuzzleOptions()); + } + + /** + * Initialize a new instance of Kuzzle + * + * @param networkProtocol The network protocol + * @param options Kuzzle options + * @throws IllegalArgumentException + */ + public Kuzzle(AbstractProtocol networkProtocol, final KuzzleOptions options) throws IllegalArgumentException { + + if (networkProtocol == null) { + throw new IllegalArgumentException("networkProtocol can't be null"); + } + + KuzzleOptions kOptions = options != null ? options : new KuzzleOptions(); + + this.networkProtocol = networkProtocol; + this.networkProtocol.registerResponseEvent(this::onResponseReceived); + this.networkProtocol.registerStateChangeEvent(this::onStateChanged); + + this.maxQueueSize = new AtomicInteger(kOptions.getMaxQueueSize()); + this.minTokenDuration = new AtomicInteger(kOptions.getMinTokenDuration()); + this.refreshedTokenDuration = new AtomicInteger(kOptions.getRefreshedTokenDuration()); + this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); + + this.version = "3.0.0"; + this.instanceId = UUID.randomUUID().toString(); + this.sdkName = "java@" + version; + + this.tokenExpiredEvent = new EventListener(); + this.unhandledResponseEvent = new EventListener<>(); + } + + /** + * Establish a network connection + * + * @throws Exception + */ + public void connect() throws Exception { + networkProtocol.connect(); + } + + /** + * Disconnect this instance + */ + public void disconnect() { + networkProtocol.disconnect(); + } + + /** + * Handles the ResponseReceivedEvent from the network protocol + * + * @param payload Raw API Response + */ + protected void onResponseReceived(String payload) { + + Response response = new Response(); + try { + response.fromMap(JsonSerializer.deserialize(payload)); + } catch (InternalException e) { + e.printStackTrace(); + return; + } + + if (response.room == null || !requests.containsKey(response.room)) { + unhandledResponseEvent.trigger(response); + return; + } + + if (response.error == null) { + Task task = requests.get(response.requestId); + + if (task != null) { + task.trigger(response); + } + + requests.remove(response.requestId); + return; + } + + if (response.error.id == null || !response.error.id.equals("security.token.expired")) { + Task task = requests.get(response.requestId); + if (task != null) { + task.setException(new ApiErrorException(response)); + } + return; + } + + tokenExpiredEvent.trigger(); + } + + protected void onStateChanged(ProtocolState state) { + // If not connected anymore: close tasks and clean up the requests buffer + if (state == ProtocolState.CLOSE) { + for (Task task : requests.values()) { + task.setException(new ConnectionLostException()); + } + requests.clear(); + } + } + + /** + * Registers a callback to be called when the token expires + * + * @param callback A callback + * @return true if success + */ + public boolean registerTokenExpiredEvent(Runnable callback) { + return tokenExpiredEvent.register(callback); + } + + /** + * Unregisters a previously registered callback for the TokenExpired event + * + * @param callback A callback + * @return true if success + */ + public boolean unregisterTokenExpiredEvent(Runnable callback) { + return tokenExpiredEvent.unregister(callback); + } + + /** + * Registers a callback to be called when a response is unhandled + * + * @param callback A callback + * @return true if success + */ + public boolean registerUnhandledResponseEvent(Consumer callback) { + return unhandledResponseEvent.register(callback); + } + + /** + * @param callback Unregisters a previously registered callback for the + * UnhandledResponse event + * @return true if success + */ + public boolean unregisterUnhandledResponseEvent(Consumer callback) { + return unhandledResponseEvent.unregister(callback); + } + + /** + * Triggers the TokenExpired event + */ + public void dispatchTokenExpired() { + tokenExpiredEvent.trigger(); + } + + /** + * Sends an API request to Kuzzle and returns the corresponding API + * + * @param query Kuzzle API query + * @return A CompletableFuture + * @throws InternalException + * @throws NotConnectedException + */ + public CompletableFuture query(ConcurrentHashMap query) + throws InternalException, NotConnectedException { + if (query == null) { + throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); + } + + if (networkProtocol.getState() == ProtocolState.CLOSE) { + throw new NotConnectedException(); + } + + KuzzleMap queryMap = KuzzleMap.from(query); + + if (queryMap.contains("waitForRefresh")) { + if (queryMap.optBoolean("waitForRefresh", false).booleanValue()) { + queryMap.put("refresh", "wait_for"); + } + queryMap.remove("waitForRefresh"); + } + + if (authenticationToken != null) { + queryMap.put("jwt", authenticationToken); + } + + String requestId = UUID.randomUUID().toString(); + + queryMap.put("requestId", requestId); + + if (!queryMap.containsKey("volatile") || queryMap.isNull("volatile")) { + queryMap.put("volatile", new KuzzleMap()); + } else if (!queryMap.isMap("volatile")) { + throw new InternalException(KuzzleExceptionCode.WRONG_VOLATILE_TYPE); + } + + queryMap.getMap("volatile").put("sdkVersion", version); + + queryMap.getMap("volatile").put("sdkInstanceId", instanceId); + + queryMap.getMap("volatile").put("sdkName", sdkName); + + Task task = new Task<>(); + requests.put(requestId, task); + + if (networkProtocol.getState() == ProtocolState.OPEN) { + networkProtocol.send(queryMap); + } + + return task.getFuture(); + } + + /** + * @return The authentication token + */ + public String getAuthenticationToken() { + return authenticationToken.get(); + } + + /** + * Set the authentication token + * + * @param token Authentication token + */ + public void setAuthenticationToken(String token) { + authenticationToken.set(token); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java new file mode 100644 index 00000000..21d6999f --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java @@ -0,0 +1,145 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; + +import static io.kuzzle.sdk.Helpers.Default.defaultValue; + +public class KuzzleOptions { + + /** + * The maximum amount of elements that the queue can contains. If set to -1, the + * size is unlimited. + */ + private int maxQueueSize = -1; + + /** + * The minimum duration of a Token before being automatically refreshed. If set + * to -1 the SDK does not refresh the token automatically. + */ + private int minTokenDuration = 3_600_000; + + /** + * The minimum duration of a Token after refresh. If set to -1 the SDK does not + * refresh the token automatically. + */ + private int refreshedTokenDuration = 3_600_000; + + /** + * The maximum delay between two requests to be replayed. + */ + private int maxRequestDelay = 1000; + + private Predicate> filter = (ConcurrentHashMap obj) -> true; + + /** + * Initialize a new KuzzleOptions instance. + */ + public KuzzleOptions() { + } + + /** + * Initialize a new KuzzleOptions instance and copy other KuzzleOptions fields + * + * @param options + */ + public KuzzleOptions(KuzzleOptions options) { + this.maxQueueSize = options.maxQueueSize; + this.minTokenDuration = options.minTokenDuration; + this.refreshedTokenDuration = options.refreshedTokenDuration; + + this.maxRequestDelay = options.maxRequestDelay; + + this.filter = options.filter; + } + + /** + * @return The maximum amount of elements that the queue can contains. If set to + * -1, the size is unlimited. + */ + public int getMaxQueueSize() { + return maxQueueSize; + } + + /** + * Set the maximum amount of elements that the queue can contains. If set to -1, + * the size is unlimited. + * + * @param maxQueueSize + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMaxQueueSize(int maxQueueSize) { + this.maxQueueSize = maxQueueSize < 0 ? -1 : maxQueueSize; + + return this; + } + + /** + * @return The minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. + */ + public int getMinTokenDuration() { + return minTokenDuration; + } + + /** + * Set the minimum duration of a Token before being automatically refreshed. If + * set to -1 the SDK does not refresh the token automatically. + * + * @param minTokenDuration + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMinTokenDuration(int minTokenDuration) { + this.minTokenDuration = minTokenDuration < 0 ? -1 : minTokenDuration; + + return this; + } + + /** + * @return The minimum duration of a Token after refresh. If set to -1 the SDK + * does not refresh the token automatically. + */ + public int getRefreshedTokenDuration() { + return refreshedTokenDuration; + } + + /** + * Set the minimum duration of a Token after refresh. If set to -1 the SDK does + * not refresh the token automatically. + * + * @param refreshedTokenDuration + * @return This KuzzleOptions instance + */ + public KuzzleOptions withRefreshedTokenDuration(int refreshedTokenDuration) { + this.refreshedTokenDuration = refreshedTokenDuration < 0 ? -1 : refreshedTokenDuration; + + return this; + } + + /** + * @return The maximum delay between two requests to be replayed. + */ + public int getMaxRequestDelay() { + return maxRequestDelay; + } + + /** + * Set the maximum delay between two requests to be replayed. + * + * @param maxRequestDelay + * @return This KuzzleOptions instance + */ + public KuzzleOptions withMaxRequestDelay(int maxRequestDelay) { + this.maxRequestDelay = maxRequestDelay; + return this; + } + + public Predicate> getFilter() { + return filter; + } + + public KuzzleOptions withFilter(Predicate> filter) { + this.filter = defaultValue(filter, (ConcurrentHashMap obj) -> true); + return this; + } +} diff --git a/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java new file mode 100644 index 00000000..0c5df6d2 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java @@ -0,0 +1,117 @@ +package io.kuzzle.sdk.Options.Protocol; + +import io.kuzzle.sdk.Options.KuzzleOptions; + +public class WebSocketOptions { + + /** + * The port to use to connect. + */ + private int port = 7512; + + /** + * If we use SSL connection. + */ + private boolean ssl = false; + + /** + * The duration before the connection timeout. + */ + private int connectionTimeout = -1; + + /** + * If the websocket auto reconnects. + */ + private boolean autoReconnect = true; + + /** + * Initialize a new WebSocketOptions instance. + */ + public WebSocketOptions() { + } + + /** + * Initialize a new WebSocketOptions instance and copy other WebSocketOptions + * fields + * + * @param other + */ + public WebSocketOptions(WebSocketOptions other) { + this.port = other.port; + this.ssl = other.ssl; + this.connectionTimeout = other.connectionTimeout; + this.autoReconnect = other.autoReconnect; + } + + /** + * @return The port used to connect. + */ + public int getPort() { + return port; + } + + /** + * Set the port to use to connect. + * + * @param port + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withPort(int port) { + this.port = port >= 0 ? port : 7512; + return this; + } + + /** + * @return If we use SSL connection. + */ + public boolean isSsl() { + return ssl; + } + + /** + * Set if we use SSL connection. + * + * @param ssl + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withSsl(boolean ssl) { + this.ssl = ssl; + return this; + } + + /** + * @return The duration before the connection timeout. + */ + public int getConnectionTimeout() { + return connectionTimeout; + } + + /** + * Set the duration before the connection timeout. + * + * @param connectionTimeout + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout < 0 ? -1 : connectionTimeout; + return this; + } + + /** + * @return If the websocket auto reconnects. + */ + public boolean isAutoReconnect() { + return autoReconnect; + } + + /** + * Set if the websocket auto reconnects. + * + * @param autoReconnect + * @return This WebSocketOptions instance. + */ + public WebSocketOptions withAutoReconnect(boolean autoReconnect) { + this.autoReconnect = autoReconnect; + return this; + } +} diff --git a/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java b/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java new file mode 100644 index 00000000..d50127aa --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java @@ -0,0 +1,87 @@ +package io.kuzzle.sdk.Protocol; + +import io.kuzzle.sdk.Events.EventListener; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +public abstract class AbstractProtocol { + protected EventListener stateChanged; + protected EventListener messageReceived; + + public AbstractProtocol() { + stateChanged = new EventListener<>(); + messageReceived = new EventListener<>(); + } + + /** + * Current connection state. + * + * @return The state. + */ + public abstract ProtocolState getState(); + + /** + * connect this instance. + * + * @throws Exception + */ + public abstract void connect() throws Exception; + + /** + * Disconnect this instance. + */ + public abstract void disconnect(); + + /** + * Send the specified payload to Kuzzle. + * + * @param payload + */ + public abstract void send(ConcurrentHashMap payload); + + /** + * Register to the Response event + */ + public boolean registerResponseEvent(Consumer callback) { + return messageReceived.register(callback); + } + + /** + * Unregister from the Response event + */ + public boolean unregisterResponseEvent(Consumer callback) { + return messageReceived.unregister(callback); + } + + /** + * Register to the StateChange event + */ + public boolean registerStateChangeEvent(Consumer callback) { + return stateChanged.register(callback); + } + + /** + * Unregister from the StateChange event + */ + public boolean unregisterStateChangeEvent(Consumer callback) { + return stateChanged.unregister(callback); + } + + /** + * Dispatch a state changed event. + * + * @param state The ProtocolState. + */ + protected void dispatchStateChangeEvent(ProtocolState state) { + stateChanged.trigger(state); + } + + /** + * Dispatch a message received from a Kuzzle server. + * + * @param message Kuzzle API response. + */ + protected void dispatchResponseEvent(String message) { + messageReceived.trigger(message); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java b/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java new file mode 100644 index 00000000..5b3dcf6b --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java @@ -0,0 +1,6 @@ +package io.kuzzle.sdk.Protocol; + +public enum ProtocolState { + CLOSE, // The network protocol does not accept requests. + OPEN, // The network protocol accepts new requests. +} diff --git a/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java new file mode 100644 index 00000000..b7690917 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java @@ -0,0 +1,166 @@ +package io.kuzzle.sdk.Protocol; + +import com.neovisionaries.ws.client.WebSocketAdapter; +import com.neovisionaries.ws.client.WebSocketFactory; +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; + +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.concurrent.*; + +public class WebSocket extends AbstractProtocol { + + protected BlockingDeque> queue; + protected com.neovisionaries.ws.client.WebSocket socket; + protected ProtocolState state = ProtocolState.CLOSE; + protected URI uri; + + protected final boolean ssl; + protected final int port; + protected int connectionTimeout; + + public ProtocolState getState() { + return state; + } + + public WebSocket(URI uri) throws Exception { + WebSocketOptions options = new WebSocketOptions(); + if (uri.getPort() > -1) { + options.withPort(uri.getPort()); + } + if (uri.getHost() == null || uri.getHost().isEmpty()) { + throw new URISyntaxException("Missing host", "Could not find host part"); + } + if (uri.getScheme() != null) { + options.withSsl(uri.getScheme().equals("wss")); + } + WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) : new WebSocketOptions(); + + ssl = wsOptions.isSsl(); + port = wsOptions.getPort(); + connectionTimeout = wsOptions.getConnectionTimeout(); + + this.uri = new URI((ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); + this.queue = new LinkedBlockingDeque<>(); + } + + public WebSocket(URI uri, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { + this(uri.getHost(), options); + } + + public WebSocket(String host) throws URISyntaxException, IllegalArgumentException { + this(host, new WebSocketOptions()); + } + + /** + * @param host Kuzzle host address + * @param options WebSocket options + * @throws URISyntaxException + * @throws IllegalArgumentException + */ + public WebSocket(String host, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { + super(); + + WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) : new WebSocketOptions(); + + ssl = wsOptions.isSsl(); + port = wsOptions.getPort(); + connectionTimeout = wsOptions.getConnectionTimeout(); + + if (host == null || host.isEmpty()) { + throw new IllegalArgumentException("Host name/address can't be empty"); + } + this.uri = new URI((ssl ? "wss" : "ws") + "://" + host + ":" + port + "/"); + this.queue = new LinkedBlockingDeque<>(); + } + + @Override + public void send(ConcurrentHashMap payload) { + queue.add(payload); + } + + protected com.neovisionaries.ws.client.WebSocket createClientSocket() throws IOException { + WebSocketFactory wsFactory = new WebSocketFactory(); + + if (connectionTimeout > -1) { + wsFactory = wsFactory.setConnectionTimeout(connectionTimeout); + } + + if (ssl) { + + wsFactory.setSocketFactory(SSLSocketFactory.getDefault()); + } + + return wsFactory.createSocket(uri); + } + + /** + * Connects to a Kuzzle server. + * + * @throws Exception + */ + @Override + public void connect() throws Exception { + if (socket != null) { + return; + } + + socket = createClientSocket(); + + socket.connect(); + state = ProtocolState.OPEN; + dispatchStateChangeEvent(state); + Dequeue(); + + socket.addListener(new WebSocketAdapter() { + @Override + public void onTextMessage(com.neovisionaries.ws.client.WebSocket websocket, String text) throws Exception { + super.onTextMessage(websocket, text); + dispatchResponseEvent(text); + } + }); + } + + /** + * Disconnects this instance. + */ + @Override + public void disconnect() { + CloseState(); + } + + protected void CloseState() { + if (socket != null) { + socket.disconnect(); + state = ProtocolState.CLOSE; + socket = null; + dispatchStateChangeEvent(state); + } + } + + protected Thread Dequeue() { + Thread thread = new Thread(() -> { + while (state == ProtocolState.OPEN) { + ConcurrentHashMap payload = queue.poll(); + if (payload != null) { + String rawJson = JsonSerializer.serialize(payload); + socket.sendText(rawJson); + } + } + }); + thread.start(); + return thread; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout < 0 ? -1 : connectionTimeout; + } +} diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java new file mode 100644 index 00000000..08959ee1 --- /dev/null +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/KuzzleMapTest.java @@ -0,0 +1,236 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +public class KuzzleMapTest { + private KuzzleMap kuzzleMap; + + @Before + public void setup() throws URISyntaxException { + kuzzleMap = new KuzzleMap(); + kuzzleMap.put("String", "String"); + kuzzleMap.put("Number", 0); + kuzzleMap.put("Boolean", false); + kuzzleMap.put("ArrayList", new ArrayList<>()); + kuzzleMap.put("Map", new ConcurrentHashMap<>()); + kuzzleMap.put("KuzzleMap", new KuzzleMap()); + kuzzleMap.put("Null", null); + } + + @Test + public void isString() { + Assert.assertTrue(kuzzleMap.isString("String")); + Assert.assertFalse(kuzzleMap.isString("Number")); + Assert.assertFalse(kuzzleMap.isString("Boolean")); + Assert.assertFalse(kuzzleMap.isString("ArrayList")); + Assert.assertFalse(kuzzleMap.isString("Map")); + Assert.assertFalse(kuzzleMap.isString("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isString("Null")); + Assert.assertFalse(kuzzleMap.isString("UnknownKey")); + } + + @Test + public void isNumber() { + Assert.assertFalse(kuzzleMap.isNumber("String")); + Assert.assertTrue(kuzzleMap.isNumber("Number")); + Assert.assertFalse(kuzzleMap.isNumber("Boolean")); + Assert.assertFalse(kuzzleMap.isNumber("ArrayList")); + Assert.assertFalse(kuzzleMap.isNumber("Map")); + Assert.assertFalse(kuzzleMap.isNumber("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isNumber("Null")); + Assert.assertFalse(kuzzleMap.isNumber("UnknownKey")); + } + + @Test + public void isBoolean() throws Exception { + Assert.assertFalse(kuzzleMap.isBoolean("String")); + Assert.assertFalse(kuzzleMap.isBoolean("Number")); + Assert.assertTrue(kuzzleMap.isBoolean("Boolean")); + Assert.assertFalse(kuzzleMap.isBoolean("ArrayList")); + Assert.assertFalse(kuzzleMap.isBoolean("Map")); + Assert.assertFalse(kuzzleMap.isBoolean("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isBoolean("Null")); + Assert.assertFalse(kuzzleMap.isBoolean("UnknownKey")); + } + + @Test + public void isArrayList() { + Assert.assertFalse(kuzzleMap.isArrayList("String")); + Assert.assertFalse(kuzzleMap.isArrayList("Number")); + Assert.assertFalse(kuzzleMap.isArrayList("Boolean")); + Assert.assertTrue(kuzzleMap.isArrayList("ArrayList")); + Assert.assertFalse(kuzzleMap.isArrayList("Map")); + Assert.assertFalse(kuzzleMap.isArrayList("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isArrayList("Null")); + Assert.assertFalse(kuzzleMap.isArrayList("UnknownKey")); + } + + @Test + public void isMap() { + Assert.assertFalse(kuzzleMap.isMap("String")); + Assert.assertFalse(kuzzleMap.isMap("Number")); + Assert.assertFalse(kuzzleMap.isMap("Boolean")); + Assert.assertFalse(kuzzleMap.isMap("ArrayList")); + Assert.assertTrue(kuzzleMap.isMap("Map")); + Assert.assertTrue(kuzzleMap.isMap("KuzzleMap")); + Assert.assertFalse(kuzzleMap.isMap("Null")); + Assert.assertFalse(kuzzleMap.isMap("UnknownKey")); + } + + @Test + public void isNull() { + Assert.assertFalse(kuzzleMap.isNull("String")); + Assert.assertFalse(kuzzleMap.isNull("Number")); + Assert.assertFalse(kuzzleMap.isNull("Boolean")); + Assert.assertFalse(kuzzleMap.isNull("ArrayList")); + Assert.assertFalse(kuzzleMap.isNull("Map")); + Assert.assertFalse(kuzzleMap.isNull("KuzzleMap")); + Assert.assertTrue(kuzzleMap.isNull("Null")); + Assert.assertFalse(kuzzleMap.isNull("UnknownKey")); + } + + @Test + public void getString() { + Assert.assertNotNull(kuzzleMap.getString("String")); + Assert.assertNull(kuzzleMap.getString("Number")); + Assert.assertNull(kuzzleMap.getString("Boolean")); + Assert.assertNull(kuzzleMap.getString("ArrayList")); + Assert.assertNull(kuzzleMap.getString("Map")); + Assert.assertNull(kuzzleMap.getString("KuzzleMap")); + Assert.assertNull(kuzzleMap.getString("Null")); + Assert.assertNull(kuzzleMap.getString("UnknownKey")); + } + + @Test + public void getNumber() { + Assert.assertNull(kuzzleMap.getNumber("String")); + Assert.assertNotNull(kuzzleMap.getNumber("Number")); + Assert.assertNull(kuzzleMap.getNumber("Boolean")); + Assert.assertNull(kuzzleMap.getNumber("ArrayList")); + Assert.assertNull(kuzzleMap.getNumber("Map")); + Assert.assertNull(kuzzleMap.getNumber("KuzzleMap")); + Assert.assertNull(kuzzleMap.getNumber("Null")); + Assert.assertNull(kuzzleMap.getNumber("UnknownKey")); + } + + @Test + public void getBoolean() { + Assert.assertNull(kuzzleMap.getBoolean("String")); + Assert.assertNull(kuzzleMap.getBoolean("Number")); + Assert.assertNotNull(kuzzleMap.getBoolean("Boolean")); + Assert.assertNull(kuzzleMap.getBoolean("ArrayList")); + Assert.assertNull(kuzzleMap.getBoolean("Map")); + Assert.assertNull(kuzzleMap.getBoolean("KuzzleMap")); + Assert.assertNull(kuzzleMap.getBoolean("Null")); + Assert.assertNull(kuzzleMap.getBoolean("UnknownKey")); + } + + @Test + public void getArrayList() { + Assert.assertNull(kuzzleMap.getArrayList("String")); + Assert.assertNull(kuzzleMap.getArrayList("Number")); + Assert.assertNull(kuzzleMap.getArrayList("Boolean")); + Assert.assertNotNull(kuzzleMap.getArrayList("ArrayList")); + Assert.assertNull(kuzzleMap.getArrayList("Map")); + Assert.assertNull(kuzzleMap.getArrayList("KuzzleMap")); + Assert.assertNull(kuzzleMap.getArrayList("Null")); + Assert.assertNull(kuzzleMap.getArrayList("UnknownKey")); + } + + @Test + public void getMap() { + Assert.assertNull(kuzzleMap.getMap("String")); + Assert.assertNull(kuzzleMap.getMap("Number")); + Assert.assertNull(kuzzleMap.getMap("Boolean")); + Assert.assertNull(kuzzleMap.getMap("ArrayList")); + Assert.assertNotNull(kuzzleMap.getMap("Map")); + Assert.assertNotNull(kuzzleMap.getMap("KuzzleMap")); + Assert.assertNull(kuzzleMap.getMap("Null")); + Assert.assertNull(kuzzleMap.getMap("UnknownKey")); + } + + @Test + public void get() { + Assert.assertTrue(kuzzleMap.get("String") instanceof String); + Assert.assertTrue(kuzzleMap.get("Number") instanceof Number); + Assert.assertTrue(kuzzleMap.get("Boolean") instanceof Boolean); + Assert.assertTrue(kuzzleMap.get("ArrayList") instanceof ArrayList); + Assert.assertTrue(kuzzleMap.get("Map") instanceof ConcurrentHashMap); + Assert.assertTrue(kuzzleMap.get("KuzzleMap") instanceof ConcurrentHashMap); + Assert.assertTrue(kuzzleMap.get("Null") == null); + Assert.assertTrue(kuzzleMap.get("UnknownKey") == null); + } + + @Test + public void optString() { + Assert.assertTrue(kuzzleMap.optString("String", "foo").equals("String")); + Assert.assertTrue(kuzzleMap.optString("Number", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Boolean", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("ArrayList", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Map", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("KuzzleMap", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("Null", "foo").equals("foo")); + Assert.assertTrue(kuzzleMap.optString("UnknownKey", "foo").equals("foo")); + } + + @Test + public void optNumber() { + Assert.assertTrue(kuzzleMap.optNumber("String", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Number", 42).equals(0)); + Assert.assertTrue(kuzzleMap.optNumber("Boolean", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("ArrayList", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Map", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("KuzzleMap", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("Null", 42).equals(42)); + Assert.assertTrue(kuzzleMap.optNumber("UnknownKey", 42).equals(42)); + } + + @Test + public void optBoolean() { + Assert.assertTrue(kuzzleMap.optBoolean("String", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Number", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Boolean", true).equals(false)); + Assert.assertTrue(kuzzleMap.optBoolean("ArrayList", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Map", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("KuzzleMap", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("Null", true).equals(true)); + Assert.assertTrue(kuzzleMap.optBoolean("UnknownKey", true).equals(true)); + } + + @Test + public void optArrayList() { + ArrayList list = new ArrayList<>(); + list.add(1); + + Assert.assertEquals(kuzzleMap.optArrayList("String", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Number", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Boolean", list).hashCode(), list.hashCode()); + Assert.assertNotEquals(kuzzleMap.optArrayList("ArrayList", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Map", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("KuzzleMap", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("Null", list).hashCode(), list.hashCode()); + Assert.assertEquals(kuzzleMap.optArrayList("UnknownKey", list).hashCode(), list.hashCode()); + } + + @Test + public void optMap() { + KuzzleMap map = new KuzzleMap(); + map.put("Data", 1); + + Assert.assertEquals(kuzzleMap.optMap("String", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Number", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Boolean", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("ArrayList", map).hashCode(), map.hashCode()); + Assert.assertNotEquals(kuzzleMap.optMap("Map", map).hashCode(), map.hashCode()); + Assert.assertNotEquals(kuzzleMap.optMap("KuzzleMap", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("Null", map).hashCode(), map.hashCode()); + Assert.assertEquals(kuzzleMap.optMap("UnknownKey", map).hashCode(), map.hashCode()); + } +} diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java new file mode 100644 index 00000000..8386f7f8 --- /dev/null +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java @@ -0,0 +1,124 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import io.kuzzle.sdk.CoreClasses.Task; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + +public class TaskTests { + + @Test + public void constructorTest() { + TestableTask task = new TestableTask<>(); + Assert.assertNotNull(task.getAtomicReference()); + Assert.assertEquals(AtomicReference.class, task.getAtomicReference().getClass()); + Assert.assertNotNull(task.getCountDownLatch()); + Assert.assertEquals(CountDownLatch.class, task.getCountDownLatch().getClass()); + Assert.assertNotNull(task.getFuture()); + } + + @Test + public void getFutureTest() { + Task task = new Task<>(); + + Assert.assertEquals(CompletableFuture.class, task.getFuture().getClass()); + } + + @Test + public void setExceptionTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + task.setException(new Exception("foobar")); + + verify(task.mockedFuture, times(1)).completeExceptionally(any(Exception.class)); + } + + @Test + public void isCancelledTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isCancelled()).thenReturn(true); + + Assert.assertTrue(task.isCancelled()); + + verify(task.mockedFuture, times(1)).isCancelled(); + } + + @Test + public void isDoneTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isDone()).thenReturn(true); + + Assert.assertTrue(task.isDone()); + + verify(task.mockedFuture, times(1)).isDone(); + } + + @Test + public void isCompletedExceptionallyTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + when(task.mockedFuture.isCompletedExceptionally()).thenReturn(true); + + Assert.assertTrue(task.isCompletedExceptionally()); + + verify(task.mockedFuture, times(1)).isCompletedExceptionally(); + } + + @Test + public void setCancelledTest() { + TestableTask task = new TestableTask<>(); + task.applyMockFuture(); + + task.setCancelled(true); + + verify(task.mockedFuture, times(1)).cancel(anyBoolean()); + } + + @Test + public void triggerTest() { + Task task = new Task(); + + final AtomicBoolean success = new AtomicBoolean(false); + + CompletableFuture taskChain = task.getFuture().thenRun(() -> { + success.set(true); + }); + + task.trigger(); + + taskChain.join(); + + Assert.assertTrue(success.get()); + + } + + @Test + public void triggerWithObjectTest() { + Task task = new Task(); + + final AtomicBoolean success = new AtomicBoolean(false); + + CompletableFuture taskChain = task.getFuture().thenAccept((str) -> { + success.set(str.equals("foobar")); + }); + + task.trigger("foobar"); + + taskChain.join(); + + Assert.assertTrue(success.get()); + } +} diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java new file mode 100644 index 00000000..7ac9140f --- /dev/null +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java @@ -0,0 +1,31 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import io.kuzzle.sdk.CoreClasses.Task; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.Mockito.mock; + +public class TestableTask extends Task { + public CountDownLatch mockedCountDownLatch = mock(CountDownLatch.class); + public CompletableFuture mockedFuture = mock(CompletableFuture.class); + + public TestableTask() { + super(); + } + + public void applyMockFuture() { + super.future = mockedFuture; + } + + public CountDownLatch getCountDownLatch() { + return super.countDownLatch; + } + + public AtomicReference getAtomicReference() { + return super.atomicReference; + } + +} diff --git a/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java b/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java new file mode 100644 index 00000000..441de60c --- /dev/null +++ b/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java @@ -0,0 +1,142 @@ +package io.kuzzle.test.EventsTest; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class EventListenerTests { + + @Test + public void registerRunnableTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.register(() -> { + }); + + verify(eventListener.mockedCallbacks, times(1)).add(any(Runnable.class)); + } + + @Test + public void unregisterRunnableTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.unregister(() -> { + }); + + verify(eventListener.mockedCallbacks, times(1)).remove(any(Runnable.class)); + } + + @Test + public void registerConsumerTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.register((obj) -> { + }); + + verify(eventListener.mockedCallbacks, times(1)).add(any(Consumer.class)); + } + + @Test + public void unregisterConsumerTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + eventListener.applyMock(); + + eventListener.unregister((obj) -> { + }); + + verify(eventListener.mockedCallbacks, times(1)).remove(any(Consumer.class)); + } + + @Test + public void registerDuplicateTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + + Runnable runnable1 = () -> { + }; + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(runnable1); + eventListener.register(() -> { + }); + + Assert.assertEquals(2, eventListener.getCallbacks().size()); + } + + @Test + public void triggerRunnableTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + + AtomicBoolean success = new AtomicBoolean(false); + eventListener.register(() -> success.set(true)); + + Assert.assertFalse(success.get()); + + eventListener.trigger(); + + Assert.assertTrue(success.get()); + } + + @Test + public void triggerConsumerTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + + AtomicBoolean success = new AtomicBoolean(false); + eventListener.register((str) -> success.set(str.equals("foobar"))); + + Assert.assertFalse(success.get()); + + eventListener.trigger("foobar"); + + Assert.assertTrue(success.get()); + } + + @Test + public void triggerOnlyConsumerTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + + AtomicBoolean consumerSuccess = new AtomicBoolean(false); + AtomicBoolean runnableSuccess = new AtomicBoolean(false); + + eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); + eventListener.register(() -> runnableSuccess.set(true)); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + + eventListener.trigger("foobar"); + + Assert.assertTrue(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + } + + @Test + public void triggerOnlyRunnableTest() { + TestableEventListener eventListener = new TestableEventListener<>(); + + AtomicBoolean consumerSuccess = new AtomicBoolean(false); + AtomicBoolean runnableSuccess = new AtomicBoolean(false); + + eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); + eventListener.register(() -> runnableSuccess.set(true)); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertFalse(runnableSuccess.get()); + + eventListener.trigger(); + + Assert.assertFalse(consumerSuccess.get()); + Assert.assertTrue(runnableSuccess.get()); + } + +} diff --git a/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java b/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java new file mode 100644 index 00000000..42c48d5c --- /dev/null +++ b/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java @@ -0,0 +1,23 @@ +package io.kuzzle.test.EventsTest; + +import io.kuzzle.sdk.Events.EventListener; + +import java.util.Set; + +import static org.mockito.Mockito.mock; + +public class TestableEventListener extends EventListener { + public Set mockedCallbacks = mock(Set.class); + + public TestableEventListener() { + super(); + } + + public void applyMock() { + super.callbacks = mockedCallbacks; + } + + public Set getCallbacks() { + return super.callbacks; + } +} diff --git a/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java b/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java new file mode 100644 index 00000000..c4152d3a --- /dev/null +++ b/src/test/java/io/kuzzle/test/Helpers/DefaultTests.java @@ -0,0 +1,24 @@ +package io.kuzzle.test.Helpers; + +import io.kuzzle.sdk.Helpers.Default; +import org.junit.Assert; +import org.junit.Test; + +public class DefaultTests { + + @Test + public void notNullTest() { + String str1 = Default.defaultValue(null, "foobar"); + String str2 = Default.defaultValue("SomeString", "foobar"); + + Integer int1 = Default.defaultValue(null, 42); + Integer int2 = Default.defaultValue(10, 42); + + Assert.assertEquals("foobar", str1); + Assert.assertEquals("SomeString", str2); + + Assert.assertEquals(42, int1.intValue()); + Assert.assertEquals(10, int2.intValue()); + } + +} diff --git a/src/test/java/io/kuzzle/test/KuzzleTests.java b/src/test/java/io/kuzzle/test/KuzzleTests.java new file mode 100644 index 00000000..1c498031 --- /dev/null +++ b/src/test/java/io/kuzzle/test/KuzzleTests.java @@ -0,0 +1,139 @@ +package io.kuzzle.test; + +import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.CoreClasses.Responses.ErrorResponse; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import java.net.URISyntaxException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +public class KuzzleTests { + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + private EventListener tokenExpiredEventListener = Mockito.mock(EventListener.class); + private EventListener unhandledResponseEventListener = Mockito.mock(EventListener.class); + private TestableKuzzle kuzzle; + + @Before + public void setup() throws URISyntaxException { + kuzzle = new TestableKuzzle(networkProtocol); + kuzzle.setTokenExpiredEventListener(tokenExpiredEventListener); + kuzzle.setUnhandledResponseEventListener(unhandledResponseEventListener); + } + + @Test + public void connect() throws Exception { + kuzzle.connect(); + Mockito.verify(networkProtocol, Mockito.times(1)).connect(); + } + + @Test + public void disconnect() throws Exception { + kuzzle.disconnect(); + Mockito.verify(networkProtocol, Mockito.times(1)).disconnect(); + } + + @Test + public void registerTokenExpiredEvent() throws Exception { + kuzzle.registerTokenExpiredEvent(() -> { + }); + Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).register(Matchers.any(Runnable.class)); + } + + @Test + public void unregisterTokenExpiredEvent() throws Exception { + kuzzle.unregisterTokenExpiredEvent(() -> { + }); + Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).unregister(Matchers.any(Runnable.class)); + } + + @Test + public void onStateChanged() { + ConcurrentHashMap> requests = kuzzle.getRequests(); + + Task response = new Task<>(); + requests.put("foobar", response); + kuzzle.onStateChanged(ProtocolState.CLOSE); + Assert.assertEquals(0, requests.size()); + Assert.assertTrue(response.isCompletedExceptionally()); + } + + @Test(expected = NotConnectedException.class) + public void queryShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + kuzzle.query(new ConcurrentHashMap<>()); + } + + @Test + public void querySuccess() throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.OPEN); + + CompletableFuture response = kuzzle.query(new ConcurrentHashMap<>()); + + Assert.assertNotNull(response); + Mockito.verify(networkProtocol, Mockito.times(1)).send(Matchers.any(ConcurrentHashMap.class)); + } + + @Test(expected = InternalException.class) + public void queryShouldThrowWhenVolatileIsNotConcurrentHashMap() throws NotConnectedException, InternalException { + Mockito.when(networkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.OPEN); + + ConcurrentHashMap payload = new ConcurrentHashMap<>(); + payload.put("volatile", "foobar"); + + kuzzle.query(payload); + } + + @Test + public void onResponseReceivedAndTokenIsExpired() { + ConcurrentHashMap> requests = kuzzle.getRequests(); + + Response response = new Response(); + response.requestId = "foobar"; + response.error = new ErrorResponse(); + response.error.id = "security.token.expired"; + response.error.status = 42; + response.room = "room-id"; + + Task task = new Task<>(); + + requests.put("room-id", task); + + kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); + + Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).trigger(); + } + + @Test + public void onResponseReceivedAndResponseIsUnhandled() { + ConcurrentHashMap> requests = kuzzle.getRequests(); + + AtomicBoolean success = new AtomicBoolean(false); + Response response = new Response(); + response.requestId = "foobar"; + + Task task = new Task<>(); + + requests.put("request-id", task); + + kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); + + Mockito.verify(unhandledResponseEventListener, Mockito.times(1)).trigger(Matchers.any(Response.class)); + } + +} diff --git a/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java b/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java new file mode 100644 index 00000000..c6c5db13 --- /dev/null +++ b/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java @@ -0,0 +1,35 @@ +package io.kuzzle.test.ProtocolTest; + +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; +import java.net.URISyntaxException; + +import static org.mockito.Mockito.mock; + +public class TestableWebSocket extends WebSocket { + public int stateChangedCount = 0; + public ProtocolState lastStateDispatched = ProtocolState.CLOSE; + public com.neovisionaries.ws.client.WebSocket mockedSocket = mock(com.neovisionaries.ws.client.WebSocket.class); + + public TestableWebSocket(String host) throws URISyntaxException, IllegalArgumentException { + super(host); + } + + public TestableWebSocket(String host, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { + super(host, options); + super.stateChanged.register((ProtocolState state) -> { + stateChangedCount += 1; + lastStateDispatched = state; + }); + } + + public com.neovisionaries.ws.client.WebSocket getSocket() { + return super.socket; + } + + @Override + protected com.neovisionaries.ws.client.WebSocket createClientSocket() { + return mockedSocket; + } +} diff --git a/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java new file mode 100644 index 00000000..d5f20dc9 --- /dev/null +++ b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java @@ -0,0 +1,85 @@ +package io.kuzzle.test.ProtocolTest; + +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.ProtocolState; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.net.URISyntaxException; + +import static org.mockito.Mockito.*; + +public class WebSocketTests { + + private TestableWebSocket socket; + private String host; + private WebSocketOptions options; + + @Before + public void setup() throws URISyntaxException { + host = "foo"; + options = new WebSocketOptions().withPort(1234).withSsl(true); + socket = new TestableWebSocket(host, options); + } + + @Test + public void constructorNotConnected() throws URISyntaxException { + TestableWebSocket ws = new TestableWebSocket(host, options); + + Assert.assertEquals(ProtocolState.CLOSE, ws.getState()); + Assert.assertNull(ws.getSocket()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorRejectsNullHost() throws URISyntaxException { + TestableWebSocket ws = new TestableWebSocket(null, options); + } + + @Test + public void connectTest() throws Exception { + when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); + + socket.connect(); + + Assert.assertNotNull(socket.getSocket()); + + socket.connect(); + socket.connect(); + socket.connect(); + + verify(socket.mockedSocket, times(1)).connect(); + + Assert.assertEquals(ProtocolState.OPEN, socket.getState()); + Assert.assertEquals(1, socket.stateChangedCount); + Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); + } + + @Test + public void disconnectTest() throws Exception { + when(socket.mockedSocket.connect()).thenAnswer(invocation -> null); + + socket.connect(); + + Assert.assertEquals(ProtocolState.OPEN, socket.getState()); + Assert.assertEquals(1, socket.stateChangedCount); + Assert.assertEquals(ProtocolState.OPEN, socket.lastStateDispatched); + + socket.disconnect(); + socket.disconnect(); + socket.disconnect(); + + verify(socket.mockedSocket, times(1)).disconnect(); + } + + @Test + public void disconnectWithoutEverConnecting() throws Exception { + Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); + Assert.assertEquals(0, socket.stateChangedCount); + + socket.disconnect(); + + Assert.assertEquals(ProtocolState.CLOSE, socket.getState()); + Assert.assertEquals(0, socket.stateChangedCount); + } +} diff --git a/src/test/java/io/kuzzle/test/TestableKuzzle.java b/src/test/java/io/kuzzle/test/TestableKuzzle.java new file mode 100644 index 00000000..d8a9d579 --- /dev/null +++ b/src/test/java/io/kuzzle/test/TestableKuzzle.java @@ -0,0 +1,51 @@ +package io.kuzzle.test; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; + +import java.net.URISyntaxException; +import java.util.concurrent.ConcurrentHashMap; + +public class TestableKuzzle extends Kuzzle { + + public TestableKuzzle(AbstractProtocol networkProtocol) throws URISyntaxException, IllegalArgumentException { + super(networkProtocol); + } + + public TestableKuzzle(AbstractProtocol networkProtocol, KuzzleOptions options) throws IllegalArgumentException { + super(networkProtocol, options); + } + + public void setTokenExpiredEventListener(EventListener eventListener) { + super.tokenExpiredEvent = eventListener; + } + + public EventListener getTokenExpiredEventListener() { + return super.tokenExpiredEvent; + } + + public void setUnhandledResponseEventListener(EventListener eventListener) { + super.unhandledResponseEvent = eventListener; + } + + public EventListener getUnhandledResponseEventListener() { + return super.unhandledResponseEvent; + } + + public void onStateChanged(ProtocolState state) { + super.onStateChanged(state); + } + + public void onResponseReceived(String payload) { + super.onResponseReceived(payload); + } + + public ConcurrentHashMap> getRequests() { + return super.requests; + } +} From 6192b2afcbda179241b1874cba3c5b2d5c246a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Fri, 17 Jan 2020 14:51:55 +0100 Subject: [PATCH 010/134] Add rules to generate and publish the .jar (#47) What does this PR do ? Depends on #46 Add rules to generate and publish the .jar --- build.gradle | 73 +++++++++ gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 183 +++++++++++++++++++++++ gradlew.bat | 100 +++++++++++++ 5 files changed, 361 insertions(+) create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat diff --git a/build.gradle b/build.gradle index 70d4d8d0..69729b57 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ import org.gradle.api.JavaVersion plugins { + id "com.jfrog.bintray" version "1.7.3" id 'jacoco' id 'java' } @@ -24,6 +25,77 @@ repositories { mavenCentral() } +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +javadoc.failOnError = false +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +bintray { + user = System.getenv('BINTRAY_USER') + key = System.getenv('BINTRAY_KEY') + publications = ['MyPublication'] + + pkg { + repo = 'maven' + name = 'kuzzle-sdk-java' + userOrg = 'kuzzle' + licenses = ['Apache-2.0'] + desc = 'Kuzzle JAVA SDK' + vcsUrl = 'https://github.com/kuzzleio/sdk-java.git' + websiteUrl = 'https://kuzzle.io' + issueTrackerUrl = 'https://github.com/kuzzleio/sdk-java/issues' + publicDownloadNumbers = true + publish = true + } +} + +def pomConfig = { + licenses { + license { + name "The Apache Software License, Version 2.0" + url "http://www.apache.org/licenses/LICENSE-2.0.txt" + distribution "repo" + } + } + developers { + developer { + id "kuzzle" + name "kuzzle" + email "support@kuzzle.io" + } + } + + scm { + url "https://github.com/kuzzleio/sdk-java" + } +} + +publishing { + publications { + MyPublication(MavenPublication) { + from components.java + artifact sourcesJar + artifact javadocJar + groupId 'io.kuzzle' + artifactId 'sdk-java' + version version + pom.withXml { + def root = asNode() + root.appendNode('description', 'Kuzzle JAVA SDK') + root.appendNode('name', 'sdk-java') + root.appendNode('url', 'https://github.com/kuzzleio/sdk-java') + root.children().last() + pomConfig + } + } + } +} + dependencies { implementation 'com.neovisionaries:nv-websocket-client:2.9' implementation 'com.google.code.gson:gson:2.8.5' @@ -52,3 +124,4 @@ test { maxHeapSize = '1G' } + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 25668 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

r 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 Hp`iW;?oWjv delta 22507 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..24467a14 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From da6407bffaa5e9b3d3941820f7cd94edfff74c60 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 11:37:10 +0100 Subject: [PATCH 011/134] [doc-ci] dep & deploy fix --- .gitignore | 3 +- .travis.yml | 30 +- package-lock.json | 1525 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 15 +- 4 files changed, 1556 insertions(+), 17 deletions(-) create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 2407ed41..151f1041 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ bin .project .settings -doc/framework \ No newline at end of file +doc/framework +node_modules diff --git a/.travis.yml b/.travis.yml index 7f0c1e3d..0977e11b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,8 +39,8 @@ jobs: - python-pip install: - - cd $TRAVIS_BUILD_DIR/ - - gradle assemble + - npm ci + script: - npm run doc-prepare - npm run doc-build && cd - @@ -48,8 +48,10 @@ jobs: deploy: provider: script script: - - npm run doc-upload && cd - + - npm run doc-upload && cd - skip_cleanup: true + on: + all_branches: true after_deploy: - npm run doc-cloudfront && cd - @@ -72,14 +74,22 @@ jobs: - python-pip install: - - cd $TRAVIS_BUILD_DIR/ - - gradle assemble - - cd $TRAVIS_BUILD_DIR/ - - gradle assemble + - npm ci + script: - - gradle check - after_success: - - bash <(curl -s https://codecov.io/bash) + - npm run doc-prepare + - npm run doc-build && cd - + + deploy: + provider: script + script: + - npm run doc-upload && cd - + skip_cleanup: true + on: + all_branches: true + + after_deploy: + - npm run doc-cloudfront && cd - # --------------------------------------- # Builds diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..eca555d5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1525 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@oclif/command": { + "version": "1.5.19", + "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.5.19.tgz", + "integrity": "sha512-6+iaCMh/JXJaB2QWikqvGE9//wLEVYYwZd5sud8aLoLKog1Q75naZh2vlGVtg5Mq/NqpqGQvdIjJb3Bm+64AUQ==", + "requires": { + "@oclif/config": "^1", + "@oclif/errors": "^1.2.2", + "@oclif/parser": "^3.8.3", + "@oclif/plugin-help": "^2", + "debug": "^4.1.1", + "semver": "^5.6.0" + } + }, + "@oclif/config": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.13.3.tgz", + "integrity": "sha512-qs5XvGRw+1M41abOKCjd0uoeHCgsMxa2MurD2g2K8CtQlzlMXl0rW5idVeimIg5208LLuxkfzQo8TKAhhRCWLg==", + "requires": { + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "tslib": "^1.9.3" + } + }, + "@oclif/errors": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.2.2.tgz", + "integrity": "sha512-Eq8BFuJUQcbAPVofDxwdE0bL14inIiwt5EaKRVY9ZDIG11jwdXZqiQEECJx0VfnLyUZdYfRd/znDI/MytdJoKg==", + "requires": { + "clean-stack": "^1.3.0", + "fs-extra": "^7.0.0", + "indent-string": "^3.2.0", + "strip-ansi": "^5.0.0", + "wrap-ansi": "^4.0.0" + } + }, + "@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" + }, + "@oclif/parser": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.4.tgz", + "integrity": "sha512-cyP1at3l42kQHZtqDS3KfTeyMvxITGwXwH1qk9ktBYvqgMp5h4vHT+cOD74ld3RqJUOZY/+Zi9lb4Tbza3BtuA==", + "requires": { + "@oclif/linewrap": "^1.0.0", + "chalk": "^2.4.2", + "tslib": "^1.9.3" + } + }, + "@oclif/plugin-help": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-2.2.3.tgz", + "integrity": "sha512-bGHUdo5e7DjPJ0vTeRBMIrfqTRDBfyR5w0MP41u0n3r7YG5p14lvMmiCXxi6WDaP2Hw5nqx3PnkAIntCKZZN7g==", + "requires": { + "@oclif/command": "^1.5.13", + "chalk": "^2.4.1", + "indent-string": "^4.0.0", + "lodash.template": "^4.4.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0", + "widest-line": "^2.0.1", + "wrap-ansi": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "@oclif/screen": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", + "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==" + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/listr": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@types/listr/-/listr-0.14.2.tgz", + "integrity": "sha512-wCipMbQr3t2UHTm90LldVp+oTBj1TX6zvpkCJcWS4o8nn6kS8SN93oUvKJAgueIRZ5M36yOlFmScqBxYH8Ajig==", + "requires": { + "@types/node": "*", + "rxjs": "^6.5.1" + } + }, + "@types/node": { + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.8.tgz", + "integrity": "sha512-6XzyyNM9EKQW4HKuzbo/CkOIjn/evtCmsU+MUM1xDfJ+3/rNjBttM1NgN7AOQvN6tP1Sl1D1PIKMreTArnxM9A==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "clean-stack": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", + "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-progress": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.5.0.tgz", + "integrity": "sha512-S1wR4xfcfLWbVBH6RwYat1nMCm2UsuygxNoiRYVAXQsuWKjCRgWRZVohXLmsWfiuAK0FFf7t9OyZ2JBmDWaQGA==", + "requires": { + "colors": "^1.1.2", + "string-width": "^2.1.1" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "cli-ux": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.4.2.tgz", + "integrity": "sha512-DdebO9mCNjY0+rtzucZ3GcAaW5iI/2DFFSUU/R9Dx5ubnOa8gFb2+4gh7NqZCL/jL0zZgW7UFcKvYADi0WHI1Q==", + "requires": { + "@oclif/command": "^1.5.1", + "@oclif/errors": "^1.2.1", + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^1.0.3", + "ansi-escapes": "^3.1.0", + "ansi-styles": "^3.2.1", + "cardinal": "^2.1.1", + "chalk": "^2.4.1", + "clean-stack": "^2.0.0", + "cli-progress": "^3.4.0", + "extract-stack": "^1.0.0", + "fs-extra": "^7.0.1", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^1.1.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.11", + "natural-orderby": "^2.0.1", + "password-prompt": "^1.1.2", + "semver": "^5.6.0", + "string-width": "^3.1.0", + "strip-ansi": "^5.1.0", + "supports-color": "^5.5.0", + "supports-hyperlinks": "^1.0.1", + "treeify": "^1.1.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "execa": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.0.tgz", + "integrity": "sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "extract-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-1.0.0.tgz", + "integrity": "sha1-uXrK+UQe6iMyUpYktzL8WhyBZfo=" + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kuzdoc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/kuzdoc/-/kuzdoc-1.2.2.tgz", + "integrity": "sha512-QXw4dVIh4dRoD/9Vz9tbpfKNT9Y0AEORJyRHIwKuHaxH65Ccr7KHwxSTbJokK/PV4PebRDO96sPodEc/4NrxbQ==", + "requires": { + "@oclif/command": "^1.5.19", + "@oclif/config": "^1.13.3", + "@oclif/plugin-help": "^2.2.3", + "@types/listr": "^0.14.2", + "axios": "^0.19.0", + "cli-ux": "^5.4.1", + "execa": "^4.0.0", + "express": "^4.17.1", + "listr": "^0.14.3", + "tslib": "^1.10.0", + "yaml": "^1.7.2" + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=" + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + } + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "requires": { + "chalk": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "requires": { + "mime-db": "1.43.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + }, + "dependencies": { + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + } + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "requires": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "requires": { + "esprima": "~4.0.0" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "requires": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "requires": { + "string-width": "^2.1.1" + } + }, + "wrap-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz", + "integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "requires": { + "@babel/runtime": "^7.6.3" + } + } + } +} diff --git a/package.json b/package.json index 947f07b4..0b74e3db 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,14 @@ { "scripts": { - "doc-prepare": "cd doc && bash doc.sh prepare", - "doc-dev": "cd doc && bash doc.sh dev", - "doc-build": "cd doc && bash doc.sh build", - "doc-upload": "cd doc && bash doc.sh upload", - "doc-cloudfront": "cd doc && bash doc.sh cloudfront", + "doc-prepare": "kuzdoc framework:install", + "doc-dev": "kuzdoc repo:dev -d /sdk/java/3/ -v 3", + "doc-build": "kuzdoc repo:build -d /sdk/java/3/ -v 3", + "doc-upload": "kuzdoc repo:deploy -d /sdk/java/3/ -v 3", + "doc-cloudfront": "kuzdoc repo:cloudfront -d /sdk/java/3/", "doc-deploy": "npm run doc-upload && npm run doc-cloudfront", - "doc-netlify": "npm run doc-prepare && cd doc && bash doc.sh build-netlify" + "doc-netlify": "npm run doc-prepare && kuzdoc repo:build -d / -v 3" + }, + "dependencies": { + "kuzdoc": "^1.2.2" } } From 996218685a3089cdee2a82b1464d405b9d04bd9c Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 11:47:19 +0100 Subject: [PATCH 012/134] [doc-ci] dead link check fix --- .travis.yml | 3 ++- features/sdk-features | 1 + sdk-cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 160000 features/sdk-features create mode 160000 sdk-cpp diff --git a/.travis.yml b/.travis.yml index 0977e11b..fd4818bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ jobs: before_script: - bash -c "npm run doc-prepare" - - npm run --prefix $TRAVIS_BUILD_DIR/doc/framework clone-repos + - npm run --prefix doc/framework repositories -- clone + script: - gem install typhoeus - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links diff --git a/features/sdk-features b/features/sdk-features new file mode 160000 index 00000000..882e0664 --- /dev/null +++ b/features/sdk-features @@ -0,0 +1 @@ +Subproject commit 882e066490b2ca6a6dd045fdcf65cc4d847b2785 diff --git a/sdk-cpp b/sdk-cpp new file mode 160000 index 00000000..d0750478 --- /dev/null +++ b/sdk-cpp @@ -0,0 +1 @@ +Subproject commit d07504781a8b3389da9a189be32e7388ae0a9f63 From b0347f04d94aac417959f895ae4a6f8d664208b6 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 11:57:50 +0100 Subject: [PATCH 013/134] [doc-ci] dead-link check --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fd4818bb..943899e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ jobs: before_script: - bash -c "npm run doc-prepare" - - npm run --prefix doc/framework repositories -- clone + - $(npm bin)/kuzdoc iterate-repos:install --repos_path doc/framework/.repos/ + - $(npm bin)/kuzdoc framework:link -d /sdk/java/3/ -v 3 script: - gem install typhoeus From fdc435770b14cc991ff88565b1b5580f19225563 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 12:15:27 +0100 Subject: [PATCH 014/134] [doc-ci] clean build commands --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 943899e6..993eded2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,18 +45,18 @@ jobs: script: - npm run doc-prepare - - npm run doc-build && cd - + - npm run doc-build deploy: provider: script script: - - npm run doc-upload && cd - + - npm run doc-upload skip_cleanup: true on: all_branches: true after_deploy: - - npm run doc-cloudfront && cd - + - npm run doc-cloudfront - stage: Deployment Doc Prod name: Deploy docs.kuzzle.io @@ -80,18 +80,18 @@ jobs: script: - npm run doc-prepare - - npm run doc-build && cd - + - npm run doc-build deploy: provider: script script: - - npm run doc-upload && cd - + - npm run doc-upload skip_cleanup: true on: all_branches: true after_deploy: - - npm run doc-cloudfront && cd - + - npm run doc-cloudfront # --------------------------------------- # Builds From 8abbaa0a5c2a0a47084d83dc4e75811ff5f26e4c Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 13:05:07 +0100 Subject: [PATCH 015/134] [doc-ci] install aws cli --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 993eded2..b0ac124a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,6 +41,7 @@ jobs: - python-pip install: + - pip install awscli --upgrade --user - npm ci script: @@ -76,6 +77,7 @@ jobs: - python-pip install: + - pip install awscli --upgrade --user - npm ci script: From 2982d96b7ab60cac6e0558c1e78920d94a679824 Mon Sep 17 00:00:00 2001 From: Luca Marchesini Date: Thu, 23 Jan 2020 14:06:32 +0100 Subject: [PATCH 016/134] [doc-ci] add AWS credentials --- .travis.yml | 50 +++++++++++++------------------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0ac124a..a208037d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ ---- -# ----------------- -# YAML Templates -# ----------------- - +env: + global: + - AWS_ACCESS_KEY_ID=AKIAIYAXFUAHXOWP2MJA + # AWS_SECRET_ACCESS_KEY + - secure: NElUP03Z1jbkOO20zYOo6WTdXrHa+b1UbMQJJX1rvG8wLHcEEid5m5VUa9UdSrBT4OxeVLKTVqEtEgFshz8Jjcc7JJ4pZBtGq4ty+S+nG6F9DJ+IMS2kD8h5qtoqh1TBLhov19s0mRNCG53No2+8VSk8STAeSG7x2hL2PAgJq3LCCy5lYVbmhnrCXObtd1a7Nq8XV7EHM+R9aITq3+jKa/NpdADoUv/WcoQAqjc8W3GhACRiNxRaGM58OF2WTojLM5fD3wwuicGkcsBkZkxho4cs0u36EEoxhZuy9U2/Emp7uhs9yCrhY0AwqYbSqvZ6jiwtJflvHHAsW2ZTgHWUekKippAyPIqF+QTeBvkg+q7tabOkfQLaZcREDzUBMI5AQiIW0Sv1fTPEs5jJv2+dE4bzi6BJmzFFGE0iHt4Nui7TLYMeAN17RYB5rJK50AGBA42Puzjr8CaV1FfnqLXOwiDXjGwvz7iHk4MMHFT/vvLcgDgHM16SM5QvhfbfX6Aj13VIG9lWUfKsalMSug8+zrXadtnZoz5XPskw1oA2iEUmgNzS33EVedgtxWDykadn3zhA+Ii+4C+Gge1dPG0sNXYiyI0/XKwlHBe6/Ar/DzKAf9Fo7/Z2haYGHC8XXmblagzVTxqX1FZVeiI3kyDBtduMSILU5ir5VA0dNtGdKVY= # ------------------------ # Jobs configuration # ------------------------ @@ -10,19 +10,18 @@ jobs: include: - stage: Tests name: Dead link check - if: type = pull_request OR type = push AND branch =~ /^master|[0-9]+-(dev|stable)$/ OR type = cron + if: + type = pull_request OR type = push AND branch =~ /^master|[0-9]+-(dev|stable)$/ + OR type = cron language: node_js node_js: 12 - before_script: - bash -c "npm run doc-prepare" - - $(npm bin)/kuzdoc iterate-repos:install --repos_path doc/framework/.repos/ - - $(npm bin)/kuzdoc framework:link -d /sdk/java/3/ -v 3 - + - "$(npm bin)/kuzdoc iterate-repos:install --repos_path doc/framework/.repos/" + - "$(npm bin)/kuzdoc framework:link -d /sdk/java/3/ -v 3" script: - gem install typhoeus - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links - - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io if: type = push AND branch =~ .*-dev @@ -33,21 +32,17 @@ jobs: - S3_BUCKET=docs-next.kuzzle.io - CLOUDFRONT_DISTRIBUTION_ID=E2ZCCEK9GRB49U - AWS_DEFAULT_REGION=us-west-2 - addons: apt: packages: - python - python-pip - install: - pip install awscli --upgrade --user - npm ci - script: - npm run doc-prepare - npm run doc-build - deploy: provider: script script: @@ -55,10 +50,8 @@ jobs: skip_cleanup: true on: all_branches: true - after_deploy: - npm run doc-cloudfront - - stage: Deployment Doc Prod name: Deploy docs.kuzzle.io if: type = push AND branch =~ /^master|[0-9]+-stable$/ @@ -69,21 +62,17 @@ jobs: - S3_BUCKET=docs.kuzzle.io - CLOUDFRONT_DISTRIBUTION_ID=E3D6RP0POLCJMM - AWS_DEFAULT_REGION=us-west-2 - addons: apt: packages: - python - python-pip - install: - pip install awscli --upgrade --user - npm ci - script: - npm run doc-prepare - npm run doc-build - deploy: provider: script script: @@ -91,13 +80,8 @@ jobs: skip_cleanup: true on: all_branches: true - after_deploy: - npm run doc-cloudfront - - # --------------------------------------- - # Builds - # --------------------------------------- - stage: Builds name: Build SDK Java language: java @@ -108,8 +92,8 @@ jobs: - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ cache: directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ + - "$HOME/.gradle/caches/" + - "$HOME/.gradle/wrapper/" install: - cd $TRAVIS_BUILD_DIR/ - gradle assemble @@ -117,22 +101,14 @@ jobs: - gradle assemble script: - gradle build - -# ------------------------ -# Stages configuration -# ------------------------ stages: - name: Unit Tests if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ - name: Builds if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ - -# --------------------------------------- -# Notifications -# --------------------------------------- notifications: slack: rooms: - - secure: "ACjz4TJEYBEzmwVOYrCNnr4+jC0FaX+qh150QacYGIgaQYL+U3xLEQmWNlZ3oxaPPMDAk42m+diHolqNwh6qsOWaPSWRlGfLKhHLSzRI98bhF7HQ+3eLMYmx7y7SKwRzyRjus0jgxp0Kc2mq0nhKqv+7rarQtIgWlC1PLrzZ35CUbUlqYSoeYAlXoyDB1eZgYsvjt+eC5yCvGePsfKbupWC2/hIVl+qZ+9AhVmOfiMv7daFW29Vu300aoY+0IqwX7jHGcmHn/7QCRsx0IBy/SL24TzfSV9SUSnbjK4fTrcrhjYDEZdH1lpvDtvr50GgkrTjy1wPVz8XIyCZ7LZolylkx+nR1MWyvum20QRFub2Qhz/+rS+OFiQZ8H01BPuklLUTSQhBksfpGBck3d2yNLiTqGEVWYTnZ9mkCnMQ3BzJXEF04KLHG7wYn2rk6wjPghVmFQH5GMsxM5v33CFgcNzp6lRJOX9CmjZosck6o9SA0WlazHH/CLWWKk1wrQ1ygDayW5m+N/o58UIxgW2LIUlp4tV1z/bRtO2yTd020yWchlKPVmf1A5OMfigJNMRsQGNZNadS7qA2M394OJw3/Hg+0EVF8gai/V8FRijmkxmhYyCIYMcjaGwx8JxfoMrRKcM76haBAhg0JQxsSVKzyXfONGzd5DXjcxSGZ2wuEdu0=" + - secure: ACjz4TJEYBEzmwVOYrCNnr4+jC0FaX+qh150QacYGIgaQYL+U3xLEQmWNlZ3oxaPPMDAk42m+diHolqNwh6qsOWaPSWRlGfLKhHLSzRI98bhF7HQ+3eLMYmx7y7SKwRzyRjus0jgxp0Kc2mq0nhKqv+7rarQtIgWlC1PLrzZ35CUbUlqYSoeYAlXoyDB1eZgYsvjt+eC5yCvGePsfKbupWC2/hIVl+qZ+9AhVmOfiMv7daFW29Vu300aoY+0IqwX7jHGcmHn/7QCRsx0IBy/SL24TzfSV9SUSnbjK4fTrcrhjYDEZdH1lpvDtvr50GgkrTjy1wPVz8XIyCZ7LZolylkx+nR1MWyvum20QRFub2Qhz/+rS+OFiQZ8H01BPuklLUTSQhBksfpGBck3d2yNLiTqGEVWYTnZ9mkCnMQ3BzJXEF04KLHG7wYn2rk6wjPghVmFQH5GMsxM5v33CFgcNzp6lRJOX9CmjZosck6o9SA0WlazHH/CLWWKk1wrQ1ygDayW5m+N/o58UIxgW2LIUlp4tV1z/bRtO2yTd020yWchlKPVmf1A5OMfigJNMRsQGNZNadS7qA2M394OJw3/Hg+0EVF8gai/V8FRijmkxmhYyCIYMcjaGwx8JxfoMrRKcM76haBAhg0JQxsSVKzyXfONGzd5DXjcxSGZ2wuEdu0= on_success: never on_failure: always From f0c61323ec8c5bc645fde256285674d9156e8849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Tue, 28 Jan 2020 15:45:59 +0100 Subject: [PATCH 017/134] Auth controller (#52) ## What does this PR do ? Add auth controller with unit tests and documentation. ### How should this be manually tested? ```sh ./gradlew test ``` ### Other changes - Added test snippet documentation - Reformat code with new prettier rules --- .ci/doc/config.yml | 18 ++ .ci/doc/docker-compose.yml | 56 ++++ .ci/doc/project/build.gradle | 31 ++ .../project/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58695 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .ci/doc/project/gradlew | 183 ++++++++++++ .ci/doc/project/gradlew.bat | 100 +++++++ .ci/doc/project/libs/.keep | 0 .ci/doc/project/settings.gradle | 1 + .ci/doc/project/src/main/java/.keep | 0 .ci/doc/templates/catch.tpl.java | 25 ++ .ci/doc/templates/default.tpl.java | 25 ++ .ci/doc/templates/empty.tpl.java | 1 + .ci/doc/templates/print-result.tpl.java | 27 ++ .ci/doc/templates/without-connect.tpl.java | 20 ++ .ci/doc/templates/without-ctor.tpl.java | 15 + .gitignore | 1 - .settings/org.eclipse.buildship.core.prefs | 2 + .settings/org.eclipse.jdt.core.prefs | 281 ++++++++++++++++++ .settings/org.eclipse.jdt.ui.prefs | 60 ++++ .../org.eclipse.ltk.core.refactoring.prefs | 2 + doc/3/.vuepress | 1 + doc/3/controllers/auth/check-token/index.md | 35 +++ .../check-token/snippets/check-token.java | 6 + .../check-token/snippets/check-token.test.yml | 7 + .../auth/create-my-credentials/index.md | 31 ++ .../snippets/create-my-credentials.java | 11 + .../snippets/create-my-credentials.test.yml | 7 + .../auth/credentials-exist/index.md | 29 ++ .../snippets/credentials-exist.java | 9 + .../snippets/credentials-exist.test.yml | 7 + .../auth/delete-my-credentials/index.md | 25 ++ .../snippets/delete-my-credentials.java | 6 + .../snippets/delete-my-credentials.test.yml | 7 + .../auth/get-current-user/index.md | 31 ++ .../snippets/get-current-user.java | 6 + .../snippets/get-current-user.test.yml | 7 + .../auth/get-my-credentials/index.md | 29 ++ .../snippets/get-my-credentials.java | 7 + .../snippets/get-my-credentials.test.yml | 8 + doc/3/controllers/auth/get-my-rights/index.md | 25 ++ .../get-my-rights/snippets/get-my-rights.java | 6 + .../snippets/get-my-rights.test.yml | 7 + .../controllers/auth/get-strategies/index.md | 25 ++ .../snippets/get-strategies.java | 6 + .../snippets/get-strategies.test.yml | 7 + doc/3/controllers/auth/index.md | 8 + doc/3/controllers/auth/login/index.md | 62 ++++ .../auth/login/snippets/login.java | 6 + .../auth/login/snippets/login.test.yml | 8 + doc/3/controllers/auth/logout/index.md | 25 ++ .../auth/logout/snippets/logout.java | 6 + .../auth/logout/snippets/logout.test.yml | 7 + doc/3/controllers/auth/refresh-token/index.md | 43 +++ .../refresh-token/snippets/refresh-token.java | 7 + .../snippets/refresh-token.test.yml | 7 + .../auth/update-my-credentials/index.md | 37 +++ .../snippets/update-my-credentials.java | 6 + .../snippets/update-my-credentials.test.yml | 7 + doc/3/controllers/auth/update-self/index.md | 35 +++ .../update-self/snippets/update-self.java | 11 + .../update-self/snippets/update-self.test.yml | 7 + .../auth/validate-my-credentials/index.md | 31 ++ .../snippets/validate-my-credentials.java | 6 + .../snippets/validate-my-credentials.test.yml | 7 + doc/3/controllers/index.md | 2 +- doc/3/core-classes/error-response/index.md | 7 + .../error-response/introduction/index.md | 20 ++ doc/3/core-classes/kuzzle-options/index.md | 67 +++++ doc/3/core-classes/kuzzle/connect/index.md | 22 ++ .../kuzzle/connect/snippets/connect.java | 1 + .../kuzzle/connect/snippets/connect.test.yml | 8 + .../core-classes/kuzzle/constructor/index.md | 52 ++++ .../constructor/snippets/constructor.java | 7 + .../constructor/snippets/constructor.test.yml | 8 + doc/3/core-classes/kuzzle/disconnect/index.md | 22 ++ .../disconnect/snippets/disconnect.java | 1 + .../disconnect/snippets/disconnect.test.yml | 8 + doc/3/core-classes/kuzzle/index.md | 7 + doc/3/core-classes/kuzzle/query/index.md | 51 ++++ .../kuzzle/query/snippets/query.java | 13 + .../kuzzle/query/snippets/query.test.yml | 11 + doc/3/core-classes/response/index.md | 7 + .../response/introduction/index.md | 30 ++ .../illegal-argument-exception/index.md | 11 + doc/3/index.md | 7 + doc/3/protocols/websocket-options/index.md | 56 ++++ .../protocols/websocket/constructor/index.md | 72 +++++ .../constructor/snippets/constructor.java | 7 + .../constructor/snippets/constructor.test.yml | 8 + doc/3/protocols/websocket/index.md | 7 + features/sdk-features | 1 - sdk-cpp | 1 - .../sdk/API/Controllers/AuthController.java | 276 +++++++++++++++++ .../sdk/API/Controllers/BaseController.java | 12 + .../Json/ConcurrentHashMapTypeAdapter.java | 13 +- .../sdk/CoreClasses/Json/JsonSerializer.java | 9 +- .../sdk/CoreClasses/Maps/KuzzleMap.java | 103 ++++--- .../io/kuzzle/sdk/CoreClasses/Maps/Null.java | 4 + .../sdk/CoreClasses/Responses/Response.java | 4 +- src/main/java/io/kuzzle/sdk/Events/Event.java | 18 ++ .../io/kuzzle/sdk/Events/EventListener.java | 83 +----- .../io/kuzzle/sdk/Events/EventManager.java | 62 ++++ .../sdk/Exceptions/ApiErrorException.java | 5 + .../Exceptions/ConnectionLostException.java | 5 + .../sdk/Exceptions/InternalException.java | 5 + .../sdk/Exceptions/KuzzleException.java | 10 +- .../sdk/Exceptions/KuzzleExceptionCode.java | 10 +- .../sdk/Exceptions/NotConnectedException.java | 5 + src/main/java/io/kuzzle/sdk/Kuzzle.java | 163 ++++------ .../io/kuzzle/sdk/Options/KuzzleOptions.java | 59 ++-- .../Options/Protocol/WebSocketOptions.java | 10 +- .../kuzzle/sdk/Protocol/AbstractProtocol.java | 59 +--- .../io/kuzzle/sdk/Protocol/WebSocket.java | 50 ++-- .../test/CoreClasses/TaskTest/TaskTests.java | 1 - .../test/EventsTest/EventListenerTests.java | 142 --------- .../test/EventsTest/EventManagerTests.java | 84 ++++++ .../test/EventsTest/MockedEventManager.java | 19 ++ .../EventsTest/TestableEventListener.java | 23 -- src/test/java/io/kuzzle/test/KuzzleTests.java | 30 +- .../test/ProtocolTest/TestableWebSocket.java | 3 +- .../test/ProtocolTest/WebSocketTests.java | 2 +- .../java/io/kuzzle/test/TestableKuzzle.java | 16 - 123 files changed, 2774 insertions(+), 550 deletions(-) create mode 100644 .ci/doc/config.yml create mode 100644 .ci/doc/docker-compose.yml create mode 100644 .ci/doc/project/build.gradle create mode 100644 .ci/doc/project/gradle/wrapper/gradle-wrapper.jar create mode 100644 .ci/doc/project/gradle/wrapper/gradle-wrapper.properties create mode 100755 .ci/doc/project/gradlew create mode 100644 .ci/doc/project/gradlew.bat create mode 100644 .ci/doc/project/libs/.keep create mode 100644 .ci/doc/project/settings.gradle create mode 100644 .ci/doc/project/src/main/java/.keep create mode 100644 .ci/doc/templates/catch.tpl.java create mode 100644 .ci/doc/templates/default.tpl.java create mode 100644 .ci/doc/templates/empty.tpl.java create mode 100644 .ci/doc/templates/print-result.tpl.java create mode 100644 .ci/doc/templates/without-connect.tpl.java create mode 100644 .ci/doc/templates/without-ctor.tpl.java create mode 100644 .settings/org.eclipse.buildship.core.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.jdt.ui.prefs create mode 100644 .settings/org.eclipse.ltk.core.refactoring.prefs create mode 120000 doc/3/.vuepress create mode 100644 doc/3/controllers/auth/check-token/index.md create mode 100644 doc/3/controllers/auth/check-token/snippets/check-token.java create mode 100644 doc/3/controllers/auth/check-token/snippets/check-token.test.yml create mode 100644 doc/3/controllers/auth/create-my-credentials/index.md create mode 100644 doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.java create mode 100644 doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.test.yml create mode 100644 doc/3/controllers/auth/credentials-exist/index.md create mode 100644 doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.java create mode 100644 doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.test.yml create mode 100644 doc/3/controllers/auth/delete-my-credentials/index.md create mode 100644 doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.java create mode 100644 doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.test.yml create mode 100644 doc/3/controllers/auth/get-current-user/index.md create mode 100644 doc/3/controllers/auth/get-current-user/snippets/get-current-user.java create mode 100644 doc/3/controllers/auth/get-current-user/snippets/get-current-user.test.yml create mode 100644 doc/3/controllers/auth/get-my-credentials/index.md create mode 100644 doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.java create mode 100644 doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.test.yml create mode 100644 doc/3/controllers/auth/get-my-rights/index.md create mode 100644 doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.java create mode 100644 doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.test.yml create mode 100644 doc/3/controllers/auth/get-strategies/index.md create mode 100644 doc/3/controllers/auth/get-strategies/snippets/get-strategies.java create mode 100644 doc/3/controllers/auth/get-strategies/snippets/get-strategies.test.yml create mode 100644 doc/3/controllers/auth/index.md create mode 100644 doc/3/controllers/auth/login/index.md create mode 100644 doc/3/controllers/auth/login/snippets/login.java create mode 100644 doc/3/controllers/auth/login/snippets/login.test.yml create mode 100644 doc/3/controllers/auth/logout/index.md create mode 100644 doc/3/controllers/auth/logout/snippets/logout.java create mode 100644 doc/3/controllers/auth/logout/snippets/logout.test.yml create mode 100644 doc/3/controllers/auth/refresh-token/index.md create mode 100644 doc/3/controllers/auth/refresh-token/snippets/refresh-token.java create mode 100644 doc/3/controllers/auth/refresh-token/snippets/refresh-token.test.yml create mode 100644 doc/3/controllers/auth/update-my-credentials/index.md create mode 100644 doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.java create mode 100644 doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.test.yml create mode 100644 doc/3/controllers/auth/update-self/index.md create mode 100644 doc/3/controllers/auth/update-self/snippets/update-self.java create mode 100644 doc/3/controllers/auth/update-self/snippets/update-self.test.yml create mode 100644 doc/3/controllers/auth/validate-my-credentials/index.md create mode 100644 doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.java create mode 100644 doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.test.yml create mode 100644 doc/3/core-classes/error-response/index.md create mode 100644 doc/3/core-classes/error-response/introduction/index.md create mode 100644 doc/3/core-classes/kuzzle-options/index.md create mode 100644 doc/3/core-classes/kuzzle/connect/index.md create mode 100644 doc/3/core-classes/kuzzle/connect/snippets/connect.java create mode 100644 doc/3/core-classes/kuzzle/connect/snippets/connect.test.yml create mode 100644 doc/3/core-classes/kuzzle/constructor/index.md create mode 100644 doc/3/core-classes/kuzzle/constructor/snippets/constructor.java create mode 100644 doc/3/core-classes/kuzzle/constructor/snippets/constructor.test.yml create mode 100644 doc/3/core-classes/kuzzle/disconnect/index.md create mode 100644 doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.java create mode 100644 doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.test.yml create mode 100644 doc/3/core-classes/kuzzle/index.md create mode 100644 doc/3/core-classes/kuzzle/query/index.md create mode 100644 doc/3/core-classes/kuzzle/query/snippets/query.java create mode 100644 doc/3/core-classes/kuzzle/query/snippets/query.test.yml create mode 100644 doc/3/core-classes/response/index.md create mode 100644 doc/3/core-classes/response/introduction/index.md create mode 100644 doc/3/exceptions/illegal-argument-exception/index.md create mode 100644 doc/3/index.md create mode 100644 doc/3/protocols/websocket-options/index.md create mode 100644 doc/3/protocols/websocket/constructor/index.md create mode 100644 doc/3/protocols/websocket/constructor/snippets/constructor.java create mode 100644 doc/3/protocols/websocket/constructor/snippets/constructor.test.yml create mode 100644 doc/3/protocols/websocket/index.md delete mode 160000 features/sdk-features delete mode 160000 sdk-cpp create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/BaseController.java create mode 100644 src/main/java/io/kuzzle/sdk/Events/Event.java create mode 100644 src/main/java/io/kuzzle/sdk/Events/EventManager.java delete mode 100644 src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java create mode 100644 src/test/java/io/kuzzle/test/EventsTest/EventManagerTests.java create mode 100644 src/test/java/io/kuzzle/test/EventsTest/MockedEventManager.java delete mode 100644 src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java diff --git a/.ci/doc/config.yml b/.ci/doc/config.yml new file mode 100644 index 00000000..9bd2fe99 --- /dev/null +++ b/.ci/doc/config.yml @@ -0,0 +1,18 @@ +--- + +snippets: + mount: /mnt + path: 'doc/**/snippets/*.test.yml' + templates: /mnt/.ci/doc/templates + +runners: + default: java + + java: + service: doc-runner-java + path: /var/snippets/java + build: + cmd: cd /mnt && ./gradlew jar + run: + before: timeout 600 bash -c 'until stat /tmp/runner_is_ready && curl -f -s -o /dev/null http://kuzzle:7512/_now; do sleep 1; done' + cmd: cp /mnt/build/libs/sdk-java-[0-9+].[0-9+].[0-9+].jar /mnt/.ci/doc/project/libs/ && cp {{ snippet.source }} /mnt/.ci/doc/project/src/main/java/SnippetTest.java && cd /mnt/.ci/doc/project/ && ./gradlew build && java -classpath 'libs/sdk-java-3.0.0.jar:' -jar build/libs/project-1.jar diff --git a/.ci/doc/docker-compose.yml b/.ci/doc/docker-compose.yml new file mode 100644 index 00000000..5a2e9223 --- /dev/null +++ b/.ci/doc/docker-compose.yml @@ -0,0 +1,56 @@ +version: '3' + +services: + kuzzle: + image: kuzzleio/kuzzle:2 + ports: + - "7512:7512" + cap_add: + - SYS_PTRACE + depends_on: + - redis + - elasticsearch + environment: + - kuzzle_services__storageEngine__client__node=http://elasticsearch:9200 + - kuzzle_services__internalCache__node__host=redis + - kuzzle_services__memoryStorage__node__host=redis + - kuzzle_services__storageEngine__commonMapping__dynamic=true + - NODE_ENV=production + + redis: + image: redis:5 + + elasticsearch: + image: kuzzleio/elasticsearch:7 + ulimits: + nofile: 65536 + + doc-tests: + image: kuzzleio/snippets-tests + privileged: true + ports: + - '9229:9229' + depends_on: + - kuzzle + - doc-runner-java + volumes: + - ../..:/mnt + - /var/run/docker.sock:/var/run/docker.sock + - snippets:/var/snippets + environment: + - CONFIG_FILE=/mnt/.ci/doc/config.yml + + doc-runner-java: + image: adoptopenjdk/openjdk8 + command: > + bash -c ' + mkdir -p /var/snippets/java; + touch /tmp/runner_is_ready; + tail -f /dev/null + ' + volumes: + - ../..:/mnt + - snippets:/var/snippets + +volumes: + snippets: diff --git a/.ci/doc/project/build.gradle b/.ci/doc/project/build.gradle new file mode 100644 index 00000000..99b9cd83 --- /dev/null +++ b/.ci/doc/project/build.gradle @@ -0,0 +1,31 @@ +plugins { + id 'java' +} + +group 'test.example.java' +version '1' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.12' + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.neovisionaries:nv-websocket-client:2.9' + compile 'com.google.code.gson:gson:2.8.5' +} + +jar { + manifest { + attributes( + 'Class-Path': configurations.compile.collect { it.getName() }.join(' '), + 'Main-Class': 'SnippetTest' + ) + } + from { + configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } + } +} \ No newline at end of file diff --git a/.ci/doc/project/gradle/wrapper/gradle-wrapper.jar b/.ci/doc/project/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f3d88b1c2faf2fc91d853cd5d4242b5547257070 GIT binary patch literal 58695 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 literal 0 HcmV?d00001 diff --git a/.ci/doc/project/gradle/wrapper/gradle-wrapper.properties b/.ci/doc/project/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..718c0f3d --- /dev/null +++ b/.ci/doc/project/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jan 17 11:19:10 CET 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip diff --git a/.ci/doc/project/gradlew b/.ci/doc/project/gradlew new file mode 100755 index 00000000..2fe81a7d --- /dev/null +++ b/.ci/doc/project/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/.ci/doc/project/gradlew.bat b/.ci/doc/project/gradlew.bat new file mode 100644 index 00000000..24467a14 --- /dev/null +++ b/.ci/doc/project/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/.ci/doc/project/libs/.keep b/.ci/doc/project/libs/.keep new file mode 100644 index 00000000..e69de29b diff --git a/.ci/doc/project/settings.gradle b/.ci/doc/project/settings.gradle new file mode 100644 index 00000000..682509ee --- /dev/null +++ b/.ci/doc/project/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'project' diff --git a/.ci/doc/project/src/main/java/.keep b/.ci/doc/project/src/main/java/.keep new file mode 100644 index 00000000..e69de29b diff --git a/.ci/doc/templates/catch.tpl.java b/.ci/doc/templates/catch.tpl.java new file mode 100644 index 00000000..bd56af5f --- /dev/null +++ b/.ci/doc/templates/catch.tpl.java @@ -0,0 +1,25 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; +import java.util.concurrent.ConcurrentHashMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + kuzzle.connect(); + [snippet-code] + System.out.println("Error"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java new file mode 100644 index 00000000..bb86e2d1 --- /dev/null +++ b/.ci/doc/templates/default.tpl.java @@ -0,0 +1,25 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; +import java.util.concurrent.ConcurrentHashMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + kuzzle.connect(); + [snippet-code] + System.out.println("Success"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/.ci/doc/templates/empty.tpl.java b/.ci/doc/templates/empty.tpl.java new file mode 100644 index 00000000..f6c250ed --- /dev/null +++ b/.ci/doc/templates/empty.tpl.java @@ -0,0 +1 @@ +[snippet-code] \ No newline at end of file diff --git a/.ci/doc/templates/print-result.tpl.java b/.ci/doc/templates/print-result.tpl.java new file mode 100644 index 00000000..1e7b1e39 --- /dev/null +++ b/.ci/doc/templates/print-result.tpl.java @@ -0,0 +1,27 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.ArrayList; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + kuzzle.connect(); + [snippet-code] + System.out.println(result.toString()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/.ci/doc/templates/without-connect.tpl.java b/.ci/doc/templates/without-connect.tpl.java new file mode 100644 index 00000000..06da4d92 --- /dev/null +++ b/.ci/doc/templates/without-connect.tpl.java @@ -0,0 +1,20 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + [snippet-code] + System.out.println("Success"); + } catch (Exception e) { + System.err.println(e.getMessage()); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} diff --git a/.ci/doc/templates/without-ctor.tpl.java b/.ci/doc/templates/without-ctor.tpl.java new file mode 100644 index 00000000..0050e727 --- /dev/null +++ b/.ci/doc/templates/without-ctor.tpl.java @@ -0,0 +1,15 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; + +public class SnippetTest { + public static void main(String[] argv) { + try { + [snippet-code] + System.out.println("Success"); + } catch (Exception e) { + System.err.println((e.getMessage())); + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 151f1041..ea7a48bf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ bin bin .classpath .project -.settings doc/framework node_modules diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..e8895216 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..cd6e3b3f --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,281 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=48 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=48 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=48 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000..9de95cfa --- /dev/null +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,60 @@ +cleanup.add_default_serial_version_id=true +cleanup.add_generated_serial_version_id=false +cleanup.add_missing_annotations=true +cleanup.add_missing_deprecated_annotations=true +cleanup.add_missing_methods=false +cleanup.add_missing_nls_tags=false +cleanup.add_missing_override_annotations=true +cleanup.add_missing_override_annotations_interface_methods=true +cleanup.add_serial_version_id=false +cleanup.always_use_blocks=true +cleanup.always_use_parentheses_in_expressions=false +cleanup.always_use_this_for_non_static_field_access=false +cleanup.always_use_this_for_non_static_method_access=false +cleanup.convert_to_enhanced_for_loop=false +cleanup.correct_indentation=true +cleanup.format_source_code=true +cleanup.format_source_code_changes_only=false +cleanup.make_local_variable_final=true +cleanup.make_parameters_final=false +cleanup.make_private_fields_final=true +cleanup.make_type_abstract_if_missing_method=false +cleanup.make_variable_declarations_final=false +cleanup.never_use_blocks=false +cleanup.never_use_parentheses_in_expressions=true +cleanup.organize_imports=true +cleanup.qualify_static_field_accesses_with_declaring_class=false +cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +cleanup.qualify_static_member_accesses_with_declaring_class=true +cleanup.qualify_static_method_accesses_with_declaring_class=false +cleanup.remove_private_constructors=true +cleanup.remove_trailing_whitespaces=true +cleanup.remove_trailing_whitespaces_all=true +cleanup.remove_trailing_whitespaces_ignore_empty=false +cleanup.remove_unnecessary_casts=true +cleanup.remove_unnecessary_nls_tags=true +cleanup.remove_unused_imports=true +cleanup.remove_unused_local_variables=false +cleanup.remove_unused_private_fields=true +cleanup.remove_unused_private_members=false +cleanup.remove_unused_private_methods=true +cleanup.remove_unused_private_types=true +cleanup.sort_members=true +cleanup.sort_members_all=true +cleanup.use_blocks=true +cleanup.use_blocks_only_for_return_and_throw=false +cleanup.use_parentheses_in_expressions=false +cleanup.use_this_for_non_static_field_access=false +cleanup.use_this_for_non_static_field_access_only_if_necessary=true +cleanup.use_this_for_non_static_method_access=false +cleanup.use_this_for_non_static_method_access_only_if_necessary=true +cleanup_profile=_Eclipse [built-in] custom +cleanup_settings_version=2 +eclipse.preferences.version=1 +formatter_profile=_Eclipse [built-in] custom +formatter_settings_version=12 +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com; +org.eclipse.jdt.ui.ondemandthreshold=99 +org.eclipse.jdt.ui.staticondemandthreshold=99 diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 00000000..b196c64a --- /dev/null +++ b/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/doc/3/.vuepress b/doc/3/.vuepress new file mode 120000 index 00000000..c7af454d --- /dev/null +++ b/doc/3/.vuepress @@ -0,0 +1 @@ +../framework/src/.vuepress \ No newline at end of file diff --git a/doc/3/controllers/auth/check-token/index.md b/doc/3/controllers/auth/check-token/index.md new file mode 100644 index 00000000..12b24375 --- /dev/null +++ b/doc/3/controllers/auth/check-token/index.md @@ -0,0 +1,35 @@ +--- +code: true +type: page +title: CheckToken +description: Checks an authentication Token's validity. +--- + +# CheckToken + +Checks an authentication token's validity. + +## Arguments + +```java +public CompletableFuture> checkToken(final String token) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|----------|-------------------|-------------| +| `token` |

String
| Authentication token | + +## Return + +A ConcurrentHashMap which has the following properties: + +| Property | Type | Description | +|--------------|-------------------|----------------------------------| +| `valid` |
boolean
| Token validity | +| `state` |
String
| Explain why the token is invalid | +| `expires_at` |
int
| Token expiration timestamp | + +## Usage + +<<< ./snippets/check-token.java \ No newline at end of file diff --git a/doc/3/controllers/auth/check-token/snippets/check-token.java b/doc/3/controllers/auth/check-token/snippets/check-token.java new file mode 100644 index 00000000..3ec31bb2 --- /dev/null +++ b/doc/3/controllers/auth/check-token/snippets/check-token.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +ConcurrentHashMap response = kuzzle.getAuthController().login("local", credentials).get(); +ConcurrentHashMap responseToken = kuzzle.getAuthController().checkToken(response.get("jwt").toString()).get(); diff --git a/doc/3/controllers/auth/check-token/snippets/check-token.test.yml b/doc/3/controllers/auth/check-token/snippets/check-token.test.yml new file mode 100644 index 00000000..7ed24530 --- /dev/null +++ b/doc/3/controllers/auth/check-token/snippets/check-token.test.yml @@ -0,0 +1,7 @@ +name: Auth#CheckToken +description: Checks an authentication token's validity. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/auth/create-my-credentials/index.md b/doc/3/controllers/auth/create-my-credentials/index.md new file mode 100644 index 00000000..0e11aaec --- /dev/null +++ b/doc/3/controllers/auth/create-my-credentials/index.md @@ -0,0 +1,31 @@ +--- +code: true +type: page +title: CreateMyCredentials +description: Create the current user's credentials for the specified strategy. +--- + +# CreateMyCredentials + +Creates the current user's credentials for the specified strategy. + +## Arguments + +```java +public CompletableFuture> createMyCredentials(final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|---------------|--------------------|--------------------------------------| +| `strategy` |
String
| Strategy to use | +| `credentials` |
ConcurrentHashMap
| ConcurrentHashMap representing the credentials | + +## Return + +A ConcurrentHashMap representing the new credentials. + +## Usage + +<<< ./snippets/create-my-credentials.java diff --git a/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.java b/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.java new file mode 100644 index 00000000..04c80a31 --- /dev/null +++ b/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.java @@ -0,0 +1,11 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +ConcurrentHashMap newCredentials = new ConcurrentHashMap<>(); +newCredentials.put("username", "foo2"); +newCredentials.put("password", "bar2"); + +ConcurrentHashMap response = + kuzzle.getAuthController().login("local", credentials).get(); +kuzzle.getAuthController().createMyCredentials("other", newCredentials).get(); diff --git a/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.test.yml b/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.test.yml new file mode 100644 index 00000000..5fddc144 --- /dev/null +++ b/doc/3/controllers/auth/create-my-credentials/snippets/create-my-credentials.test.yml @@ -0,0 +1,7 @@ +name: Auth#CreateMyCredentials +description: Creates the current user's credentials for the specified strategy. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: catch +expected: io.kuzzle.sdk.Exceptions.ApiErrorException:\ Unknown\ authentication\ strategy\ "other" diff --git a/doc/3/controllers/auth/credentials-exist/index.md b/doc/3/controllers/auth/credentials-exist/index.md new file mode 100644 index 00000000..9d1e406a --- /dev/null +++ b/doc/3/controllers/auth/credentials-exist/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: CredentialsExist +description: Checks that the current user has credentials for the specified strategy. +--- + +# CredentialsExist + +Checks that the current user has credentials for the specified strategy. + +## Arguments + +```java +public CompletableFuture credentialsExist(final String strategy) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|------------|-------------------|-----------------| +| `strategy` |
String
| Strategy to use | + +## Return + +A boolean indicating if credentials exist for the strategy. + +## Usage + +<<< ./snippets/credentials-exist.java diff --git a/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.java b/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.java new file mode 100644 index 00000000..2b30c7a6 --- /dev/null +++ b/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.java @@ -0,0 +1,9 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +Boolean exists = kuzzle.getAuthController().credentialsExist("local").get(); +if (exists) { + System.out.println("Credentials exists for local strategy"); +} diff --git a/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.test.yml b/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.test.yml new file mode 100644 index 00000000..2f519b43 --- /dev/null +++ b/doc/3/controllers/auth/credentials-exist/snippets/credentials-exist.test.yml @@ -0,0 +1,7 @@ +name: Auth#CredentialsExistAsync +description: Checks that the current user has credentials for the specified strategy. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: default +expected: Credentials\ exists\ for\ local\ strategy diff --git a/doc/3/controllers/auth/delete-my-credentials/index.md b/doc/3/controllers/auth/delete-my-credentials/index.md new file mode 100644 index 00000000..a19ef6df --- /dev/null +++ b/doc/3/controllers/auth/delete-my-credentials/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: DeleteMyCredentials +description: Deletes the current user's credentials for the specified strategy. +--- + +# DeleteMyCredentials + +Deletes the current user's credentials for the specified strategy. If the credentials that generated the current authentication token are removed, the user will remain logged in until they log out or until their session expires. After that they will no longer be able to log in with the deleted credentials. + +## Arguments + +```java +public CompletableFuture deleteMyCredentials(final String strategy) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|------------|-------------------|-----------------| +| `strategy` |
String
| Strategy to use | + +## Usage + +<<< ./snippets/delete-my-credentials.java diff --git a/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.java b/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.java new file mode 100644 index 00000000..debdfa83 --- /dev/null +++ b/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +ConcurrentHashMap response = kuzzle.getAuthController().login("local", credentials).get(); +kuzzle.getAuthController().deleteMyCredentials("local").get(); diff --git a/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.test.yml b/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.test.yml new file mode 100644 index 00000000..dcc8e528 --- /dev/null +++ b/doc/3/controllers/auth/delete-my-credentials/snippets/delete-my-credentials.test.yml @@ -0,0 +1,7 @@ +name: Auth#DeleteMyCredentialsAsync +description: Deletes the current user's credentials for the specified. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/auth/get-current-user/index.md b/doc/3/controllers/auth/get-current-user/index.md new file mode 100644 index 00000000..46a75ddf --- /dev/null +++ b/doc/3/controllers/auth/get-current-user/index.md @@ -0,0 +1,31 @@ +--- +code: true +type: page +title: GetCurrentUser +description: Returns the profile object for the user linked to the `JSON Web Token`. +--- + +# GetCurrentUserAsync + +Returns informations about the user currently loggued with the SDK instance. + +## Arguments + +```java +public CompletableFuture> getCurrentUser() + throws NotConnectedException, InternalException +``` + +## Return + +A ConcurrentHashMap representing the User. + +| Property | Type | Description | +|--------------|--------------------|---------------------------------------------------| +| `_id` |
String
| Representing the current user `kuid` | +| `strategies` |
Array
| Available authentication strategies for that user | +| `_source` |
ConcurrentHashMap
| User information | + +## Usage + +<<< ./snippets/get-current-user.java diff --git a/doc/3/controllers/auth/get-current-user/snippets/get-current-user.java b/doc/3/controllers/auth/get-current-user/snippets/get-current-user.java new file mode 100644 index 00000000..0ee6ec1e --- /dev/null +++ b/doc/3/controllers/auth/get-current-user/snippets/get-current-user.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ConcurrentHashMap result = kuzzle.getAuthController().getCurrentUser().get(); diff --git a/doc/3/controllers/auth/get-current-user/snippets/get-current-user.test.yml b/doc/3/controllers/auth/get-current-user/snippets/get-current-user.test.yml new file mode 100644 index 00000000..047325ac --- /dev/null +++ b/doc/3/controllers/auth/get-current-user/snippets/get-current-user.test.yml @@ -0,0 +1,7 @@ +name: Auth#GetCurrentUser +description: Returns the profile object for the user linked to the `JSON Web Token`. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: ^{strategies=\[local\],\ _source={profileIds=\[default\],\ _kuzzle_info={.*}},\ _id=foo}$ diff --git a/doc/3/controllers/auth/get-my-credentials/index.md b/doc/3/controllers/auth/get-my-credentials/index.md new file mode 100644 index 00000000..12dcda4b --- /dev/null +++ b/doc/3/controllers/auth/get-my-credentials/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: GetMyCredentials +description: Returns the current user's credential information for the specified strategy. +--- + +# GetMyCredentials + +Returns the current user's credential information for the specified strategy. The data returned will depend on the specified strategy. The result can be empty. + +## Arguments + +```java +public CompletableFuture> getMyCredentials() + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|------------|-------------------|-----------------| +| `strategy` |
String
| Strategy to use | + +## Return + +Returns a ConcurrentHashMap representing the credentials for the provided authentication strategy. + +## Usage + +<<< ./snippets/get-my-credentials.java diff --git a/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.java b/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.java new file mode 100644 index 00000000..916cc641 --- /dev/null +++ b/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.java @@ -0,0 +1,7 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ConcurrentHashMap result = + kuzzle.getAuthController().getMyCredentials("local").get(); diff --git a/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.test.yml b/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.test.yml new file mode 100644 index 00000000..acc13e04 --- /dev/null +++ b/doc/3/controllers/auth/get-my-credentials/snippets/get-my-credentials.test.yml @@ -0,0 +1,8 @@ +name: Auth#GetMyCredentials +description: Returns the current user's credential information for the specified strategy. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: + - {kuid=foo,\ username=foo} diff --git a/doc/3/controllers/auth/get-my-rights/index.md b/doc/3/controllers/auth/get-my-rights/index.md new file mode 100644 index 00000000..50e42c72 --- /dev/null +++ b/doc/3/controllers/auth/get-my-rights/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: GetMyRights +description: Returns the rights for the user linked to the `JSON Web Token`. +--- + +# GetMyRights + +Returns the rights for the currently logged in user within the SDK instance. + +## Arguments + +```java +public CompletableFuture> getMyRights() + throws NotConnectedException, InternalException +``` + +## Return + +An ArrayList object. + +## Usage + +<<< ./snippets/get-my-rights.java diff --git a/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.java b/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.java new file mode 100644 index 00000000..d93e5473 --- /dev/null +++ b/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ArrayList result = kuzzle.getAuthController().getMyRights().get(); diff --git a/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.test.yml b/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.test.yml new file mode 100644 index 00000000..5873e365 --- /dev/null +++ b/doc/3/controllers/auth/get-my-rights/snippets/get-my-rights.test.yml @@ -0,0 +1,7 @@ +name: Auth#GetMyRights +description: Returns the rights for the user linked to the `JSON Web Token`. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: [{controller=*,\ action=*,\ index=*,\ collection=*,\ value=allowed}] diff --git a/doc/3/controllers/auth/get-strategies/index.md b/doc/3/controllers/auth/get-strategies/index.md new file mode 100644 index 00000000..7892d289 --- /dev/null +++ b/doc/3/controllers/auth/get-strategies/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: GetStrategies +description: Get all authentication strategies registered in Kuzzle. +--- + +# GetStrategies + +Gets all authentication strategies registered in Kuzzle. + +## Arguments + +```java +public CompletableFuture> getStrategies() + throws NotConnectedException, InternalException +``` + +## Return + +An ArrayList representing the available authentication strategies. + +## Usage + +<<< ./snippets/get-strategies.java diff --git a/doc/3/controllers/auth/get-strategies/snippets/get-strategies.java b/doc/3/controllers/auth/get-strategies/snippets/get-strategies.java new file mode 100644 index 00000000..0f19782b --- /dev/null +++ b/doc/3/controllers/auth/get-strategies/snippets/get-strategies.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ArrayList result = kuzzle.getAuthController().getStrategies().get(); diff --git a/doc/3/controllers/auth/get-strategies/snippets/get-strategies.test.yml b/doc/3/controllers/auth/get-strategies/snippets/get-strategies.test.yml new file mode 100644 index 00000000..e704fb36 --- /dev/null +++ b/doc/3/controllers/auth/get-strategies/snippets/get-strategies.test.yml @@ -0,0 +1,7 @@ +name: Auth#GetStrategies +description: Returns the rights for the user linked to the `JSON Web Token`. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: [local] diff --git a/doc/3/controllers/auth/index.md b/doc/3/controllers/auth/index.md new file mode 100644 index 00000000..6aef4117 --- /dev/null +++ b/doc/3/controllers/auth/index.md @@ -0,0 +1,8 @@ +--- +code: true +type: branch +title: Auth +description: Auth Controller +--- + +# Auth Controller \ No newline at end of file diff --git a/doc/3/controllers/auth/login/index.md b/doc/3/controllers/auth/login/index.md new file mode 100644 index 00000000..e310beed --- /dev/null +++ b/doc/3/controllers/auth/login/index.md @@ -0,0 +1,62 @@ +--- +code: true +type: page +title: Login +description: Authenticates a user. +--- + +# Login + +Authenticates a user. + +If this action is successful, all further requests emitted by this SDK instance will be in the name of the authenticated user, until either the authenticated token expires, the [logout](/sdk/java/3/controllers/auth/logout) action is called, or the authentication token property is manually unset. + +## Arguments + +```java +CompletableFuture> login( + final String strategy, + final ConcurrentHashMap credentials, + final String expiresIn) + throws NotConnectedException, InternalException +``` + +
+ +| Argument | Type | Description | +|---------------|----------------------|--------------------------------------| +| `strategy` |
String
| Strategy to use | +| `credentials` |
ConcurrentHashMap
| Hashmap representing the credentials | +| `expiresIn` |
String
| Token duration | + +#### strategy + +The name of the authentication [strategy](/core/2/guides/kuzzle-depth/authentication/#authentication) used to log the user in. + +Depending on the chosen authentication `strategy`, additional [credential arguments](/core/2/guides/kuzzle-depth/authentication/#authentication) may be required. +The API request example on this page provides the necessary arguments for the [`local` authentication plugin](https://github.com/kuzzleio/kuzzle-plugin-auth-passport-local). + +Check the appropriate [authentication plugin](/core/2/plugins/guides/strategies/overview) documentation to get the list of additional arguments to provide. + + +### expiresIn + +The default value for the `expiresIn` option is defined at server level, in Kuzzle's [configuration file](/core/2/guides/essentials/configuration). + + +## Return + +Returns a Hashmap with the following properties: + +| Property | Type | Description | +|-------------|-------------------|------------------------------------------------------------------------------------------| +| `_id` |
String
| User's `kuid` | +| `jwt` |
String
| Encrypted authentication token, that must then be sent in the requests headers or in the query | +| `expiresAt` |
int
| Token expiration date, in Epoch-millis (UTC) | +| `ttl` |
int
| Token time to live, in milliseconds | + +Once `auth:login` has been called, the returned authentication token is stored by the SDK and used for all the subsequent API call, ensuring they are properly authenticated. + +## Usage + +<<< ./snippets/login.java diff --git a/doc/3/controllers/auth/login/snippets/login.java b/doc/3/controllers/auth/login/snippets/login.java new file mode 100644 index 00000000..7db19af2 --- /dev/null +++ b/doc/3/controllers/auth/login/snippets/login.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "bar"); + +ConcurrentHashMap result = + kuzzle.getAuthController().login("local", credentials).get(); diff --git a/doc/3/controllers/auth/login/snippets/login.test.yml b/doc/3/controllers/auth/login/snippets/login.test.yml new file mode 100644 index 00000000..7e926dcf --- /dev/null +++ b/doc/3/controllers/auth/login/snippets/login.test.yml @@ -0,0 +1,8 @@ +--- +name: Auth#Login +description: Authenticates a user. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: ^{jwt=.*,\ _id=foo,\ ttl=3600000,\ expiresAt=[0-9]+}$ diff --git a/doc/3/controllers/auth/logout/index.md b/doc/3/controllers/auth/logout/index.md new file mode 100644 index 00000000..7d1410d6 --- /dev/null +++ b/doc/3/controllers/auth/logout/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: Logout +description: Revokes the user's token & unsubscribe them from registered rooms. +--- + +# Logout + +Revokes the user's token & unsubscribes them from registered rooms. + +## Arguments + +```java +public CompletableFuture logout() + throws NotConnectedException, InternalException +``` + +## Return + +A [Response](/sdk/java/3/core-classes/response) object. + +## Usage + +<<< ./snippets/logout.java diff --git a/doc/3/controllers/auth/logout/snippets/logout.java b/doc/3/controllers/auth/logout/snippets/logout.java new file mode 100644 index 00000000..d2a8f8b2 --- /dev/null +++ b/doc/3/controllers/auth/logout/snippets/logout.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +kuzzle.getAuthController().logout(); diff --git a/doc/3/controllers/auth/logout/snippets/logout.test.yml b/doc/3/controllers/auth/logout/snippets/logout.test.yml new file mode 100644 index 00000000..38e8d693 --- /dev/null +++ b/doc/3/controllers/auth/logout/snippets/logout.test.yml @@ -0,0 +1,7 @@ +name: Auth#Logout +description: Revokes the user's token & unsubscribe them from registered rooms. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: default +expected: Success diff --git a/doc/3/controllers/auth/refresh-token/index.md b/doc/3/controllers/auth/refresh-token/index.md new file mode 100644 index 00000000..cd1c8f08 --- /dev/null +++ b/doc/3/controllers/auth/refresh-token/index.md @@ -0,0 +1,43 @@ +--- +code: true +type: page +title: RefreshToken +description: Refreshes an authentication token. +--- + +# RefreshToken + +Refreshes an authentication token. + +- a valid, non-expired authentication must be provided +- the provided authentication token is revoked +- a new authentication token is generated and returned + +## Arguments + +```java +CompletableFuture> refreshToken( + final String expiresIn) throws NotConnectedException, InternalException +``` + +**Optional:** + +| Argument | Type | Description | +|-------------|-------------------|-----------------------------------------------------------------------------| +| `expiresIn` |
String
| Set the token expiration duration (default: depends on Kuzzle configuration file) | + +## Return + +A ConcurrentHashMap with the following properties: + +| Property | Type | Description | +|-------------|-------------------|------------------------------------------------------------------------------------------| +| `_id` |
String
| User's `kuid` | +| `jwt` |
String
| Encrypted authentication token, that must then be sent in the requests headers or in the query | +| `expiresAt` |
int
| Token expiration date, in Epoch-millis (UTC) | +| `ttl` |
int
| Token time to live, in milliseconds | +Once `auth:refreshToken` has been called, the returned authentication token is stored by the SDK and used for all the subsequent API calls. + +## Usage + +<<< ./snippets/refresh-token.java diff --git a/doc/3/controllers/auth/refresh-token/snippets/refresh-token.java b/doc/3/controllers/auth/refresh-token/snippets/refresh-token.java new file mode 100644 index 00000000..4883c424 --- /dev/null +++ b/doc/3/controllers/auth/refresh-token/snippets/refresh-token.java @@ -0,0 +1,7 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ConcurrentHashMap result = + kuzzle.getAuthController().refreshToken("1h").get(); diff --git a/doc/3/controllers/auth/refresh-token/snippets/refresh-token.test.yml b/doc/3/controllers/auth/refresh-token/snippets/refresh-token.test.yml new file mode 100644 index 00000000..9de330c4 --- /dev/null +++ b/doc/3/controllers/auth/refresh-token/snippets/refresh-token.test.yml @@ -0,0 +1,7 @@ +name: Auth#RefreshToken +description: Refreshes an authentication token. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: ^{jwt=.*,\ _id=foo,\ ttl=3600000,\ expiresAt=[0-9]+}$ diff --git a/doc/3/controllers/auth/update-my-credentials/index.md b/doc/3/controllers/auth/update-my-credentials/index.md new file mode 100644 index 00000000..c7081c11 --- /dev/null +++ b/doc/3/controllers/auth/update-my-credentials/index.md @@ -0,0 +1,37 @@ +--- +code: true +type: page +title: UpdateMyCredentials +description: Updates the current user's credentials for the specified strategy. +--- + +# UpdateMyCredentials + +Updates the current user's credentials for the specified strategy. The credentials to send will depend on the authentication plugin and the authentication strategy. + +## Arguments + +```java +CompletableFuture> updateMyCredentials( + final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|---------------|--------------------|--------------------------------------| +| `strategy` |
String
| Strategy to use | +| `credentials` |
ConcurrentHashMap
| JObject representing the credentials | + +## Return + +A ConcurrentHashMap representing the updated credentials with the following properties: + +| Property | Type | Description | +|------------|-------------------|-------------------| +| `username` |
String
| The Username | +| `kuid` |
String
| The user's `kuid` | + +## Usage + +<<< ./snippets/update-my-credentials.java diff --git a/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.java b/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.java new file mode 100644 index 00000000..73021f4f --- /dev/null +++ b/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +ConcurrentHashMap result = kuzzle.getAuthController().updateMyCredentials("local", credentials).get(); diff --git a/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.test.yml b/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.test.yml new file mode 100644 index 00000000..5f6b297f --- /dev/null +++ b/doc/3/controllers/auth/update-my-credentials/snippets/update-my-credentials.test.yml @@ -0,0 +1,7 @@ +name: Auth#UpdateMyCredentials +description: Updates the current user's credentials for the specified strategy. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: {username=foo} diff --git a/doc/3/controllers/auth/update-self/index.md b/doc/3/controllers/auth/update-self/index.md new file mode 100644 index 00000000..a912660f --- /dev/null +++ b/doc/3/controllers/auth/update-self/index.md @@ -0,0 +1,35 @@ +--- +code: true +type: page +title: UpdateSelf +description: Updates the current user object in Kuzzle. +--- + +# UpdateSelf + +Updates the current user object in Kuzzle. + +## Arguments + +```java +CompletableFuture> updateSelf( + final ConcurrentHashMap content) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|-----------|--------------------|---------------------------------------| +| `content` |
ConcurrentHashMap
| Hashmap representing the user content | + +## Return + +Returns a ConcurrentHashMap with the following properties: + +| Property | Type | Description | +|-----------|--------------------|-------------------------------------------| +| `_id` |
String
| User's `kuid` | +| `_source` |
ConcurrentHashMap
| Additional (and optional) user properties | + +## Usage + +<<< ./snippets/update-self.java diff --git a/doc/3/controllers/auth/update-self/snippets/update-self.java b/doc/3/controllers/auth/update-self/snippets/update-self.java new file mode 100644 index 00000000..4d142b15 --- /dev/null +++ b/doc/3/controllers/auth/update-self/snippets/update-self.java @@ -0,0 +1,11 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); + +ConcurrentHashMap custom = new ConcurrentHashMap<>(); +custom.put("age", 42); + +ConcurrentHashMap result = + kuzzle.getAuthController().updateSelf(custom).get(); diff --git a/doc/3/controllers/auth/update-self/snippets/update-self.test.yml b/doc/3/controllers/auth/update-self/snippets/update-self.test.yml new file mode 100644 index 00000000..56a8f326 --- /dev/null +++ b/doc/3/controllers/auth/update-self/snippets/update-self.test.yml @@ -0,0 +1,7 @@ +name: Auth#UpdateSelf +description: Updates the current user object in Kuzzle. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: ^{_source={profileIds=\[default\],\ _kuzzle_info={createdAt=[0-9]+,\ author=-1},\ age=42},\ _id=foo}$ diff --git a/doc/3/controllers/auth/validate-my-credentials/index.md b/doc/3/controllers/auth/validate-my-credentials/index.md new file mode 100644 index 00000000..a56a7f70 --- /dev/null +++ b/doc/3/controllers/auth/validate-my-credentials/index.md @@ -0,0 +1,31 @@ +--- +code: true +type: page +title: ValidateMyCredentials +description: Validates the current user's credentials for the specified strategy. +--- + +# ValidateMyCredentials + +Validates the current user's credentials for the specified strategy. This method returns `true` if the provided credentials are valid; otherwise an error is triggered. This route does not actually create or modify the user credentials. The credentials to send will depend on the authentication plugin and authentication strategy. + +## Arguments + +```java +CompletableFuture validateMyCredentials(final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|---------------|--------------------|--------------------------------------| +| `strategy` |
String
| Strategy to use | +| `credentials` |
ConcurrentHashMap
| A Hashmap representing the credentials | + +## Return + +A boolean indicating if the credentials are valid. + +## Usage + +<<< ./snippets/validate-my-credentials.java diff --git a/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.java b/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.java new file mode 100644 index 00000000..2888af52 --- /dev/null +++ b/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.java @@ -0,0 +1,6 @@ +ConcurrentHashMap credentials = new ConcurrentHashMap<>(); +credentials.put("username", "foo"); +credentials.put("password", "bar"); + +kuzzle.getAuthController().login("local", credentials).get(); +Boolean result = kuzzle.getAuthController().validateMyCredentials("local", credentials).get(); diff --git a/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.test.yml b/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.test.yml new file mode 100644 index 00000000..cd4a836a --- /dev/null +++ b/doc/3/controllers/auth/validate-my-credentials/snippets/validate-my-credentials.test.yml @@ -0,0 +1,7 @@ +name: Auth#ValidateMyCredentials +description: Validates the current user's credentials for the specified strategy. +hooks: + before: curl -X POST kuzzle:7512/users/foo/_create -H "Content-Type:application/json" --data '{"content":{"profileIds":["default"]},"credentials":{"local":{"username":"foo","password":"bar"}}}' + after: curl -X DELETE kuzzle:7512/users/foo +template: print-result +expected: [true] diff --git a/doc/3/controllers/index.md b/doc/3/controllers/index.md index fc59442a..3e88f493 100644 --- a/doc/3/controllers/index.md +++ b/doc/3/controllers/index.md @@ -1,7 +1,7 @@ --- code: false type: branch -order: 100 +order: 60 title: Controllers description: Kuzzle Java SDK controllers --- diff --git a/doc/3/core-classes/error-response/index.md b/doc/3/core-classes/error-response/index.md new file mode 100644 index 00000000..bae90d65 --- /dev/null +++ b/doc/3/core-classes/error-response/index.md @@ -0,0 +1,7 @@ +--- +code: true +type: branch +title: ErrorResponse +description: ErrorResponse object documentation +order: 0 +--- \ No newline at end of file diff --git a/doc/3/core-classes/error-response/introduction/index.md b/doc/3/core-classes/error-response/introduction/index.md new file mode 100644 index 00000000..1e0cc386 --- /dev/null +++ b/doc/3/core-classes/error-response/introduction/index.md @@ -0,0 +1,20 @@ +--- +code: false +type: page +title: Introduction +description: ErrorResponse object description +order: 0 +--- + +## ErrorResponse + +`ErrorResponse` is a **serializable** class representing a raw Kuzzle response with error. + +## Properties + +| Property | Type | Description | +|--- |--- |--- | +| `id` |
String
| Error ID | +| `message` |
String
| Error message | +| `stack` |
String
| Error stack | +| `status` |
int
| esponse status, following HTTP status codes. | diff --git a/doc/3/core-classes/kuzzle-options/index.md b/doc/3/core-classes/kuzzle-options/index.md new file mode 100644 index 00000000..193fa890 --- /dev/null +++ b/doc/3/core-classes/kuzzle-options/index.md @@ -0,0 +1,67 @@ +--- +code: true +type: page +title: KuzzleOptions +description: KuzzleOptions class documentation +order: 110 +--- + +# KuzzleOptions + +This class represents the options usable with the Kuzzle class. + +It can be used with the following methods: + - [Kuzzle.Kuzzle](/sdk/java/3/core-classes/kuzzle) + +# Constructor + +This class has a constructor and a constructor by copy. + +## Getters and setters + +### queueMaxSize + +The maximum amount of elements that the queue can contains. If set to -1, the size is unlimited. + +```java +public int getMaxQueueSize(); +public KuzzleOptions setMaxQueueSize(int maxQueueSize) +``` + +### minTokenDuration + +The minimum duration of a Token before being automatically refreshed. If set to -1 the SDK does not refresh the token automatically. + +```java +public int getMinTokenDuration() +public KuzzleOptions setMinTokenDuration(int minTokenDuration) +``` + +### refreshedTokenDuration + +The minimum duration of a Token after refresh. If set to -1 the SDK does not refresh the token automatically. + +```java +public int getRefreshedTokenDuration() +public KuzzleOptions setRefreshedTokenDuration(int refreshedTokenDuration) +``` + +### maxRequestDelay + +The maximum delay between two requests to be replayed. + +```java +public int getMaxRequestDelay() +public KuzzleOptions setMaxRequestDelay(int maxRequestDelay) +``` + +### queueFilter + +Function to filter the request queue before replaying requests. + +```java +public Predicate> getQueueFilter() +public KuzzleOptions setQueueFilter( + Predicate> filter +) +``` diff --git a/doc/3/core-classes/kuzzle/connect/index.md b/doc/3/core-classes/kuzzle/connect/index.md new file mode 100644 index 00000000..983d56c9 --- /dev/null +++ b/doc/3/core-classes/kuzzle/connect/index.md @@ -0,0 +1,22 @@ +--- +code: true +type: page +title: Connect +description: Connects the SDK to Kuzzle +--- + +# Connect + +Connects to Kuzzle using the underlying protocol `connect` method. + +Subsequent calls have no effect if the SDK is already connected. + +## Arguments + +```java +public void connect() throws Exception; +``` + +## Usage + +<<< ./snippets/connect.java diff --git a/doc/3/core-classes/kuzzle/connect/snippets/connect.java b/doc/3/core-classes/kuzzle/connect/snippets/connect.java new file mode 100644 index 00000000..599a215c --- /dev/null +++ b/doc/3/core-classes/kuzzle/connect/snippets/connect.java @@ -0,0 +1 @@ +kuzzle.connect(); diff --git a/doc/3/core-classes/kuzzle/connect/snippets/connect.test.yml b/doc/3/core-classes/kuzzle/connect/snippets/connect.test.yml new file mode 100644 index 00000000..9932ecd6 --- /dev/null +++ b/doc/3/core-classes/kuzzle/connect/snippets/connect.test.yml @@ -0,0 +1,8 @@ +--- +name: kuzzle#Connect +description: Connects the SDK to Kuzzle +hooks: + before: + after: +template: without-connect +expected: Success diff --git a/doc/3/core-classes/kuzzle/constructor/index.md b/doc/3/core-classes/kuzzle/constructor/index.md new file mode 100644 index 00000000..f2b2f5c8 --- /dev/null +++ b/doc/3/core-classes/kuzzle/constructor/index.md @@ -0,0 +1,52 @@ +--- +code: true +type: page +title: Constructor +description: Creates a new Kuzzle object connected to the backend +order: 100 +--- + +# Constructor + +Use this constructor to create a new instance of the SDK. +Each instance represents a different connection to a Kuzzle server with specific options. + +## Arguments + +```java +public Kuzzle( + AbstractProtocol networkProtocol, + KuzzleOptions options +) throws IllegalArgumentException +``` + +
+ +| Argument | Type | Description | +| ---------- | ------------------- | --------------------------------- | +| `networkProtocol` |
AbstractProtocol
| Protocol used by the SDK instance | +| `options` |
KuzzleOptions
| Class which contains options | + +## networkProtocol + +The protocol used to connect to the Kuzzle instance. +It can be one of the following available protocols: + +- [WebSocket](/sdk/java/3/protocols/websocket) + +## options + +The options used to connect to the Kuzzle instance. +[KuzzleOptions](/sdk/java/3/core-classes/kuzzle-options) + +## Return + +The `Kuzzle` SDK instance. + +## Throws + +Can throw an [IllegalArgumentException](/sdk/java/3/exceptions/illegal-argument-exception) + +## Usage + +<<< ./snippets/constructor.java diff --git a/doc/3/core-classes/kuzzle/constructor/snippets/constructor.java b/doc/3/core-classes/kuzzle/constructor/snippets/constructor.java new file mode 100644 index 00000000..279377aa --- /dev/null +++ b/doc/3/core-classes/kuzzle/constructor/snippets/constructor.java @@ -0,0 +1,7 @@ +KuzzleOptions options = new KuzzleOptions(); +options.setMaxQueueSize(42) + .setMaxRequestDelay(1) + .setMinTokenDuration(24) + .setRefreshedTokenDuration(40) + .setQueueFilter(stringObjectConcurrentHashMap -> true); +Kuzzle kuzzle = new Kuzzle(new WebSocket("kuzzle"), options); diff --git a/doc/3/core-classes/kuzzle/constructor/snippets/constructor.test.yml b/doc/3/core-classes/kuzzle/constructor/snippets/constructor.test.yml new file mode 100644 index 00000000..3ff0862d --- /dev/null +++ b/doc/3/core-classes/kuzzle/constructor/snippets/constructor.test.yml @@ -0,0 +1,8 @@ +--- +name: kuzzle#constructor +description: Creates a new Kuzzle instance +hooks: + before: + after: +template: without-ctor +expected: Success \ No newline at end of file diff --git a/doc/3/core-classes/kuzzle/disconnect/index.md b/doc/3/core-classes/kuzzle/disconnect/index.md new file mode 100644 index 00000000..1f4d7de8 --- /dev/null +++ b/doc/3/core-classes/kuzzle/disconnect/index.md @@ -0,0 +1,22 @@ +--- +code: true +type: page +title: Disconnect +description: Disconnects the SDK from Kuzzle +--- + +# Disconnect + +Closes the current connection to Kuzzle. + +Disconnects the SDK from the Kuzzle server using the underlying protocol `Disconnect` method. + +## Arguments + +```java +public void disconnect() +``` + +## Usage + +<<< ./snippets/disconnect.java diff --git a/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.java b/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.java new file mode 100644 index 00000000..e7a7f4d6 --- /dev/null +++ b/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.java @@ -0,0 +1 @@ +kuzzle.disconnect(); diff --git a/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.test.yml b/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.test.yml new file mode 100644 index 00000000..a9d9fe19 --- /dev/null +++ b/doc/3/core-classes/kuzzle/disconnect/snippets/disconnect.test.yml @@ -0,0 +1,8 @@ +--- +name: kuzzle#Disconnect +description: Disconnects the SDK to Kuzzle +hooks: + before: + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/core-classes/kuzzle/index.md b/doc/3/core-classes/kuzzle/index.md new file mode 100644 index 00000000..b6873810 --- /dev/null +++ b/doc/3/core-classes/kuzzle/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: branch +order: 100 +title: Kuzzle +description: Kuzzle class +--- diff --git a/doc/3/core-classes/kuzzle/query/index.md b/doc/3/core-classes/kuzzle/query/index.md new file mode 100644 index 00000000..68f3884d --- /dev/null +++ b/doc/3/core-classes/kuzzle/query/index.md @@ -0,0 +1,51 @@ +--- +code: true +type: page +title: Query +description: Base method to send API query to Kuzzle +--- + +# query + +Base method used to send queries to Kuzzle, following the [API Documentation](/core/2/api). + +:::warning +This is a low-level method, exposed to allow advanced SDK users to bypass high-level methods. +::: + +## Arguments + +```java +public CompletableFuture query( + final ConcurrentHashMap query) + throws InternalException, NotConnectedException +``` + +
+ +| Argument | Type | Description | +| --------- | ----------------- | ---------------------- | +| `query` |
ConcurrentHashMap
| API request | + +### query + +All properties necessary for the Kuzzle API can be added in the query object. +The following properties are the most common. + +| Property | Type | Description | +| ------------ | ----------------- | ---------------------------------------- | +| `controller` |
String
| Controller name (mandatory) | +| `action` |
String
| Action name (mandatory) | +| `body` |
ConcurrentHashMap
| Query body for this action | +| `index` |
String
| Index name for this action | +| `collection` |
String
| Collection name for this action | +| `_id` |
String
| id for this action | +| `volatile` |
ConcurrentHashMap
| Additional information to send to Kuzzle | + +## Returns + +Returns a [Response](/sdk/java/3/core-classes/response) object which represents a raw Kuzzle API response. See the [API Documentation](/core/2/api). + +## Usage + +<<< ./snippets/query.java diff --git a/doc/3/core-classes/kuzzle/query/snippets/query.java b/doc/3/core-classes/kuzzle/query/snippets/query.java new file mode 100644 index 00000000..76e76e85 --- /dev/null +++ b/doc/3/core-classes/kuzzle/query/snippets/query.java @@ -0,0 +1,13 @@ +ConcurrentHashMap query = new ConcurrentHashMap<>(); +query.put("controller", "document"); +query.put("action", "create"); +query.put("index", "nyc-open-data"); +query.put("collection", "yellow-taxi"); +query.put("_id", "my-custom-document-id"); +query.put("refresh", "wait_for"); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +body.put("trip_distance", 4.23); +body.put("passenger_count", 2); +query.put("body", body); + +Response res = kuzzle.query(query).get(); diff --git a/doc/3/core-classes/kuzzle/query/snippets/query.test.yml b/doc/3/core-classes/kuzzle/query/snippets/query.test.yml new file mode 100644 index 00000000..87fbb5b7 --- /dev/null +++ b/doc/3/core-classes/kuzzle/query/snippets/query.test.yml @@ -0,0 +1,11 @@ +--- +name: kuzzle#Query +description: Sends a request to Kuzzle API +hooks: + before: | + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -X DELETE kuzzle:7512/nyc-open-data/yellow-taxi/my-custom-document-id + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/core-classes/response/index.md b/doc/3/core-classes/response/index.md new file mode 100644 index 00000000..020ffc47 --- /dev/null +++ b/doc/3/core-classes/response/index.md @@ -0,0 +1,7 @@ +--- +code: true +type: branch +title: Response +description: Response object documentation +order: 0 +--- \ No newline at end of file diff --git a/doc/3/core-classes/response/introduction/index.md b/doc/3/core-classes/response/introduction/index.md new file mode 100644 index 00000000..a88bf823 --- /dev/null +++ b/doc/3/core-classes/response/introduction/index.md @@ -0,0 +1,30 @@ +--- +code: false +type: page +title: Introduction +description: Response object description +order: 0 +--- + +## Response + +`Response` is a **serializable** class representing a raw Kuzzle response. + +## Properties + +| Property | Type | Description | +|--- |--- |--- | +| `action` |
String
| Executed Kuzzle API controller's action | +| `collection` |
String
| Impacted collection | +| `controller` |
String
| Executed Kuzzle API controller | +| `error` |
[ErrorResponse](/sdk/java/3/core-classes/error-response)
| Error object (null if the request finished successfully) | +| `index` |
String
| Impacted index | +| `protocol` |
String
| Network protocol at the origin of the real-time notification | +| `requestId` |
String
| Request unique identifier | +| `result` |
Object
| Response payload (depends on the executed API action) | +| `room` |
String
| Room identifier (realtime only) | +| `scope` |
String
| Document scope ("in" or "out", realtime only) | +| `state` |
String
| Document state (realtime only) | +| `status` |
int
| Response status, following HTTP status codes | +| `timestamp` |
Long
| Notification timestamp (UTC) | +| `volatile` |
ConcurrentHashMap
| Volatile data | diff --git a/doc/3/exceptions/illegal-argument-exception/index.md b/doc/3/exceptions/illegal-argument-exception/index.md new file mode 100644 index 00000000..23fe27a7 --- /dev/null +++ b/doc/3/exceptions/illegal-argument-exception/index.md @@ -0,0 +1,11 @@ +--- +code: true +type: page +title: IllegalArgumentException +description: IllegalArgumentException +order: 10 +--- + +# IllegalArgumentException + +The `IllegalArgumentException` class is thrown when a bad argument is passed. diff --git a/doc/3/index.md b/doc/3/index.md new file mode 100644 index 00000000..6642becc --- /dev/null +++ b/doc/3/index.md @@ -0,0 +1,7 @@ +--- +code: false +type: root +order: 9 +title: JAVA SDK +description: JAVA SDK 3.x +--- diff --git a/doc/3/protocols/websocket-options/index.md b/doc/3/protocols/websocket-options/index.md new file mode 100644 index 00000000..fc0801ea --- /dev/null +++ b/doc/3/protocols/websocket-options/index.md @@ -0,0 +1,56 @@ +--- +code: true +type: page +title: WebSocketOptions +description: KuzzleOptions class documentation +order: 110 +--- + +# WebSocketOptions + +This class represents the options usable with the Kuzzle class. + +It can be used with the following methods: + - [WebSocket.WebSocket](/sdk/java/3/protocols/websocket) + +# Constructor + +This class has a constructor and a constructor by copy. + +## Getters and setters + +### port + +The port to use to connect. + +```java +public int getPort(); +public WebSocketOptions setPort(int port) +``` + +### ssl + +If we use SSL connection. + +```java +public boolean getSsl() +public WebSocketOptions setSsl(boolean ssl) +``` + +### connectionTimeout + +The duration before the connection timeout. + +```java +public int getConnectionTimeout() +public WebSocketOptions setConnectionTimeout(int connectionTimeout) +``` + +### autoReconnect + +If the websocket auto reconnects. + +```java +public boolean getAutoReconnect() +public KuzzleOptions setAutoReconnect(boolean autoReconnect) +``` diff --git a/doc/3/protocols/websocket/constructor/index.md b/doc/3/protocols/websocket/constructor/index.md new file mode 100644 index 00000000..d136c3f7 --- /dev/null +++ b/doc/3/protocols/websocket/constructor/index.md @@ -0,0 +1,72 @@ +--- +code: true +type: page +title: Constructor +description: Creates a new WebSocket protocol +order: 50 +--- + +# Constructor + +Initializes a new instance of the WebSocket class pointing to the Kuzzle server specified by the uri. + +## Arguments + +```java +public WebSocket(URI uri, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException +``` + +
+ +| Argument | Type | Description | +| --------- | ----------------- | ---------------------------- | +| `uri` |
Uri
| URI pointing to a Kuzzle server | +| `options` |
WebSocketOptions
| Class which contains websocket options | + +### uri + +A Uri object pointing to a Kuzzle server. + +Use `wss://:` to initiate a secure SSL connection. + +## options + +The options used to connect to the Kuzzle instance. +[WebSocketOptions](/sdk/java/3/protocols/websocket-options) + +## Return + +A `WebSocket` protocol instance. + +## Arguments + +```java +public WebSocket(String host, WebSocketOptions options) + throws URISyntaxException, IllegalArgumentException +``` + +
+ +| Argument | Type | Description | +| --------- | ----------------- | ---------------------------- | +| `host` |
String
| Host pointing to a Kuzzle server | +| `options` |
WebSocketOptions
| Class which contains websocket options | + +### host + +A host pointing to a Kuzzle server. + +Use `wss://:` to initiate a secure SSL connection. + +## options + +The options used to connect to the Kuzzle instance. +[WebSocketOptions](/sdk/java/3/protocols/websocket-options) + +## Return + +A `WebSocket` protocol instance. + +## Usage + +<<< ./snippets/constructor.java diff --git a/doc/3/protocols/websocket/constructor/snippets/constructor.java b/doc/3/protocols/websocket/constructor/snippets/constructor.java new file mode 100644 index 00000000..d7fccde8 --- /dev/null +++ b/doc/3/protocols/websocket/constructor/snippets/constructor.java @@ -0,0 +1,7 @@ +WebSocketOptions options = new WebSocketOptions(); +options.setAutoReconnect(true) + .setConnectionTimeout(42000) + .setPort(7513) + .setSsl(false); + +WebSocket ws = new WebSocket("localhost", options); diff --git a/doc/3/protocols/websocket/constructor/snippets/constructor.test.yml b/doc/3/protocols/websocket/constructor/snippets/constructor.test.yml new file mode 100644 index 00000000..419028a7 --- /dev/null +++ b/doc/3/protocols/websocket/constructor/snippets/constructor.test.yml @@ -0,0 +1,8 @@ +--- +name: websocket#constructor +description: Creates a new WebSocket instance +hooks: + before: + after: +template: without-ctor +expected: Success \ No newline at end of file diff --git a/doc/3/protocols/websocket/index.md b/doc/3/protocols/websocket/index.md new file mode 100644 index 00000000..8185611a --- /dev/null +++ b/doc/3/protocols/websocket/index.md @@ -0,0 +1,7 @@ +--- +code: true +type: branch +title: WebSocket +description: WebSocket protocol documentation +order: 0 +--- \ No newline at end of file diff --git a/features/sdk-features b/features/sdk-features deleted file mode 160000 index 882e0664..00000000 --- a/features/sdk-features +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 882e066490b2ca6a6dd045fdcf65cc4d847b2785 diff --git a/sdk-cpp b/sdk-cpp deleted file mode 160000 index d0750478..00000000 --- a/sdk-cpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d07504781a8b3389da9a189be32e7388ae0a9f63 diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java new file mode 100644 index 00000000..4255cb7c --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java @@ -0,0 +1,276 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class AuthController extends BaseController { + + public AuthController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Checks the validity of an authentication token. + * + * @param token + * An authentication token + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> checkToken( + final String token) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "checkToken") + .put("body", new KuzzleMap().put("token", token)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Creates new credentials for the current user. + * + * @param strategy + * A String representing the strategy + * @param credentials + * A ConcurrentHashMap representing + * credentials information + * @return A CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> createMyCredentials( + final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "createMyCredentials") + .put("body", credentials) + .put("strategy", strategy); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result)); + } + + /** + * Checks that the current authenticated user has credentials for the + * specified authentication strategy. + * + * @param strategy + * A String representing the strategy + * @return A CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture credentialsExist(final String strategy) + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "credentialsExist") + .put("strategy", strategy); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> (Boolean) response.result); + } + + public CompletableFuture deleteMyCredentials(final String strategy) + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query.put("controller", "auth"); + query.put("action", "deleteMyCredentials"); + query.put("strategy", strategy); + + return kuzzle.query(query).thenRunAsync(() -> { + }); + } + + public CompletableFuture> getCurrentUser() + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query.put("controller", "auth").put("action", "getCurrentUser"); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result)); + } + + public CompletableFuture> getMyCredentials( + final String strategy) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "getMyCredentials") + .put("strategy", strategy); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result)); + } + + public CompletableFuture> getMyRights() + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query.put("controller", "auth").put("action", "getMyRights"); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result) + .getArrayList("hits")); + } + + public CompletableFuture> getStrategies() + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query.put("controller", "auth").put("action", "getStrategies"); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> (ArrayList) response.result); + } + + public CompletableFuture> login( + final String strategy, + final ConcurrentHashMap credentials, + final String expiresIn) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "login") + .put("strategy", strategy) + .put("body", credentials) + .put("expiresIn", (expiresIn == null ? "1h" : expiresIn)); + + return kuzzle.query(query).thenApplyAsync((response) -> { + final KuzzleMap map = KuzzleMap + .from((ConcurrentHashMap) response.result); + kuzzle.setAuthenticationToken(map.getString("jwt")); + if (!map.isNull("_id")) { + kuzzle.trigger(Event.loginAttempt, true); + } else { + kuzzle.trigger(Event.loginAttempt, false); + } + return map; + }); + } + + public CompletableFuture> login( + final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException { + return login(strategy, credentials, null); + } + + public CompletableFuture logout() + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query.put("controller", "auth").put("action", "logout"); + + return kuzzle.query(query); + } + + public CompletableFuture> refreshToken( + final String expiresIn) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "refreshToken") + .put("expiresIn", expiresIn); + + return kuzzle.query(query).thenApplyAsync((response) -> { + final KuzzleMap map = KuzzleMap + .from((ConcurrentHashMap) response.result); + kuzzle.setAuthenticationToken(map.getString("jwt")); + + return map; + }); + } + + public CompletableFuture> refreshToken() + throws NotConnectedException, InternalException { + return refreshToken(null); + } + + public CompletableFuture> updateMyCredentials( + final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "updateMyCredentials") + .put("strategy", strategy) + .put("body", credentials); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result)); + } + + public CompletableFuture> updateSelf( + final ConcurrentHashMap content) + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "updateSelf") + .put("body", content); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> KuzzleMap + .from((ConcurrentHashMap) response.result)); + } + + public CompletableFuture validateMyCredentials(final String strategy, + final ConcurrentHashMap credentials) + throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("controller", "auth") + .put("action", "validateMyCredentials") + .put("strategy", strategy) + .put("body", credentials); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> (Boolean) response.result); + } +} diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/BaseController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/BaseController.java new file mode 100644 index 00000000..ea16442a --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/BaseController.java @@ -0,0 +1,12 @@ + +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.Kuzzle; + +public class BaseController { + protected final Kuzzle kuzzle; + + protected BaseController(Kuzzle kuzzle) { + this.kuzzle = kuzzle; + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java index 5b34a171..f7c9776d 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/ConcurrentHashMapTypeAdapter.java @@ -15,10 +15,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class ConcurrentHashMapTypeAdapter extends TypeAdapter> { +public class ConcurrentHashMapTypeAdapter + extends TypeAdapter> { @Override - public void write(JsonWriter out, ConcurrentHashMap map) throws IOException { + public void write(JsonWriter out, ConcurrentHashMap map) + throws IOException { if (map == null) { out.nullValue(); } else { @@ -36,7 +38,8 @@ public void write(JsonWriter out, ConcurrentHashMap map) throws } @Override - public ConcurrentHashMap read(JsonReader in) throws IOException { + public ConcurrentHashMap read(JsonReader in) + throws IOException { JsonToken peek = in.peek(); if (peek == JsonToken.NULL) { in.nextNull(); @@ -83,7 +86,9 @@ private void writeObject(JsonWriter out, Object value) throws IOException { out.endArray(); } else if (value instanceof ConcurrentHashMap) { out.beginObject(); - Iterator> iterator = ((ConcurrentHashMap) value).entrySet().iterator(); + Iterator> iterator = ((ConcurrentHashMap) value) + .entrySet() + .iterator(); while (iterator.hasNext()) { Map.Entry e = iterator.next(); diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java index b0235b58..8abfaf36 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Json/JsonSerializer.java @@ -9,8 +9,13 @@ public class JsonSerializer { private static Gson gson; static { - gson = new GsonBuilder().disableHtmlEscaping().disableInnerClassSerialization().serializeNulls() - .registerTypeAdapter(ConcurrentHashMap.class, new ConcurrentHashMapTypeAdapter()).create(); + gson = new GsonBuilder() + .disableHtmlEscaping() + .disableInnerClassSerialization() + .serializeNulls() + .registerTypeAdapter(ConcurrentHashMap.class, + new ConcurrentHashMapTypeAdapter()) + .create(); } public static ConcurrentHashMap deserialize(String rawJson) { diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java index fc29d682..96dae224 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/KuzzleMap.java @@ -13,10 +13,16 @@ */ public class KuzzleMap extends ConcurrentHashMap { + /** + * serialVersionUID + */ + private static final long serialVersionUID = -3027862451021177820L; + /** * Convert à ConcurrentHashMap to a CustomMap * - * @param map ConcurrentHashMap representing JSON. + * @param map + * ConcurrentHashMap representing JSON. * @return a CustomMap instance */ public static KuzzleMap from(ConcurrentHashMap map) { @@ -37,9 +43,11 @@ public KuzzleMap() { } /** - * Create a new instance of CustomMap from a ConcurrentHashMap. + * Create a new instance of CustomMap from a ConcurrentHashMap. * - * @param map ConcurrentHashMap representing JSON. + * @param map + * ConcurrentHashMap representing JSON. */ public KuzzleMap(ConcurrentHashMap map) { super(); @@ -52,17 +60,14 @@ public KuzzleMap(ConcurrentHashMap map) { } @Override - public Object put(String s, Object o) { - Object obj = null; + public KuzzleMap put(String s, Object o) { if (o != null) { - obj = super.put(s, o); + super.put(s, o); } else { - obj = super.put(s, new Null()); + super.put(s, new Null()); } - if (obj instanceof Null) { - return null; - } - return obj; + + return this; } @Override @@ -88,7 +93,8 @@ public Set> entrySet() { /** * Check whether the key value is null or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the value is null. */ public boolean isNull(String key) { @@ -98,7 +104,8 @@ public boolean isNull(String key) { /** * Check whether the key value is a String or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the key is a String. */ public boolean isString(String key) { @@ -108,7 +115,8 @@ public boolean isString(String key) { /** * Check whether the key value is a Boolean or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the key is a Boolean. */ public boolean isBoolean(String key) { @@ -118,7 +126,8 @@ public boolean isBoolean(String key) { /** * Check whether the key value is a Number or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the key is a Number. */ public boolean isNumber(String key) { @@ -128,7 +137,8 @@ public boolean isNumber(String key) { /** * Check whether the key value is an ArrayList or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the key is an ArrayList. */ public boolean isArrayList(String key) { @@ -138,7 +148,8 @@ public boolean isArrayList(String key) { /** * Check whether the key value is a ConcurrentHashMap or not. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return true if the key is a ConcurrentHashMap. */ public boolean isMap(String key) { @@ -148,7 +159,8 @@ public boolean isMap(String key) { /** * Return the specified key value or null if the value is not a String. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The String at the key or null */ public String getString(String key) { @@ -158,7 +170,8 @@ public String getString(String key) { /** * Return the specified key value or null if the value is not a Boolean. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The Boolean at the key or null */ public Boolean getBoolean(String key) { @@ -168,7 +181,8 @@ public Boolean getBoolean(String key) { /** * Return the specified key value or null if the value is not a Number. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The Number at the key or null */ public Number getNumber(String key) { @@ -178,7 +192,8 @@ public Number getNumber(String key) { /** * Return the specified key value or null if the value is not an ArrayList. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The ArrayList at the key or null */ public ArrayList getArrayList(String key) { @@ -189,18 +204,22 @@ public ArrayList getArrayList(String key) { * Return the specified key value or null if the value is not a * ConcurrentHashMap. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The ConcurrentHashMap at the key or null */ public KuzzleMap getMap(String key) { - return isMap(key) ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) : null; + return isMap(key) + ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) + : null; } /** - * Return the specified key value or the def value if the value is nul or not a - * String. + * Return the specified key value or the def value if the value is nul or not + * a String. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The String at the key or def value */ public String optString(String key, String def) { @@ -208,10 +227,11 @@ public String optString(String key, String def) { } /** - * Return the specified key value or the def value if the value is nul or not a - * Boolean. + * Return the specified key value or the def value if the value is nul or not + * a Boolean. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The Boolean at the key or def value */ public Boolean optBoolean(String key, Boolean def) { @@ -219,10 +239,11 @@ public Boolean optBoolean(String key, Boolean def) { } /** - * Return the specified key value or the def value if the value is nul or not a - * Number. + * Return the specified key value or the def value if the value is nul or not + * a Number. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The Number at the key or def value */ public Number optNumber(String key, Number def) { @@ -230,10 +251,11 @@ public Number optNumber(String key, Number def) { } /** - * Return the specified key value or the def value if the value is nul or not an - * ArrayList. + * Return the specified key value or the def value if the value is nul or not + * an ArrayList. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The ArrayList at the key or def value */ public ArrayList optArrayList(String key, ArrayList def) { @@ -241,13 +263,16 @@ public ArrayList optArrayList(String key, ArrayList def) { } /** - * Return the specified key value or the def value if the value is nul or not a - * ConcurrentHashMap. + * Return the specified key value or the def value if the value is nul or not + * a ConcurrentHashMap. * - * @param key a String representing the key. + * @param key + * a String representing the key. * @return The ConcurrentHashMap at the key or def value */ public KuzzleMap optMap(String key, ConcurrentHashMap def) { - return isMap(key) ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) : KuzzleMap.from(def); + return isMap(key) + ? KuzzleMap.from((ConcurrentHashMap) super.get(key)) + : KuzzleMap.from(def); } } diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java index bd295eaf..b9d0350d 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Maps/Null.java @@ -6,4 +6,8 @@ public class Null { public int hashCode() { return hashCode; } + + public String toString() { + return "null"; + } } \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java index 1478c5fb..5dd0e94f 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java @@ -3,7 +3,6 @@ import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.CoreClasses.Maps.Serializable; import io.kuzzle.sdk.Exceptions.InternalException; -import io.kuzzle.sdk.Exceptions.KuzzleException; import io.kuzzle.sdk.Exceptions.KuzzleExceptionCode; import java.util.concurrent.ConcurrentHashMap; @@ -85,7 +84,8 @@ public class Response implements Serializable { public String type; @Override - public void fromMap(ConcurrentHashMap map) throws InternalException { + public void fromMap(ConcurrentHashMap map) + throws InternalException { if (map == null) return; diff --git a/src/main/java/io/kuzzle/sdk/Events/Event.java b/src/main/java/io/kuzzle/sdk/Events/Event.java new file mode 100644 index 00000000..87a89785 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Events/Event.java @@ -0,0 +1,18 @@ +package io.kuzzle.sdk.Events; + +/** + * The enum Event type. + */ +public enum Event { + disconnected, + reconnected, + connected, + error, + tokenExpired, + loginAttempt, + offlineQueuePush, + offlineQueuePop, + unhandledResponse, + networkResponseReceived, + networkStateChange +} diff --git a/src/main/java/io/kuzzle/sdk/Events/EventListener.java b/src/main/java/io/kuzzle/sdk/Events/EventListener.java index acb2b8a1..860b3a79 100644 --- a/src/main/java/io/kuzzle/sdk/Events/EventListener.java +++ b/src/main/java/io/kuzzle/sdk/Events/EventListener.java @@ -1,84 +1,5 @@ package io.kuzzle.sdk.Events; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public class EventListener { - - /** - * Set of registered callbacks. - */ - protected Set callbacks; - - /** - * Initializes a new instance of the EventListener. - */ - public EventListener() { - callbacks = ConcurrentHashMap.newKeySet(); - } - - /** - * Register a callback that takes a parameter. - * - * @param callback - * @return If successfully registered. - */ - public boolean register(final Consumer callback) { - return callbacks.add(callback); - } - - /** - * Register a callback with no parameter. - * - * @param callback - * @return If successfully registered. - */ - public boolean register(final Runnable callback) { - return callbacks.add(callback); - } - - /** - * Unregister a callback that takes a parameter. - * - * @param callback - * @return If successfully unregistered. - */ - public boolean unregister(final Consumer callback) { - return callbacks.remove(callback); - } - - /** - * Unregister a callback with no parameter. - * - * @param callback - * @return If successfully unregistered. - */ - public boolean unregister(final Runnable callback) { - return callbacks.remove(callback); - } - - /** - * Triggers every callbacks that have a parameter with the given object. - * - * @param obj An Object. - */ - public void trigger(final T obj) { - for (Object callback : callbacks) { - if (callback instanceof Consumer) { - ((Consumer) callback).accept(obj); - } - } - } - - /** - * Triggers every callbacks that doesn't have a parameter. - */ - public void trigger() { - for (Object callback : callbacks) { - if (callback instanceof Runnable) { - ((Runnable) callback).run(); - } - } - } +public interface EventListener { + void trigger(Object... args); } diff --git a/src/main/java/io/kuzzle/sdk/Events/EventManager.java b/src/main/java/io/kuzzle/sdk/Events/EventManager.java new file mode 100644 index 00000000..305129a3 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Events/EventManager.java @@ -0,0 +1,62 @@ +package io.kuzzle.sdk.Events; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class EventManager { + /** + * List of listener. + */ + protected ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); + + /** + * Register a listener. + * + * @param event + * @param listener + * @return If successfully registered. + */ + public synchronized boolean register(final Event event, + final EventListener listener) { + listeners.computeIfAbsent(event, l -> new ArrayList<>()); + + List eventListener = listeners.get(event); + if (eventListener != null) { + return listeners.get(event).add(listener); + } + return false; + } + + /** + * Unregister a listener. + * + * @param event + * @param listener + * @return If successfully unregistered. + */ + public synchronized boolean unregister(final Event event, + final EventListener listener) { + if (!listeners.containsKey(event)) { + return false; + } + return listeners.get(event).remove(listener); + } + + /** + * Triggers every listener of the same event type. + * + * @param args + * An array of Object. + */ + public void trigger(final Event event, Object... args) { + List eventListener = listeners.get(event); + if (eventListener != null) { + for (final EventListener listener : eventListener) { + if (listener != null) { + listener.trigger(args); + } + } + } + } +} diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java b/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java index 8b800868..8bcf73a1 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/ApiErrorException.java @@ -6,6 +6,11 @@ * Passed to async tasks when an API request returns an error. */ public class ApiErrorException extends KuzzleException { + /** + * + */ + private static final long serialVersionUID = 666379398727075901L; + /** * Kuzzle API stack trace */ diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java b/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java index dbd2bbb3..89804fa3 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/ConnectionLostException.java @@ -5,6 +5,11 @@ * waiting for a result. */ public class ConnectionLostException extends KuzzleException { + /** + * + */ + private static final long serialVersionUID = 1046624032334173580L; + /** * Initializes a new instance of the ConnectionLostException. */ diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java b/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java index 7791fa64..a5296651 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/InternalException.java @@ -5,6 +5,11 @@ */ public class InternalException extends KuzzleException { + /** + * + */ + private static final long serialVersionUID = -7004783427215842992L; + /** * Initializes a new instance of the InternalException */ diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java index d905b5d7..8c036c40 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleException.java @@ -5,6 +5,10 @@ */ public class KuzzleException extends Exception { + /** + * + */ + private static final long serialVersionUID = 4446507573441857492L; /** * Kuzzle API error code. */ @@ -13,8 +17,10 @@ public class KuzzleException extends Exception { /** * Initializes a new instance of the KuzzleException. * - * @param message Message. - * @param status Status. + * @param message + * Message. + * @param status + * Status. */ protected KuzzleException(String message, int status) { super(message); diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java index 88872b11..c490c9ec 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java @@ -1,9 +1,13 @@ package io.kuzzle.sdk.Exceptions; public enum KuzzleExceptionCode { - MISSING_REQUESTID(0, "Missing field requestId"), MSSING_QUERY(400, "You must provide a query"), - NOT_CONNECTED(500, "Not connected."), CONNECTION_LOST(500, "Connection lost"), - WRONG_VOLATILE_TYPE(400, "Volatile data must be a ConcurrentHashMap"); + MISSING_REQUESTID(0, "Missing field requestId"), + MSSING_QUERY(400, "You must provide a query"), + NOT_CONNECTED(500, "Not connected."), + CONNECTION_LOST(500, "Connection lost"), + WRONG_VOLATILE_TYPE( + 400, + "Volatile data must be a ConcurrentHashMap"); private final int code; private final String message; diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java b/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java index 1f695ccd..1d85a3e7 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/NotConnectedException.java @@ -5,6 +5,11 @@ */ public class NotConnectedException extends KuzzleException { + /** + * + */ + private static final long serialVersionUID = 1961824705891656436L; + /** * Initializes a new instance of the NotConnectedException. */ diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index b47eeb8d..8e10353c 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -2,29 +2,23 @@ import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.API.Controllers.AuthController; import io.kuzzle.sdk.CoreClasses.Task; -import io.kuzzle.sdk.Events.EventListener; import io.kuzzle.sdk.Exceptions.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.CoreClasses.Responses.*; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Events.EventManager; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import io.kuzzle.sdk.CoreClasses.Responses.*; - -import static io.kuzzle.sdk.Helpers.Default.defaultValue; - -public class Kuzzle { - - protected EventListener tokenExpiredEvent; - protected EventListener unhandledResponseEvent; +public class Kuzzle extends EventManager { protected final AbstractProtocol networkProtocol; public final String version; @@ -37,20 +31,20 @@ public class Kuzzle { protected AtomicReference authenticationToken; /** - * The maximum amount of elements that the queue can contains. If set to -1, the - * size is unlimited. + * The maximum amount of elements that the queue can contains. If set to -1, + * the size is unlimited. */ protected AtomicInteger maxQueueSize; /** - * The minimum duration of a Token before being automatically refreshed. If set - * to -1 the SDK does not refresh the token automatically. + * The minimum duration of a Token before being automatically refreshed. If + * set to -1 the SDK does not refresh the token automatically. */ protected AtomicInteger minTokenDuration; /** - * The minimum duration of a Token after refresh. If set to -1 the SDK does not - * refresh the token automatically. + * The minimum duration of a Token after refresh. If set to -1 the SDK does + * not refresh the token automatically. */ protected AtomicInteger refreshedTokenDuration; @@ -64,43 +58,52 @@ public class Kuzzle { /** * Initialize a new instance of Kuzzle * - * @param networkProtocol The network protocol + * @param networkProtocol + * The network protocol * @throws IllegalArgumentException */ - public Kuzzle(AbstractProtocol networkProtocol) throws IllegalArgumentException { + public Kuzzle(final AbstractProtocol networkProtocol) + throws IllegalArgumentException { this(networkProtocol, new KuzzleOptions()); } + public AuthController getAuthController() { + return new AuthController(this); + } + /** * Initialize a new instance of Kuzzle * - * @param networkProtocol The network protocol - * @param options Kuzzle options + * @param networkProtocol + * The network protocol + * @param options + * Kuzzle options * @throws IllegalArgumentException */ - public Kuzzle(AbstractProtocol networkProtocol, final KuzzleOptions options) throws IllegalArgumentException { - + public Kuzzle(final AbstractProtocol networkProtocol, + final KuzzleOptions options) throws IllegalArgumentException { if (networkProtocol == null) { throw new IllegalArgumentException("networkProtocol can't be null"); } - KuzzleOptions kOptions = options != null ? options : new KuzzleOptions(); + final KuzzleOptions kOptions = options != null ? options + : new KuzzleOptions(); this.networkProtocol = networkProtocol; - this.networkProtocol.registerResponseEvent(this::onResponseReceived); - this.networkProtocol.registerStateChangeEvent(this::onStateChanged); + this.networkProtocol + .register(Event.networkResponseReceived, this::onResponseReceived); + this.networkProtocol + .register(Event.networkStateChange, this::onStateChanged); this.maxQueueSize = new AtomicInteger(kOptions.getMaxQueueSize()); this.minTokenDuration = new AtomicInteger(kOptions.getMinTokenDuration()); - this.refreshedTokenDuration = new AtomicInteger(kOptions.getRefreshedTokenDuration()); + this.refreshedTokenDuration = new AtomicInteger( + kOptions.getRefreshedTokenDuration()); this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); - this.version = "3.0.0"; + this.version = "3"; this.instanceId = UUID.randomUUID().toString(); this.sdkName = "java@" + version; - - this.tokenExpiredEvent = new EventListener(); - this.unhandledResponseEvent = new EventListener<>(); } /** @@ -122,25 +125,26 @@ public void disconnect() { /** * Handles the ResponseReceivedEvent from the network protocol * - * @param payload Raw API Response + * @param payload + * Raw API Response */ - protected void onResponseReceived(String payload) { + protected void onResponseReceived(final Object... payload) { - Response response = new Response(); + final Response response = new Response(); try { - response.fromMap(JsonSerializer.deserialize(payload)); - } catch (InternalException e) { + response.fromMap(JsonSerializer.deserialize(payload[0].toString())); + } catch (final InternalException e) { e.printStackTrace(); return; } if (response.room == null || !requests.containsKey(response.room)) { - unhandledResponseEvent.trigger(response); + super.trigger(Event.unhandledResponse, response); return; } if (response.error == null) { - Task task = requests.get(response.requestId); + final Task task = requests.get(response.requestId); if (task != null) { task.trigger(response); @@ -150,82 +154,39 @@ protected void onResponseReceived(String payload) { return; } - if (response.error.id == null || !response.error.id.equals("security.token.expired")) { - Task task = requests.get(response.requestId); + if (response.error.id == null + || !response.error.id.equals("security.token.expired")) { + final Task task = requests.get(response.requestId); if (task != null) { task.setException(new ApiErrorException(response)); } return; } - tokenExpiredEvent.trigger(); + super.trigger(Event.tokenExpired); } - protected void onStateChanged(ProtocolState state) { + protected void onStateChanged(final Object... args) { // If not connected anymore: close tasks and clean up the requests buffer - if (state == ProtocolState.CLOSE) { - for (Task task : requests.values()) { + if ((ProtocolState) args[0] == ProtocolState.CLOSE) { + for (final Task task : requests.values()) { task.setException(new ConnectionLostException()); } requests.clear(); } } - /** - * Registers a callback to be called when the token expires - * - * @param callback A callback - * @return true if success - */ - public boolean registerTokenExpiredEvent(Runnable callback) { - return tokenExpiredEvent.register(callback); - } - - /** - * Unregisters a previously registered callback for the TokenExpired event - * - * @param callback A callback - * @return true if success - */ - public boolean unregisterTokenExpiredEvent(Runnable callback) { - return tokenExpiredEvent.unregister(callback); - } - - /** - * Registers a callback to be called when a response is unhandled - * - * @param callback A callback - * @return true if success - */ - public boolean registerUnhandledResponseEvent(Consumer callback) { - return unhandledResponseEvent.register(callback); - } - - /** - * @param callback Unregisters a previously registered callback for the - * UnhandledResponse event - * @return true if success - */ - public boolean unregisterUnhandledResponseEvent(Consumer callback) { - return unhandledResponseEvent.unregister(callback); - } - - /** - * Triggers the TokenExpired event - */ - public void dispatchTokenExpired() { - tokenExpiredEvent.trigger(); - } - /** * Sends an API request to Kuzzle and returns the corresponding API * - * @param query Kuzzle API query + * @param query + * Kuzzle API query * @return A CompletableFuture * @throws InternalException * @throws NotConnectedException */ - public CompletableFuture query(ConcurrentHashMap query) + public CompletableFuture query( + final ConcurrentHashMap query) throws InternalException, NotConnectedException { if (query == null) { throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); @@ -235,7 +196,7 @@ public CompletableFuture query(ConcurrentHashMap query throw new NotConnectedException(); } - KuzzleMap queryMap = KuzzleMap.from(query); + final KuzzleMap queryMap = KuzzleMap.from(query); if (queryMap.contains("waitForRefresh")) { if (queryMap.optBoolean("waitForRefresh", false).booleanValue()) { @@ -245,10 +206,10 @@ public CompletableFuture query(ConcurrentHashMap query } if (authenticationToken != null) { - queryMap.put("jwt", authenticationToken); + queryMap.put("jwt", authenticationToken.toString()); } - String requestId = UUID.randomUUID().toString(); + final String requestId = UUID.randomUUID().toString(); queryMap.put("requestId", requestId); @@ -258,13 +219,11 @@ public CompletableFuture query(ConcurrentHashMap query throw new InternalException(KuzzleExceptionCode.WRONG_VOLATILE_TYPE); } - queryMap.getMap("volatile").put("sdkVersion", version); - queryMap.getMap("volatile").put("sdkInstanceId", instanceId); queryMap.getMap("volatile").put("sdkName", sdkName); - Task task = new Task<>(); + final Task task = new Task<>(); requests.put(requestId, task); if (networkProtocol.getState() == ProtocolState.OPEN) { @@ -284,9 +243,13 @@ public String getAuthenticationToken() { /** * Set the authentication token * - * @param token Authentication token + * @param token + * Authentication token */ - public void setAuthenticationToken(String token) { + public void setAuthenticationToken(final String token) { + if (authenticationToken == null) { + authenticationToken = new AtomicReference<>(); + } authenticationToken.set(token); } } diff --git a/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java index 21d6999f..59376c6b 100644 --- a/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java @@ -8,20 +8,20 @@ public class KuzzleOptions { /** - * The maximum amount of elements that the queue can contains. If set to -1, the - * size is unlimited. + * The maximum amount of elements that the queue can contains. If set to -1, + * the size is unlimited. */ private int maxQueueSize = -1; /** - * The minimum duration of a Token before being automatically refreshed. If set - * to -1 the SDK does not refresh the token automatically. + * The minimum duration of a Token before being automatically refreshed. If + * set to -1 the SDK does not refresh the token automatically. */ private int minTokenDuration = 3_600_000; /** - * The minimum duration of a Token after refresh. If set to -1 the SDK does not - * refresh the token automatically. + * The minimum duration of a Token after refresh. If set to -1 the SDK does + * not refresh the token automatically. */ private int refreshedTokenDuration = 3_600_000; @@ -30,7 +30,8 @@ public class KuzzleOptions { */ private int maxRequestDelay = 1000; - private Predicate> filter = (ConcurrentHashMap obj) -> true; + private Predicate> queueFilter = ( + ConcurrentHashMap obj) -> true; /** * Initialize a new KuzzleOptions instance. @@ -50,46 +51,47 @@ public KuzzleOptions(KuzzleOptions options) { this.maxRequestDelay = options.maxRequestDelay; - this.filter = options.filter; + this.queueFilter = options.queueFilter; } /** - * @return The maximum amount of elements that the queue can contains. If set to - * -1, the size is unlimited. + * @return The maximum amount of elements that the queue can contains. If set + * to -1, the size is unlimited. */ public int getMaxQueueSize() { return maxQueueSize; } /** - * Set the maximum amount of elements that the queue can contains. If set to -1, - * the size is unlimited. + * Set the maximum amount of elements that the queue can contains. If set to + * -1, the size is unlimited. * * @param maxQueueSize * @return This KuzzleOptions instance */ - public KuzzleOptions withMaxQueueSize(int maxQueueSize) { + public KuzzleOptions setMaxQueueSize(int maxQueueSize) { this.maxQueueSize = maxQueueSize < 0 ? -1 : maxQueueSize; return this; } /** - * @return The minimum duration of a Token before being automatically refreshed. - * If set to -1 the SDK does not refresh the token automatically. + * @return The minimum duration of a Token before being automatically + * refreshed. If set to -1 the SDK does not refresh the token + * automatically. */ public int getMinTokenDuration() { return minTokenDuration; } /** - * Set the minimum duration of a Token before being automatically refreshed. If - * set to -1 the SDK does not refresh the token automatically. + * Set the minimum duration of a Token before being automatically refreshed. + * If set to -1 the SDK does not refresh the token automatically. * * @param minTokenDuration * @return This KuzzleOptions instance */ - public KuzzleOptions withMinTokenDuration(int minTokenDuration) { + public KuzzleOptions setMinTokenDuration(int minTokenDuration) { this.minTokenDuration = minTokenDuration < 0 ? -1 : minTokenDuration; return this; @@ -104,14 +106,15 @@ public int getRefreshedTokenDuration() { } /** - * Set the minimum duration of a Token after refresh. If set to -1 the SDK does - * not refresh the token automatically. + * Set the minimum duration of a Token after refresh. If set to -1 the SDK + * does not refresh the token automatically. * * @param refreshedTokenDuration * @return This KuzzleOptions instance */ - public KuzzleOptions withRefreshedTokenDuration(int refreshedTokenDuration) { - this.refreshedTokenDuration = refreshedTokenDuration < 0 ? -1 : refreshedTokenDuration; + public KuzzleOptions setRefreshedTokenDuration(int refreshedTokenDuration) { + this.refreshedTokenDuration = refreshedTokenDuration < 0 ? -1 + : refreshedTokenDuration; return this; } @@ -129,17 +132,19 @@ public int getMaxRequestDelay() { * @param maxRequestDelay * @return This KuzzleOptions instance */ - public KuzzleOptions withMaxRequestDelay(int maxRequestDelay) { + public KuzzleOptions setMaxRequestDelay(int maxRequestDelay) { this.maxRequestDelay = maxRequestDelay; return this; } - public Predicate> getFilter() { - return filter; + public Predicate> getQueueFilter() { + return queueFilter; } - public KuzzleOptions withFilter(Predicate> filter) { - this.filter = defaultValue(filter, (ConcurrentHashMap obj) -> true); + public KuzzleOptions setQueueFilter( + Predicate> filter) { + this.queueFilter = defaultValue(filter, + (ConcurrentHashMap obj) -> true); return this; } } diff --git a/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java index 0c5df6d2..4ebf007e 100644 --- a/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java @@ -1,7 +1,5 @@ package io.kuzzle.sdk.Options.Protocol; -import io.kuzzle.sdk.Options.KuzzleOptions; - public class WebSocketOptions { /** @@ -56,7 +54,7 @@ public int getPort() { * @param port * @return This WebSocketOptions instance. */ - public WebSocketOptions withPort(int port) { + public WebSocketOptions setPort(int port) { this.port = port >= 0 ? port : 7512; return this; } @@ -74,7 +72,7 @@ public boolean isSsl() { * @param ssl * @return This WebSocketOptions instance. */ - public WebSocketOptions withSsl(boolean ssl) { + public WebSocketOptions setSsl(boolean ssl) { this.ssl = ssl; return this; } @@ -92,7 +90,7 @@ public int getConnectionTimeout() { * @param connectionTimeout * @return This WebSocketOptions instance. */ - public WebSocketOptions withConnectionTimeout(int connectionTimeout) { + public WebSocketOptions setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout < 0 ? -1 : connectionTimeout; return this; } @@ -110,7 +108,7 @@ public boolean isAutoReconnect() { * @param autoReconnect * @return This WebSocketOptions instance. */ - public WebSocketOptions withAutoReconnect(boolean autoReconnect) { + public WebSocketOptions setAutoReconnect(boolean autoReconnect) { this.autoReconnect = autoReconnect; return this; } diff --git a/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java b/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java index d50127aa..49711726 100644 --- a/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java +++ b/src/main/java/io/kuzzle/sdk/Protocol/AbstractProtocol.java @@ -1,18 +1,9 @@ package io.kuzzle.sdk.Protocol; -import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Events.EventManager; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -public abstract class AbstractProtocol { - protected EventListener stateChanged; - protected EventListener messageReceived; - - public AbstractProtocol() { - stateChanged = new EventListener<>(); - messageReceived = new EventListener<>(); - } +public abstract class AbstractProtocol extends EventManager { /** * Current connection state. * @@ -38,50 +29,4 @@ public AbstractProtocol() { * @param payload */ public abstract void send(ConcurrentHashMap payload); - - /** - * Register to the Response event - */ - public boolean registerResponseEvent(Consumer callback) { - return messageReceived.register(callback); - } - - /** - * Unregister from the Response event - */ - public boolean unregisterResponseEvent(Consumer callback) { - return messageReceived.unregister(callback); - } - - /** - * Register to the StateChange event - */ - public boolean registerStateChangeEvent(Consumer callback) { - return stateChanged.register(callback); - } - - /** - * Unregister from the StateChange event - */ - public boolean unregisterStateChangeEvent(Consumer callback) { - return stateChanged.unregister(callback); - } - - /** - * Dispatch a state changed event. - * - * @param state The ProtocolState. - */ - protected void dispatchStateChangeEvent(ProtocolState state) { - stateChanged.trigger(state); - } - - /** - * Dispatch a message received from a Kuzzle server. - * - * @param message Kuzzle API response. - */ - protected void dispatchResponseEvent(String message) { - messageReceived.trigger(message); - } } diff --git a/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java index b7690917..dca6e8ef 100644 --- a/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java +++ b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java @@ -1,15 +1,16 @@ package io.kuzzle.sdk.Protocol; import com.neovisionaries.ws.client.WebSocketAdapter; +import com.neovisionaries.ws.client.WebSocketException; import com.neovisionaries.ws.client.WebSocketFactory; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; +import io.kuzzle.sdk.Events.Event; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.concurrent.*; public class WebSocket extends AbstractProtocol { @@ -30,42 +31,50 @@ public ProtocolState getState() { public WebSocket(URI uri) throws Exception { WebSocketOptions options = new WebSocketOptions(); if (uri.getPort() > -1) { - options.withPort(uri.getPort()); + options.setPort(uri.getPort()); } if (uri.getHost() == null || uri.getHost().isEmpty()) { throw new URISyntaxException("Missing host", "Could not find host part"); } if (uri.getScheme() != null) { - options.withSsl(uri.getScheme().equals("wss")); + options.setSsl(uri.getScheme().equals("wss")); } - WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) : new WebSocketOptions(); + WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) + : new WebSocketOptions(); ssl = wsOptions.isSsl(); port = wsOptions.getPort(); connectionTimeout = wsOptions.getConnectionTimeout(); - this.uri = new URI((ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); + this.uri = new URI( + (ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); this.queue = new LinkedBlockingDeque<>(); } - public WebSocket(URI uri, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { + public WebSocket(URI uri, WebSocketOptions options) + throws URISyntaxException, IllegalArgumentException { this(uri.getHost(), options); } - public WebSocket(String host) throws URISyntaxException, IllegalArgumentException { + public WebSocket(String host) + throws IllegalArgumentException, URISyntaxException { this(host, new WebSocketOptions()); } /** - * @param host Kuzzle host address - * @param options WebSocket options + * @param host + * Kuzzle host address + * @param options + * WebSocket options * @throws URISyntaxException * @throws IllegalArgumentException */ - public WebSocket(String host, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { + public WebSocket(String host, WebSocketOptions options) + throws URISyntaxException, IllegalArgumentException { super(); - WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) : new WebSocketOptions(); + WebSocketOptions wsOptions = options != null ? new WebSocketOptions(options) + : new WebSocketOptions(); ssl = wsOptions.isSsl(); port = wsOptions.getPort(); @@ -83,7 +92,8 @@ public void send(ConcurrentHashMap payload) { queue.add(payload); } - protected com.neovisionaries.ws.client.WebSocket createClientSocket() throws IOException { + protected com.neovisionaries.ws.client.WebSocket createClientSocket() + throws IOException { WebSocketFactory wsFactory = new WebSocketFactory(); if (connectionTimeout > -1) { @@ -100,11 +110,13 @@ protected com.neovisionaries.ws.client.WebSocket createClientSocket() throws IOE /** * Connects to a Kuzzle server. - * + * + * @throws IOException + * @throws WebSocketException * @throws Exception */ @Override - public void connect() throws Exception { + public void connect() throws IOException, WebSocketException { if (socket != null) { return; } @@ -113,14 +125,16 @@ public void connect() throws Exception { socket.connect(); state = ProtocolState.OPEN; - dispatchStateChangeEvent(state); + super.trigger(Event.networkStateChange, state); Dequeue(); socket.addListener(new WebSocketAdapter() { @Override - public void onTextMessage(com.neovisionaries.ws.client.WebSocket websocket, String text) throws Exception { + public void onTextMessage( + com.neovisionaries.ws.client.WebSocket websocket, String text) + throws Exception { super.onTextMessage(websocket, text); - dispatchResponseEvent(text); + WebSocket.super.trigger(Event.networkResponseReceived, text); } }); } @@ -138,7 +152,7 @@ protected void CloseState() { socket.disconnect(); state = ProtocolState.CLOSE; socket = null; - dispatchStateChangeEvent(state); + super.trigger(Event.networkStateChange, state); } } diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java index 8386f7f8..cb91e79b 100644 --- a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.*; public class TaskTests { - @Test public void constructorTest() { TestableTask task = new TestableTask<>(); diff --git a/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java b/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java deleted file mode 100644 index 441de60c..00000000 --- a/src/test/java/io/kuzzle/test/EventsTest/EventListenerTests.java +++ /dev/null @@ -1,142 +0,0 @@ -package io.kuzzle.test.EventsTest; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class EventListenerTests { - - @Test - public void registerRunnableTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.register(() -> { - }); - - verify(eventListener.mockedCallbacks, times(1)).add(any(Runnable.class)); - } - - @Test - public void unregisterRunnableTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.unregister(() -> { - }); - - verify(eventListener.mockedCallbacks, times(1)).remove(any(Runnable.class)); - } - - @Test - public void registerConsumerTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.register((obj) -> { - }); - - verify(eventListener.mockedCallbacks, times(1)).add(any(Consumer.class)); - } - - @Test - public void unregisterConsumerTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - eventListener.applyMock(); - - eventListener.unregister((obj) -> { - }); - - verify(eventListener.mockedCallbacks, times(1)).remove(any(Consumer.class)); - } - - @Test - public void registerDuplicateTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - - Runnable runnable1 = () -> { - }; - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(runnable1); - eventListener.register(() -> { - }); - - Assert.assertEquals(2, eventListener.getCallbacks().size()); - } - - @Test - public void triggerRunnableTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - - AtomicBoolean success = new AtomicBoolean(false); - eventListener.register(() -> success.set(true)); - - Assert.assertFalse(success.get()); - - eventListener.trigger(); - - Assert.assertTrue(success.get()); - } - - @Test - public void triggerConsumerTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - - AtomicBoolean success = new AtomicBoolean(false); - eventListener.register((str) -> success.set(str.equals("foobar"))); - - Assert.assertFalse(success.get()); - - eventListener.trigger("foobar"); - - Assert.assertTrue(success.get()); - } - - @Test - public void triggerOnlyConsumerTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - - AtomicBoolean consumerSuccess = new AtomicBoolean(false); - AtomicBoolean runnableSuccess = new AtomicBoolean(false); - - eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); - eventListener.register(() -> runnableSuccess.set(true)); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - - eventListener.trigger("foobar"); - - Assert.assertTrue(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - } - - @Test - public void triggerOnlyRunnableTest() { - TestableEventListener eventListener = new TestableEventListener<>(); - - AtomicBoolean consumerSuccess = new AtomicBoolean(false); - AtomicBoolean runnableSuccess = new AtomicBoolean(false); - - eventListener.register((str) -> consumerSuccess.set(str.equals("foobar"))); - eventListener.register(() -> runnableSuccess.set(true)); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertFalse(runnableSuccess.get()); - - eventListener.trigger(); - - Assert.assertFalse(consumerSuccess.get()); - Assert.assertTrue(runnableSuccess.get()); - } - -} diff --git a/src/test/java/io/kuzzle/test/EventsTest/EventManagerTests.java b/src/test/java/io/kuzzle/test/EventsTest/EventManagerTests.java new file mode 100644 index 00000000..02bc151b --- /dev/null +++ b/src/test/java/io/kuzzle/test/EventsTest/EventManagerTests.java @@ -0,0 +1,84 @@ +package io.kuzzle.test.EventsTest; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Matchers; + +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Events.EventListener; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class EventManagerTests { + + @Test + public void registerRunnableTest() { + MockedEventManager eventManager = new MockedEventManager(); + + eventManager.register(Event.connected, (Object... args) -> { + }); + + Assert.assertEquals(1, eventManager.getListeners().size()); + } + + @Test + public void unregisterRunnableTest() { + MockedEventManager eventManager = new MockedEventManager(); + EventListener listener = (Object... args) -> { + }; + + eventManager.register(Event.connected, listener); + eventManager.unregister(Event.connected, listener); + + Assert.assertEquals(0, eventManager.getListeners().get(Event.connected).size()); + } + + @Test + public void registerDuplicateTest() { + MockedEventManager eventManager = new MockedEventManager(); + + EventListener listener = (Object... args) -> { + }; + eventManager.register(Event.connected, listener); + eventManager.register(Event.connected, listener); + eventManager.register(Event.connected, listener); + eventManager.register(Event.connected, listener); + eventManager.register(Event.connected, listener); + eventManager.register(Event.connected, (Object... args) -> { + }); + + Assert.assertEquals(6, eventManager.getListeners().get(Event.connected).size()); + } + + @Test + public void triggerRunnableTest() { + MockedEventManager eventManager = new MockedEventManager(); + + AtomicBoolean success = new AtomicBoolean(false); + eventManager.register(Event.connected, (Object... args) -> success.set(true)); + + Assert.assertFalse(success.get()); + + eventManager.trigger(Event.connected); + + Assert.assertTrue(success.get()); + } + + @Test + public void triggerListenerTest() { + MockedEventManager eventManager = new MockedEventManager(); + + AtomicBoolean success = new AtomicBoolean(false); + eventManager.register(Event.connected, (Object... args) -> success.set(args[0].toString().equals("foobar"))); + + Assert.assertFalse(success.get()); + + eventManager.trigger(Event.connected, "foobar"); + + Assert.assertTrue(success.get()); + } +} diff --git a/src/test/java/io/kuzzle/test/EventsTest/MockedEventManager.java b/src/test/java/io/kuzzle/test/EventsTest/MockedEventManager.java new file mode 100644 index 00000000..07aac053 --- /dev/null +++ b/src/test/java/io/kuzzle/test/EventsTest/MockedEventManager.java @@ -0,0 +1,19 @@ + +package io.kuzzle.test.EventsTest; + +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Events.EventListener; +import io.kuzzle.sdk.Events.EventManager; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class MockedEventManager extends EventManager { + public MockedEventManager() { + super(); + } + + public ConcurrentHashMap> getListeners() { + return super.listeners; + } +} \ No newline at end of file diff --git a/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java b/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java deleted file mode 100644 index 42c48d5c..00000000 --- a/src/test/java/io/kuzzle/test/EventsTest/TestableEventListener.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.kuzzle.test.EventsTest; - -import io.kuzzle.sdk.Events.EventListener; - -import java.util.Set; - -import static org.mockito.Mockito.mock; - -public class TestableEventListener extends EventListener { - public Set mockedCallbacks = mock(Set.class); - - public TestableEventListener() { - super(); - } - - public void applyMock() { - super.callbacks = mockedCallbacks; - } - - public Set getCallbacks() { - return super.callbacks; - } -} diff --git a/src/test/java/io/kuzzle/test/KuzzleTests.java b/src/test/java/io/kuzzle/test/KuzzleTests.java index 1c498031..4025e786 100644 --- a/src/test/java/io/kuzzle/test/KuzzleTests.java +++ b/src/test/java/io/kuzzle/test/KuzzleTests.java @@ -2,6 +2,7 @@ import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Task; +import io.kuzzle.sdk.Events.Event; import io.kuzzle.sdk.Events.EventListener; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; @@ -17,6 +18,8 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import static org.mockito.Mockito.mock; + import java.net.URISyntaxException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -24,15 +27,11 @@ public class KuzzleTests { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - private EventListener tokenExpiredEventListener = Mockito.mock(EventListener.class); - private EventListener unhandledResponseEventListener = Mockito.mock(EventListener.class); private TestableKuzzle kuzzle; @Before public void setup() throws URISyntaxException { kuzzle = new TestableKuzzle(networkProtocol); - kuzzle.setTokenExpiredEventListener(tokenExpiredEventListener); - kuzzle.setUnhandledResponseEventListener(unhandledResponseEventListener); } @Test @@ -47,20 +46,6 @@ public void disconnect() throws Exception { Mockito.verify(networkProtocol, Mockito.times(1)).disconnect(); } - @Test - public void registerTokenExpiredEvent() throws Exception { - kuzzle.registerTokenExpiredEvent(() -> { - }); - Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).register(Matchers.any(Runnable.class)); - } - - @Test - public void unregisterTokenExpiredEvent() throws Exception { - kuzzle.unregisterTokenExpiredEvent(() -> { - }); - Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).unregister(Matchers.any(Runnable.class)); - } - @Test public void onStateChanged() { ConcurrentHashMap> requests = kuzzle.getRequests(); @@ -102,6 +87,7 @@ public void queryShouldThrowWhenVolatileIsNotConcurrentHashMap() throws NotConne @Test public void onResponseReceivedAndTokenIsExpired() { ConcurrentHashMap> requests = kuzzle.getRequests(); + EventListener listener = mock(EventListener.class); Response response = new Response(); response.requestId = "foobar"; @@ -114,16 +100,17 @@ public void onResponseReceivedAndTokenIsExpired() { requests.put("room-id", task); + kuzzle.register(Event.tokenExpired, listener); kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); - Mockito.verify(tokenExpiredEventListener, Mockito.times(1)).trigger(); + Mockito.verify(listener, Mockito.times(1)).trigger(); } @Test public void onResponseReceivedAndResponseIsUnhandled() { ConcurrentHashMap> requests = kuzzle.getRequests(); + EventListener listener = mock(EventListener.class); - AtomicBoolean success = new AtomicBoolean(false); Response response = new Response(); response.requestId = "foobar"; @@ -131,9 +118,10 @@ public void onResponseReceivedAndResponseIsUnhandled() { requests.put("request-id", task); + kuzzle.register(Event.unhandledResponse, listener); kuzzle.onResponseReceived(JsonSerializer.serialize(response.toMap())); - Mockito.verify(unhandledResponseEventListener, Mockito.times(1)).trigger(Matchers.any(Response.class)); + Mockito.verify(listener, Mockito.times(1)).trigger(Matchers.any(Response.class)); } } diff --git a/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java b/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java index c6c5db13..47bef2e5 100644 --- a/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java +++ b/src/test/java/io/kuzzle/test/ProtocolTest/TestableWebSocket.java @@ -1,5 +1,6 @@ package io.kuzzle.test.ProtocolTest; +import io.kuzzle.sdk.Events.Event; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.ProtocolState; import io.kuzzle.sdk.Protocol.WebSocket; @@ -18,7 +19,7 @@ public TestableWebSocket(String host) throws URISyntaxException, IllegalArgument public TestableWebSocket(String host, WebSocketOptions options) throws URISyntaxException, IllegalArgumentException { super(host, options); - super.stateChanged.register((ProtocolState state) -> { + super.register(Event.networkStateChange, (Object... args) -> { stateChangedCount += 1; lastStateDispatched = state; }); diff --git a/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java index d5f20dc9..e0b25317 100644 --- a/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java +++ b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java @@ -19,7 +19,7 @@ public class WebSocketTests { @Before public void setup() throws URISyntaxException { host = "foo"; - options = new WebSocketOptions().withPort(1234).withSsl(true); + options = new WebSocketOptions().setPort(1234).setSsl(true); socket = new TestableWebSocket(host, options); } diff --git a/src/test/java/io/kuzzle/test/TestableKuzzle.java b/src/test/java/io/kuzzle/test/TestableKuzzle.java index d8a9d579..3418edf8 100644 --- a/src/test/java/io/kuzzle/test/TestableKuzzle.java +++ b/src/test/java/io/kuzzle/test/TestableKuzzle.java @@ -21,22 +21,6 @@ public TestableKuzzle(AbstractProtocol networkProtocol, KuzzleOptions options) t super(networkProtocol, options); } - public void setTokenExpiredEventListener(EventListener eventListener) { - super.tokenExpiredEvent = eventListener; - } - - public EventListener getTokenExpiredEventListener() { - return super.tokenExpiredEvent; - } - - public void setUnhandledResponseEventListener(EventListener eventListener) { - super.unhandledResponseEvent = eventListener; - } - - public EventListener getUnhandledResponseEventListener() { - return super.unhandledResponseEvent; - } - public void onStateChanged(ProtocolState state) { super.onStateChanged(state); } From 834984d7dd97a7d6539cc044dc3c527f6e05ebd9 Mon Sep 17 00:00:00 2001 From: Aschen Date: Wed, 29 Jan 2020 11:33:01 +0100 Subject: [PATCH 018/134] Add doc dev --- .travis.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.travis.yml b/.travis.yml index a208037d..9af179f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,45 @@ jobs: all_branches: true after_deploy: - npm run doc-cloudfront + + - stage: Deployment Doc Dev + name: Deploy next-docs.kuzzle.io + if: type = push AND branch =~ /^[0-9]+-dev$/ + language: node_js + node_js: 10 + env: + - BRANCH=dev + - NODE_ENV=production + - S3_BUCKET=docs-next.kuzzle.io + - CLOUDFRONT_DISTRIBUTION_ID=E2ZCCEK9GRB49U + - AWS_DEFAULT_REGION=us-west-2 + + addons: + apt: + update: true + packages: + - python + - python-pip + + install: + - pip install awscli --upgrade --user + - npm ci + + script: + - npm run doc-prepare + - npm run doc-build + + deploy: + provider: script + script: + - npm run doc-upload + skip_cleanup: true + on: + all_branches: true + + after_deploy: + - npm run doc-cloudfront + - stage: Deployment Doc Prod name: Deploy docs.kuzzle.io if: type = push AND branch =~ /^master|[0-9]+-stable$/ @@ -82,6 +121,7 @@ jobs: all_branches: true after_deploy: - npm run doc-cloudfront + - stage: Builds name: Build SDK Java language: java @@ -101,11 +141,13 @@ jobs: - gradle assemble script: - gradle build + stages: - name: Unit Tests if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ - name: Builds if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ + notifications: slack: rooms: From 7d9c067606c54a3f3a2379e7fffeb47bedb2ce74 Mon Sep 17 00:00:00 2001 From: Aschen Date: Wed, 29 Jan 2020 11:33:44 +0100 Subject: [PATCH 019/134] Add doc dev --- .travis.yml | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9af179f7..0432d4b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,42 +22,12 @@ jobs: script: - gem install typhoeus - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links - - stage: Deployment Doc Dev - name: Deploy next-docs.kuzzle.io - if: type = push AND branch =~ .*-dev - language: node_js - node_js: 12 - env: - - NODE_ENV=production - - S3_BUCKET=docs-next.kuzzle.io - - CLOUDFRONT_DISTRIBUTION_ID=E2ZCCEK9GRB49U - - AWS_DEFAULT_REGION=us-west-2 - addons: - apt: - packages: - - python - - python-pip - install: - - pip install awscli --upgrade --user - - npm ci - script: - - npm run doc-prepare - - npm run doc-build - deploy: - provider: script - script: - - npm run doc-upload - skip_cleanup: true - on: - all_branches: true - after_deploy: - - npm run doc-cloudfront - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io if: type = push AND branch =~ /^[0-9]+-dev$/ language: node_js - node_js: 10 + node_js: 12 env: - BRANCH=dev - NODE_ENV=production From 7f0ea3fc1b7093cf4ee66f0a2f8980a4a74c8c5f Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 6 Feb 2020 18:11:42 +0100 Subject: [PATCH 020/134] add document:create --- .../API/Controllers/DocumentController.java | 53 ++++++++++++++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 7 +- .../DocumentTest/DocumentTest.java | 71 +++++++++++++++++++ src/test/java/io/kuzzle/test/KuzzleTests.java | 1 - 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java new file mode 100644 index 00000000..4446ee20 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -0,0 +1,53 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class DocumentController extends BaseController { + public DocumentController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @param _id + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final String _id, + final ConcurrentHashMap options) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "create") + .put("_id", _id) + .put("body", document) + .put("options", options); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 8e10353c..27ee0370 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -3,6 +3,7 @@ import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.API.Controllers.AuthController; +import io.kuzzle.sdk.API.Controllers.DocumentController; import io.kuzzle.sdk.CoreClasses.Task; import io.kuzzle.sdk.Exceptions.*; import io.kuzzle.sdk.Options.KuzzleOptions; @@ -71,6 +72,10 @@ public AuthController getAuthController() { return new AuthController(this); } + public DocumentController getDocumentController() { + return new DocumentController(this); + } + /** * Initialize a new instance of Kuzzle * @@ -192,10 +197,10 @@ public CompletableFuture query( throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); } + if (networkProtocol.getState() == ProtocolState.CLOSE) { throw new NotConnectedException(); } - final KuzzleMap queryMap = KuzzleMap.from(query); if (queryMap.contains("waitForRefresh")) { diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java new file mode 100644 index 00000000..047da2e3 --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -0,0 +1,71 @@ +package io.kuzzle.test.API.Controllers.DocumentTest; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; + +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class DocumentTest { + + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void createDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + String _id = "some_id"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ConcurrentHashMap options = new ConcurrentHashMap<>(); + options.put("refresh", "wait_for"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().create(index, collection, document, _id, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test(expected = NotConnectedException.class) + public void queryShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + String _id = "some_id"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ConcurrentHashMap options = new ConcurrentHashMap<>(); + options.put("refresh", "wait_for"); + + kuzzleMock.getDocumentController().create(index, collection, document, _id, options); + } +} diff --git a/src/test/java/io/kuzzle/test/KuzzleTests.java b/src/test/java/io/kuzzle/test/KuzzleTests.java index 4025e786..bfd7272e 100644 --- a/src/test/java/io/kuzzle/test/KuzzleTests.java +++ b/src/test/java/io/kuzzle/test/KuzzleTests.java @@ -23,7 +23,6 @@ import java.net.URISyntaxException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; public class KuzzleTests { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); From cd049008977fd6acb5bc61600f7fa60a73e92472 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 15:12:44 +0100 Subject: [PATCH 021/134] doc --- doc/3/controllers/document/index.md | 55 +++++++++++++++++++ .../controllers/document/snippets/create.java | 9 +++ .../document/snippets/create.test.yml | 10 ++++ 3 files changed, 74 insertions(+) create mode 100644 doc/3/controllers/document/index.md create mode 100644 doc/3/controllers/document/snippets/create.java create mode 100644 doc/3/controllers/document/snippets/create.test.yml diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md new file mode 100644 index 00000000..0c21d8f1 --- /dev/null +++ b/doc/3/controllers/document/index.md @@ -0,0 +1,55 @@ +--- +code: true +type: page +title: create +description: document:create +--- + +# create + +Creates a new document in the provided index and collection. + +--- + +## Arguments + +```java +public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final String _id, + final ConcurrentHashMap options) throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
string
| Index | +| `collection` |
string
| Collection | +| `content` |
ConcurrentHashMap
| Content of the document to create | +| `id` |
string
| Document identifier | +| `options` |
ConcurrentHashMap
| Optional parameters | + +--- + +## Options + +| Option | Type | Description | | | +| ---------- | ----------- | ---------------------------------------------------------------------------------- | +| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing| + +--- + +## Return + +A ConcurrentHashMap which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the newly created document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/create.java \ No newline at end of file diff --git a/doc/3/controllers/document/snippets/create.java b/doc/3/controllers/document/snippets/create.java new file mode 100644 index 00000000..e8eaf818 --- /dev/null +++ b/doc/3/controllers/document/snippets/create.java @@ -0,0 +1,9 @@ + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("firstname", "John"); + document.put("lastname", "Smith"); + + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + kuzzle.getDocumentController().create("nyc-open-data", "yellow-taxi", document, "some-id", options) + .get(); diff --git a/doc/3/controllers/document/snippets/create.test.yml b/doc/3/controllers/document/snippets/create.test.yml new file mode 100644 index 00000000..a9c129ba --- /dev/null +++ b/doc/3/controllers/document/snippets/create.test.yml @@ -0,0 +1,10 @@ +name: document#create +description: Creates a new document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: default +expected: Success \ No newline at end of file From cca5cfbc6443658b73ad55998e2e847461244700 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 15:13:59 +0100 Subject: [PATCH 022/134] doc --- doc/3/controllers/document/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md index 0c21d8f1..5f275d03 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/index.md @@ -34,7 +34,7 @@ public CompletableFuture> create( ## Options -| Option | Type | Description | | | +| Option | Type | Description | ---------- | ----------- | ---------------------------------------------------------------------------------- | | `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing| @@ -46,7 +46,7 @@ A ConcurrentHashMap which has the following properties: | Property | Type | Description | |------------- |----------------------------- |--------------------------------- | -| `_source` |
ConcurrentHashMap
| Created document | +| `_source` |
ConcurrentHashMap
| Created document | | `_id` |
String
| ID of the newly created document | | `_version` |
Integer
| Version of the document in the persistent data storage | From 84d015e0e665d3d6787830f83ff268efdf988662 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 15:31:18 +0100 Subject: [PATCH 023/134] update .travis.yml --- .travis.yml | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0432d4b7..f70fe555 100644 --- a/.travis.yml +++ b/.travis.yml @@ -106,11 +106,26 @@ jobs: - "$HOME/.gradle/wrapper/" install: - cd $TRAVIS_BUILD_DIR/ - - gradle assemble - - cd $TRAVIS_BUILD_DIR/ - - gradle assemble + - ./gradlew assemble script: - - gradle build + - ./gradlew build + + - stage: Builds + name: Build SDK Java + language: java + jdk: openjdk8 + sudo: false + before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: + directories: + - "$HOME/.gradle/caches/" + - "$HOME/.gradle/wrapper/" + install: + - cd $TRAVIS_BUILD_DIR/ + script: + - ./gradlew test stages: - name: Unit Tests From fcbfd4f478fd7548bf9d497d74eb9bb2905e0e0c Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 15:37:39 +0100 Subject: [PATCH 024/134] update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f70fe555..1cdf30ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -110,8 +110,8 @@ jobs: script: - ./gradlew build - - stage: Builds - name: Build SDK Java + - stage: Unit test + name: Unit tests SDK Java language: java jdk: openjdk8 sudo: false From 7a656fff269ffdfef41871a49603795b1cd4f69b Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 15:41:39 +0100 Subject: [PATCH 025/134] update .travis.yml --- .travis.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1cdf30ee..191ffb0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -110,22 +110,22 @@ jobs: script: - ./gradlew build - - stage: Unit test - name: Unit tests SDK Java - language: java - jdk: openjdk8 - sudo: false - before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ - cache: - directories: - - "$HOME/.gradle/caches/" - - "$HOME/.gradle/wrapper/" - install: - - cd $TRAVIS_BUILD_DIR/ - script: - - ./gradlew test + - stage: Unit tests + name: Unit tests SDK Java + language: java + jdk: openjdk8 + sudo: false + before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: + directories: + - "$HOME/.gradle/caches/" + - "$HOME/.gradle/wrapper/" + install: + - cd $TRAVIS_BUILD_DIR/ + script: + - ./gradlew test stages: - name: Unit Tests From 9ac554953c69909e9c9541c7aaaf53df118ff4f3 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 7 Feb 2020 16:50:30 +0100 Subject: [PATCH 026/134] update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 191ffb0f..17d69855 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ jobs: - cd $TRAVIS_BUILD_DIR/ - ./gradlew assemble script: - - ./gradlew build + - gradle build - stage: Unit tests name: Unit tests SDK Java From a903107855fd878e9b0f3b3f92e6250a49dae0ba Mon Sep 17 00:00:00 2001 From: jenow Date: Mon, 10 Feb 2020 12:50:11 +0100 Subject: [PATCH 027/134] auth controller tests --- .travis.yml | 18 + .../sdk/API/Controllers/AuthController.java | 29 +- .../java/io/kuzzle/sdk/CoreClasses/Task.java | 41 +-- src/main/java/io/kuzzle/sdk/Kuzzle.java | 32 +- .../API/Controllers/AuthControllerTest.java | 313 ++++++++++++++++++ .../test/CoreClasses/TaskTest/TaskTests.java | 25 +- .../CoreClasses/TaskTest/TestableTask.java | 11 +- src/test/java/io/kuzzle/test/KuzzleTests.java | 2 - .../test/ProtocolTest/WebSocketTests.java | 1 - 9 files changed, 371 insertions(+), 101 deletions(-) create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java diff --git a/.travis.yml b/.travis.yml index 0432d4b7..2737e5a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,6 +112,24 @@ jobs: script: - gradle build + - stage: Unit Tests + name: Run unit tests + language: java + jdk: openjdk8 + sudo: false + before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: + directories: + - "$HOME/.gradle/caches/" + - "$HOME/.gradle/wrapper/" + install: + - cd $TRAVIS_BUILD_DIR/ + - gradle assemble + script: + - gradle test + stages: - name: Unit Tests if: type =~ /(cron|push|pull_request)/ AND branch =~ /^master|[0-9]+-(dev|stable)$/ diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java index 4255cb7c..f4ac988b 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java @@ -19,9 +19,8 @@ public AuthController(final Kuzzle kuzzle) { /** * Checks the validity of an authentication token. - * - * @param token - * An authentication token + * + * @param token An authentication token * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -43,12 +42,10 @@ public CompletableFuture> checkToken( /** * Creates new credentials for the current user. - * - * @param strategy - * A String representing the strategy - * @param credentials - * A ConcurrentHashMap representing - * credentials information + * + * @param strategy A String representing the strategy + * @param credentials A ConcurrentHashMap representing + * credentials information * @return A CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -75,9 +72,8 @@ public CompletableFuture> createMyCredentials( /** * Checks that the current authenticated user has credentials for the * specified authentication strategy. - * - * @param strategy - * A String representing the strategy + * + * @param strategy A String representing the strategy * @return A CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -152,7 +148,8 @@ public CompletableFuture> getStrategies() throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); - query.put("controller", "auth").put("action", "getStrategies"); + query.put("controller", "auth") + .put("action", "getStrategies"); return kuzzle .query(query) @@ -176,7 +173,7 @@ public CompletableFuture> login( final KuzzleMap map = KuzzleMap .from((ConcurrentHashMap) response.result); kuzzle.setAuthenticationToken(map.getString("jwt")); - if (!map.isNull("_id")) { + if (map.getString("_id") != null) { kuzzle.trigger(Event.loginAttempt, true); } else { kuzzle.trigger(Event.loginAttempt, false); @@ -208,7 +205,7 @@ public CompletableFuture> refreshToken( query .put("controller", "auth") .put("action", "refreshToken") - .put("expiresIn", expiresIn); + .put("expiresIn", (expiresIn == null ? "1h" : expiresIn)); return kuzzle.query(query).thenApplyAsync((response) -> { final KuzzleMap map = KuzzleMap @@ -259,7 +256,7 @@ public CompletableFuture> updateSelf( } public CompletableFuture validateMyCredentials(final String strategy, - final ConcurrentHashMap credentials) + final ConcurrentHashMap credentials) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java index 7980ecdf..4039187b 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Task.java @@ -1,43 +1,15 @@ package io.kuzzle.sdk.CoreClasses; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; /** * @param The object type that the task return. */ public class Task { - /** - * A countDownLatch used to lock the future. - */ - protected CountDownLatch countDownLatch; /** * A completable future. */ - protected CompletableFuture future; - - /** - * The object instance to return. - */ - protected AtomicReference atomicReference; - - /** - * Initializes a new instance of the Task. - */ - public Task() { - atomicReference = new AtomicReference(); - countDownLatch = new CountDownLatch(1); - future = CompletableFuture.supplyAsync(() -> { - try { - countDownLatch.await(); - - return atomicReference.get(); - } catch (InterruptedException e) { - return null; - } - }); - } + protected CompletableFuture future = new CompletableFuture<>(); /** * @return The associated CompletableFuture. @@ -48,7 +20,7 @@ public CompletableFuture getFuture() { /** * Set the exception of the CompletableFuture. - * + * * @param exception */ public void setException(Exception exception) { @@ -78,7 +50,7 @@ public boolean isCompletedExceptionally() { /** * Set if the future is cancelled. - * + * * @param state */ public void setCancelled(boolean state) { @@ -89,16 +61,15 @@ public void setCancelled(boolean state) { * Unlock the future. */ public void trigger() { - countDownLatch.countDown(); + future.complete(null); } /** * Unlock the future and set the object. - * + * * @param object */ public void trigger(T object) { - atomicReference.set(object); - countDownLatch.countDown(); + future.complete(object); } } diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 8e10353c..3acb9446 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -57,9 +57,8 @@ public class Kuzzle extends EventManager { /** * Initialize a new instance of Kuzzle - * - * @param networkProtocol - * The network protocol + * + * @param networkProtocol The network protocol * @throws IllegalArgumentException */ public Kuzzle(final AbstractProtocol networkProtocol) @@ -73,15 +72,13 @@ public AuthController getAuthController() { /** * Initialize a new instance of Kuzzle - * - * @param networkProtocol - * The network protocol - * @param options - * Kuzzle options + * + * @param networkProtocol The network protocol + * @param options Kuzzle options * @throws IllegalArgumentException */ public Kuzzle(final AbstractProtocol networkProtocol, - final KuzzleOptions options) throws IllegalArgumentException { + final KuzzleOptions options) throws IllegalArgumentException { if (networkProtocol == null) { throw new IllegalArgumentException("networkProtocol can't be null"); } @@ -108,7 +105,7 @@ public Kuzzle(final AbstractProtocol networkProtocol, /** * Establish a network connection - * + * * @throws Exception */ public void connect() throws Exception { @@ -124,9 +121,8 @@ public void disconnect() { /** * Handles the ResponseReceivedEvent from the network protocol - * - * @param payload - * Raw API Response + * + * @param payload Raw API Response */ protected void onResponseReceived(final Object... payload) { @@ -178,9 +174,8 @@ protected void onStateChanged(final Object... args) { /** * Sends an API request to Kuzzle and returns the corresponding API - * - * @param query - * Kuzzle API query + * + * @param query Kuzzle API query * @return A CompletableFuture * @throws InternalException * @throws NotConnectedException @@ -242,9 +237,8 @@ public String getAuthenticationToken() { /** * Set the authentication token - * - * @param token - * Authentication token + * + * @param token Authentication token */ public void setAuthenticationToken(final String token) { if (authenticationToken == null) { diff --git a/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java new file mode 100644 index 00000000..70a3fe96 --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java @@ -0,0 +1,313 @@ +package io.kuzzle.test.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class AuthControllerTest { + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void checkTokenTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().checkToken("my-token"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "checkToken"); + assertEquals("my-token", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("token").toString()); + } + + @Test + public void createMyCredentialsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().createMyCredentials("local", credentials); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createMyCredentials"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void credentialsExistTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().credentialsExist("local"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "credentialsExist"); + assertEquals("local", ((((KuzzleMap) arg.getValue()).getString("strategy")))); + } + + @Test + public void getMyCredentialsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().getMyCredentials("local"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "getMyCredentials"); + assertEquals("local", ((((KuzzleMap) arg.getValue()).getString("strategy")))); + } + + @Test + public void getMyRightsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().getMyRights(); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "getMyRights"); + } + + @Test + public void getStrategies() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().getStrategies(); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "getStrategies"); + } + + @Test + public void loginSuccessTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + CompletableFuture future = new CompletableFuture<>(); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Response response = new Response(); + ConcurrentHashMap result = new ConcurrentHashMap<>(); + + result.put("jwt", "my-token"); + result.put("_id", "my-id"); + response.result = result; + + doReturn(future).when(kuzzleSpy).query(any(KuzzleMap.class)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + kuzzleSpy.getAuthController().login("local", credentials); + future.complete(response); + Thread.sleep(1000); + verify(kuzzleSpy).setAuthenticationToken(eq("my-token")); + verify(kuzzleSpy).trigger(eq(Event.loginAttempt), eq(true)); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "login"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void loginSuccessWithExpiresInTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + CompletableFuture future = new CompletableFuture<>(); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Response response = new Response(); + ConcurrentHashMap result = new ConcurrentHashMap<>(); + + result.put("jwt", "my-token"); + result.put("_id", "my-id"); + response.result = result; + + doReturn(future).when(kuzzleSpy).query(any(KuzzleMap.class)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + kuzzleSpy.getAuthController().login("local", credentials, "42h"); + future.complete(response); + Thread.sleep(1000); + verify(kuzzleSpy).setAuthenticationToken(eq("my-token")); + verify(kuzzleSpy).trigger(eq(Event.loginAttempt), eq(true)); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "login"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "42h"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void loginFailTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + CompletableFuture future = new CompletableFuture<>(); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Response response = new Response(); + response.result = new ConcurrentHashMap<>(); + + doReturn(future).when(kuzzleSpy).query(any(KuzzleMap.class)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + kuzzleSpy.getAuthController().login("local", credentials); + future.complete(response); + Thread.sleep(1000); + verify(kuzzleSpy).setAuthenticationToken(eq(null)); + verify(kuzzleSpy).trigger(eq(Event.loginAttempt), eq(false)); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "login"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void refreshTokenTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + CompletableFuture future = new CompletableFuture<>(); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Response response = new Response(); + ConcurrentHashMap result = new ConcurrentHashMap<>(); + + result.put("jwt", "my-token"); + response.result = result; + + doReturn(future).when(kuzzleSpy).query(any(KuzzleMap.class)); + + kuzzleSpy.getAuthController().refreshToken(); + future.complete(response); + Thread.sleep(1000); + verify(kuzzleSpy).setAuthenticationToken(eq("my-token")); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "refreshToken"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + } + + @Test + public void refreshTokenWithExpiresInTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + CompletableFuture future = new CompletableFuture<>(); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Response response = new Response(); + ConcurrentHashMap result = new ConcurrentHashMap<>(); + + result.put("jwt", "my-token"); + response.result = result; + + doReturn(future).when(kuzzleSpy).query(any(KuzzleMap.class)); + + kuzzleSpy.getAuthController().refreshToken("42h"); + future.complete(response); + Thread.sleep(1000); + verify(kuzzleSpy).setAuthenticationToken(eq("my-token")); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "refreshToken"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "42h"); + } + + @Test + public void updateMyCredentialsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().updateMyCredentials("local", credentials); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "updateMyCredentials"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void updateSelfTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().updateSelf(credentials); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "updateSelf"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } + + @Test + public void validateMyCredentialsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ConcurrentHashMap credentials = new ConcurrentHashMap<>(); + credentials.put("username", "foo"); + credentials.put("password", "foobar"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getAuthController().validateMyCredentials("local", credentials); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "validateMyCredentials"); + assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); + assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); + assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); + } +} diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java index cb91e79b..b2ebb046 100644 --- a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TaskTests.java @@ -5,9 +5,7 @@ import org.junit.Test; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; @@ -16,10 +14,6 @@ public class TaskTests { @Test public void constructorTest() { TestableTask task = new TestableTask<>(); - Assert.assertNotNull(task.getAtomicReference()); - Assert.assertEquals(AtomicReference.class, task.getAtomicReference().getClass()); - Assert.assertNotNull(task.getCountDownLatch()); - Assert.assertEquals(CountDownLatch.class, task.getCountDownLatch().getClass()); Assert.assertNotNull(task.getFuture()); } @@ -33,7 +27,7 @@ public void getFutureTest() { @Test public void setExceptionTest() { TestableTask task = new TestableTask<>(); - task.applyMockFuture(); + task.applyMocks(); task.setException(new Exception("foobar")); @@ -43,7 +37,7 @@ public void setExceptionTest() { @Test public void isCancelledTest() { TestableTask task = new TestableTask<>(); - task.applyMockFuture(); + task.applyMocks(); when(task.mockedFuture.isCancelled()).thenReturn(true); @@ -55,7 +49,7 @@ public void isCancelledTest() { @Test public void isDoneTest() { TestableTask task = new TestableTask<>(); - task.applyMockFuture(); + task.applyMocks(); when(task.mockedFuture.isDone()).thenReturn(true); @@ -67,7 +61,7 @@ public void isDoneTest() { @Test public void isCompletedExceptionallyTest() { TestableTask task = new TestableTask<>(); - task.applyMockFuture(); + task.applyMocks(); when(task.mockedFuture.isCompletedExceptionally()).thenReturn(true); @@ -79,7 +73,7 @@ public void isCompletedExceptionallyTest() { @Test public void setCancelledTest() { TestableTask task = new TestableTask<>(); - task.applyMockFuture(); + task.applyMocks(); task.setCancelled(true); @@ -92,16 +86,13 @@ public void triggerTest() { final AtomicBoolean success = new AtomicBoolean(false); - CompletableFuture taskChain = task.getFuture().thenRun(() -> { - success.set(true); - }); + CompletableFuture taskChain = task.getFuture().thenRun(() -> success.set(true)); task.trigger(); taskChain.join(); Assert.assertTrue(success.get()); - } @Test @@ -110,9 +101,7 @@ public void triggerWithObjectTest() { final AtomicBoolean success = new AtomicBoolean(false); - CompletableFuture taskChain = task.getFuture().thenAccept((str) -> { - success.set(str.equals("foobar")); - }); + CompletableFuture taskChain = task.getFuture().thenAccept((str) -> success.set(str.equals("foobar"))); task.trigger("foobar"); diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java index 7ac9140f..0ae5c330 100644 --- a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/TestableTask.java @@ -16,16 +16,7 @@ public TestableTask() { super(); } - public void applyMockFuture() { + public void applyMocks() { super.future = mockedFuture; } - - public CountDownLatch getCountDownLatch() { - return super.countDownLatch; - } - - public AtomicReference getAtomicReference() { - return super.atomicReference; - } - } diff --git a/src/test/java/io/kuzzle/test/KuzzleTests.java b/src/test/java/io/kuzzle/test/KuzzleTests.java index 4025e786..ad7e389d 100644 --- a/src/test/java/io/kuzzle/test/KuzzleTests.java +++ b/src/test/java/io/kuzzle/test/KuzzleTests.java @@ -23,7 +23,6 @@ import java.net.URISyntaxException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; public class KuzzleTests { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); @@ -123,5 +122,4 @@ public void onResponseReceivedAndResponseIsUnhandled() { Mockito.verify(listener, Mockito.times(1)).trigger(Matchers.any(Response.class)); } - } diff --git a/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java index e0b25317..e29a4e37 100644 --- a/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java +++ b/src/test/java/io/kuzzle/test/ProtocolTest/WebSocketTests.java @@ -11,7 +11,6 @@ import static org.mockito.Mockito.*; public class WebSocketTests { - private TestableWebSocket socket; private String host; private WebSocketOptions options; From 367b44971ceae760233dd332ef3591ceb16f78e6 Mon Sep 17 00:00:00 2001 From: jenow Date: Mon, 10 Feb 2020 14:40:55 +0100 Subject: [PATCH 028/134] replace gradle by gradlew --- .travis.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2737e5a1..1dd7a360 100644 --- a/.travis.yml +++ b/.travis.yml @@ -106,11 +106,9 @@ jobs: - "$HOME/.gradle/wrapper/" install: - cd $TRAVIS_BUILD_DIR/ - - gradle assemble - - cd $TRAVIS_BUILD_DIR/ - - gradle assemble + - ./gradlew assemble script: - - gradle build + - ./gradlew build - stage: Unit Tests name: Run unit tests @@ -126,9 +124,9 @@ jobs: - "$HOME/.gradle/wrapper/" install: - cd $TRAVIS_BUILD_DIR/ - - gradle assemble + - ./gradlew assemble script: - - gradle test + - ./gradlew test stages: - name: Unit Tests From b6bdd2d97281c39d01fe854a9bef1e3d98f8b1c7 Mon Sep 17 00:00:00 2001 From: jenow Date: Tue, 11 Feb 2020 10:45:10 +0100 Subject: [PATCH 029/134] no default value for expiresIn --- .../java/io/kuzzle/sdk/API/Controllers/AuthController.java | 2 +- .../io/kuzzle/test/API/Controllers/AuthControllerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java index f4ac988b..8c791f7f 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java @@ -167,7 +167,7 @@ public CompletableFuture> login( .put("action", "login") .put("strategy", strategy) .put("body", credentials) - .put("expiresIn", (expiresIn == null ? "1h" : expiresIn)); + .put("expiresIn", expiresIn); return kuzzle.query(query).thenApplyAsync((response) -> { final KuzzleMap map = KuzzleMap diff --git a/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java index 70a3fe96..d7b5f60a 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java @@ -137,7 +137,7 @@ public void loginSuccessTest() throws NotConnectedException, InternalException, assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "login"); assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); - assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), null); assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); } @@ -199,7 +199,7 @@ public void loginFailTest() throws NotConnectedException, InternalException, Int assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "login"); assertEquals(((KuzzleMap) arg.getValue()).getString("strategy"), "local"); - assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), null); assertEquals("foo", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("username")); assertEquals("foobar", ((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("password")); } From fe33e0676686fb7b692e644071b4023268fece66 Mon Sep 17 00:00:00 2001 From: jenow Date: Wed, 12 Feb 2020 17:47:49 +0100 Subject: [PATCH 030/134] no default value for expiresIn for refreshToken --- src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java | 2 +- .../java/io/kuzzle/test/API/Controllers/AuthControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java index 8c791f7f..318aff2b 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/AuthController.java @@ -205,7 +205,7 @@ public CompletableFuture> refreshToken( query .put("controller", "auth") .put("action", "refreshToken") - .put("expiresIn", (expiresIn == null ? "1h" : expiresIn)); + .put("expiresIn", expiresIn); return kuzzle.query(query).thenApplyAsync((response) -> { final KuzzleMap map = KuzzleMap diff --git a/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java index d7b5f60a..92510a1c 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/AuthControllerTest.java @@ -225,7 +225,7 @@ public void refreshTokenTest() throws NotConnectedException, InternalException, assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "auth"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "refreshToken"); - assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), "1h"); + assertEquals(((KuzzleMap) arg.getValue()).getString("expiresIn"), null); } @Test From c6fa610e1d4e59c755c220844d315c39a3f78510 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 17 Feb 2020 15:00:33 +0100 Subject: [PATCH 031/134] Update doc/3/controllers/document/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md index 5f275d03..1dbf0569 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/index.md @@ -42,7 +42,7 @@ public CompletableFuture> create( ## Return -A ConcurrentHashMap which has the following properties: +A `ConcurrentHashMap` which has the following properties: | Property | Type | Description | |------------- |----------------------------- |--------------------------------- | @@ -52,4 +52,4 @@ A ConcurrentHashMap which has the following properties: ## Usage -<<< ./snippets/create.java \ No newline at end of file +<<< ./snippets/create.java From 1286d02a1814f15eb6b757802fb6c89a9fe42401 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 17 Feb 2020 15:00:45 +0100 Subject: [PATCH 032/134] Update doc/3/controllers/document/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md index 1dbf0569..bd28d892 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/index.md @@ -2,7 +2,7 @@ code: true type: page title: create -description: document:create +description: Creates a new document --- # create From f52dde167d83a149a05f4e9aa23b12d1ec8876fb Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 17 Feb 2020 15:48:59 +0100 Subject: [PATCH 033/134] overloads --- doc/3/controllers/document/index.md | 17 ++--- .../API/Controllers/DocumentController.java | 63 ++++++++++++++++++- .../DocumentTest/DocumentTest.java | 12 +--- 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md index 5f275d03..550d7586 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/index.md @@ -18,8 +18,9 @@ public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final String _id, - final ConcurrentHashMap options) throws NotConnectedException, InternalException + final String _id, // optional + final Boolean waitForRefresh) // optional +throws NotConnectedException, InternalException ``` | Arguments | Type | Description | @@ -27,16 +28,8 @@ public CompletableFuture> create( | `index` |
string
| Index | | `collection` |
string
| Collection | | `content` |
ConcurrentHashMap
| Content of the document to create | -| `id` |
string
| Document identifier | -| `options` |
ConcurrentHashMap
| Optional parameters | - ---- - -## Options - -| Option | Type | Description -| ---------- | ----------- | ---------------------------------------------------------------------------------- | -| `refresh` | string | If set to `wait_for`, Kuzzle will wait for the persistence layer to finish indexing| +| `id` |
string
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| --- diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 4446ee20..9583d09a 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk.API.Controllers; +import com.sun.org.apache.xpath.internal.operations.Bool; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.Events.Event; @@ -10,6 +11,7 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.UUID; public class DocumentController extends BaseController { public DocumentController(final Kuzzle kuzzle) { @@ -23,7 +25,7 @@ public DocumentController(final Kuzzle kuzzle) { * @param collection * @param document * @param _id - * @param options + * @param waitForRefresh * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -33,7 +35,7 @@ public CompletableFuture> create( final String collection, final ConcurrentHashMap document, final String _id, - final ConcurrentHashMap options) throws NotConnectedException, InternalException { + final Boolean waitForRefresh) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); query @@ -43,11 +45,66 @@ public CompletableFuture> create( .put("action", "create") .put("_id", _id) .put("body", document) - .put("options", options); + .put("waitForRefresh", waitForRefresh); return kuzzle .query(query) .thenApplyAsync( (response) -> (ConcurrentHashMap) response.result); } + + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + return this.create(index, collection, document, UUID.randomUUID().toString(), waitForRefresh); + } + + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + return this.create(index, collection, document, UUID.randomUUID().toString(), false); + } + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @param _id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final String _id) throws NotConnectedException, InternalException { + return this.create(index, collection, document, _id, false); + } + } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 047da2e3..65bce8af 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -28,18 +28,14 @@ public void createDocumentTest() throws NotConnectedException, InternalException Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; - String _id = "some_id"; ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); document.put("nickname", "El angel de la muerte que hace el JAVA"); - ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("refresh", "wait_for"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().create(index, collection, document, _id, options); + kuzzleMock.getDocumentController().create(index, collection, document, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); @@ -57,15 +53,11 @@ public void queryShouldThrowWhenNotConnected() throws NotConnectedException, Int Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; - String _id = "some_id"; ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); document.put("nickname", "El angel de la muerte que hace el JAVA"); - ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("refresh", "wait_for"); - - kuzzleMock.getDocumentController().create(index, collection, document, _id, options); + kuzzleMock.getDocumentController().create(index, collection, document); } } From 8d9da7e5454158057c0d0fd7ab43b4f87839ba76 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 17 Feb 2020 15:51:15 +0100 Subject: [PATCH 034/134] remove useless opt --- .../kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 65bce8af..bb30f7f0 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -35,7 +35,7 @@ public void createDocumentTest() throws NotConnectedException, InternalException ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().create(index, collection, document, true); + kuzzleMock.getDocumentController().create(index, collection, document); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); From b001ce7f76e1034c302f24b1c517195575e16a5e Mon Sep 17 00:00:00 2001 From: Yoann Date: Tue, 18 Feb 2020 17:18:40 +0100 Subject: [PATCH 035/134] options object --- .../API/Controllers/DocumentController.java | 62 +++++-------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 9583d09a..0036134c 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -24,8 +24,7 @@ public DocumentController(final Kuzzle kuzzle) { * @param index * @param collection * @param document - * @param _id - * @param waitForRefresh + * @param options * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -34,18 +33,22 @@ public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final String _id, - final Boolean waitForRefresh) throws NotConnectedException, InternalException { + final ConcurrentHashMap options) throws NotConnectedException, InternalException { + final KuzzleMap query = new KuzzleMap(); + final KuzzleMap _options = KuzzleMap + .from(options); + final String _id = _options.getString("_id") == null ? UUID.randomUUID().toString() : _options.getString("_id"); + final Boolean _waitForRefresh = _options.getBoolean("waitForRefresh"); query .put("index", index) .put("collection", collection) .put("controller", "document") .put("action", "create") - .put("_id", _id) .put("body", document) - .put("waitForRefresh", waitForRefresh); + .put("_id", _id) + .put("waitForRefresh", _waitForRefresh); return kuzzle .query(query) @@ -59,52 +62,19 @@ public CompletableFuture> create( * @param index * @param collection * @param document - * @param waitForRefresh * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document, - final Boolean waitForRefresh) throws NotConnectedException, InternalException { - return this.create(index, collection, document, UUID.randomUUID().toString(), waitForRefresh); - } + final String index, + final String collection, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - return this.create(index, collection, document, UUID.randomUUID().toString(), false); - } - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @param _id - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document, - final String _id) throws NotConnectedException, InternalException { - return this.create(index, collection, document, _id, false); + final ConcurrentHashMap options = new ConcurrentHashMap<>(); + options.put("_id", UUID.randomUUID().toString()); + options.put("waitForRefresh", false); + return this.create(index, collection, document, options); } } From 37738a6518cbfd17759f5a6e89fef54e8c524601 Mon Sep 17 00:00:00 2001 From: Yoann Date: Tue, 18 Feb 2020 17:23:50 +0100 Subject: [PATCH 036/134] remove useless import --- .../io/kuzzle/sdk/API/Controllers/DocumentController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 0036134c..4a61c887 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -1,14 +1,10 @@ package io.kuzzle.sdk.API.Controllers; -import com.sun.org.apache.xpath.internal.operations.Bool; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.CoreClasses.Responses.Response; -import io.kuzzle.sdk.Events.Event; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; -import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.UUID; From 2c97572fe9844d22484b68267fab8b6a6400be63 Mon Sep 17 00:00:00 2001 From: Yoann Date: Thu, 20 Feb 2020 11:15:34 +0100 Subject: [PATCH 037/134] @aschen requested change --- .../io/kuzzle/sdk/API/Controllers/DocumentController.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 4a61c887..a4dbe99e 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -34,8 +34,6 @@ public CompletableFuture> create( final KuzzleMap query = new KuzzleMap(); final KuzzleMap _options = KuzzleMap .from(options); - final String _id = _options.getString("_id") == null ? UUID.randomUUID().toString() : _options.getString("_id"); - final Boolean _waitForRefresh = _options.getBoolean("waitForRefresh"); query .put("index", index) @@ -43,8 +41,8 @@ public CompletableFuture> create( .put("controller", "document") .put("action", "create") .put("body", document) - .put("_id", _id) - .put("waitForRefresh", _waitForRefresh); + .put("_id", _options.getString("_id")) + .put("waitForRefresh", _options.getBoolean("waitForRefresh")); return kuzzle .query(query) @@ -68,8 +66,6 @@ public CompletableFuture> create( final ConcurrentHashMap document) throws NotConnectedException, InternalException { final ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("_id", UUID.randomUUID().toString()); - options.put("waitForRefresh", false); return this.create(index, collection, document, options); } From cebebf829e00e8474086c1a0664c40f14424fe1f Mon Sep 17 00:00:00 2001 From: Yoann Date: Thu, 20 Feb 2020 15:11:13 +0100 Subject: [PATCH 038/134] doc --- doc/3/controllers/document/index.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/index.md index e0084f9c..5071839f 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/index.md @@ -14,12 +14,17 @@ Creates a new document in the provided index and collection. ## Arguments ```java +public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException + public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final String _id, // optional - final Boolean waitForRefresh) // optional + final ConcurrentHashMap options) throws NotConnectedException, InternalException ``` @@ -28,11 +33,16 @@ throws NotConnectedException, InternalException | `index` |
string
| Index | | `collection` |
string
| Collection | | `content` |
ConcurrentHashMap
| Content of the document to create | -| `id` |
string
(optional) | Document identifier. Auto-generated if not specified | -| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| --- +# options + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `id` |
string
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + ## Return A `ConcurrentHashMap` which has the following properties: From 35a77484aba29228115061981f72a8f612f3a131 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 21 Feb 2020 09:51:28 +0100 Subject: [PATCH 039/134] doc --- doc/3/controllers/document/{ => create}/index.md | 11 ++++++----- .../document/{ => create}/snippets/create.java | 0 .../document/{ => create}/snippets/create.test.yml | 0 3 files changed, 6 insertions(+), 5 deletions(-) rename doc/3/controllers/document/{ => create}/index.md (84%) rename doc/3/controllers/document/{ => create}/snippets/create.java (100%) rename doc/3/controllers/document/{ => create}/snippets/create.test.yml (100%) diff --git a/doc/3/controllers/document/index.md b/doc/3/controllers/document/create/index.md similarity index 84% rename from doc/3/controllers/document/index.md rename to doc/3/controllers/document/create/index.md index 5071839f..845207ac 100644 --- a/doc/3/controllers/document/index.md +++ b/doc/3/controllers/document/create/index.md @@ -30,17 +30,18 @@ throws NotConnectedException, InternalException | Arguments | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | -| `index` |
string
| Index | -| `collection` |
string
| Collection | -| `content` |
ConcurrentHashMap
| Content of the document to create | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `document` |
ConcurrentHashMap
| Content of the document to create | +| `options` |
ConcurrentHashMap
| Optional parameters | --- -# options +### options | Arguments | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | -| `id` |
string
(optional) | Document identifier. Auto-generated if not specified | +| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | | `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| ## Return diff --git a/doc/3/controllers/document/snippets/create.java b/doc/3/controllers/document/create/snippets/create.java similarity index 100% rename from doc/3/controllers/document/snippets/create.java rename to doc/3/controllers/document/create/snippets/create.java diff --git a/doc/3/controllers/document/snippets/create.test.yml b/doc/3/controllers/document/create/snippets/create.test.yml similarity index 100% rename from doc/3/controllers/document/snippets/create.test.yml rename to doc/3/controllers/document/create/snippets/create.test.yml From d834d5ee1695e27db78fcc5c870a6b6258e23870 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 21 Feb 2020 14:50:11 +0100 Subject: [PATCH 040/134] document:delete --- doc/3/controllers/document/delete/index.md | 59 +++++++++++++++ .../document/delete/snippets/delete.java | 3 + .../document/delete/snippets/delete.test.yml | 11 +++ .../API/Controllers/DocumentController.java | 72 +++++++++++++++++++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 5 ++ .../DocumentTest/DocumentTest.java | 54 ++++++++++++++ 6 files changed, 204 insertions(+) create mode 100644 doc/3/controllers/document/delete/index.md create mode 100644 doc/3/controllers/document/delete/snippets/delete.java create mode 100644 doc/3/controllers/document/delete/snippets/delete.test.yml create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java diff --git a/doc/3/controllers/document/delete/index.md b/doc/3/controllers/document/delete/index.md new file mode 100644 index 00000000..845207ac --- /dev/null +++ b/doc/3/controllers/document/delete/index.md @@ -0,0 +1,59 @@ +--- +code: true +type: page +title: create +description: Creates a new document +--- + +# create + +Creates a new document in the provided index and collection. + +--- + +## Arguments + +```java +public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException + +public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final ConcurrentHashMap options) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `document` |
ConcurrentHashMap
| Content of the document to create | +| `options` |
ConcurrentHashMap
| Optional parameters | + +--- + +### options + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + +## Return + +A `ConcurrentHashMap` which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the newly created document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/create.java diff --git a/doc/3/controllers/document/delete/snippets/delete.java b/doc/3/controllers/document/delete/snippets/delete.java new file mode 100644 index 00000000..0f98c216 --- /dev/null +++ b/doc/3/controllers/document/delete/snippets/delete.java @@ -0,0 +1,3 @@ + + kuzzle.getDocumentController().delete("nyc-open-data", "yellow-taxi", "some_id") + .get(); diff --git a/doc/3/controllers/document/delete/snippets/delete.test.yml b/doc/3/controllers/document/delete/snippets/delete.test.yml new file mode 100644 index 00000000..c9082ef1 --- /dev/null +++ b/doc/3/controllers/document/delete/snippets/delete.test.yml @@ -0,0 +1,11 @@ +name: document#create +description: Creates a new document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java new file mode 100644 index 00000000..7877f5f4 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -0,0 +1,72 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.UUID; + +public class DocumentController extends BaseController { + public DocumentController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Deletes a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> delete( + final String index, + final String collection, + final String id, + final ConcurrentHashMap options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + final KuzzleMap _options = KuzzleMap + .from(options); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "delete") + .put("_id", id) + .put("queuable", _options.getBoolean("queuable")) + .put("waitForRefresh", _options.getBoolean("waitForRefresh")); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Deletes a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> delete( + final String index, + final String collection, + final String id) throws NotConnectedException, InternalException { + + final ConcurrentHashMap options = new ConcurrentHashMap<>(); + return this.delete(index, collection, id, options); + } + +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 3acb9446..3f20cbca 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk; +import io.kuzzle.sdk.API.Controllers.DocumentController; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.API.Controllers.AuthController; @@ -70,6 +71,10 @@ public AuthController getAuthController() { return new AuthController(this); } + public DocumentController getDocumentController() { + return new DocumentController(this); + } + /** * Initialize a new instance of Kuzzle * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java new file mode 100644 index 00000000..9579eb24 --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -0,0 +1,54 @@ +package io.kuzzle.test.API.Controllers.DocumentTest; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; + +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class DocumentTest { + + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void deleteDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().delete(index, collection, "some-id"); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + } + + @Test(expected = NotConnectedException.class) + public void deleteDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().delete(index, collection, "some-id"); + } +} From 0cf82f047e32dbda5b4674e3128e8089018bda3c Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 21 Feb 2020 14:56:04 +0100 Subject: [PATCH 041/134] doc --- doc/3/controllers/document/delete/index.md | 30 ++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/doc/3/controllers/document/delete/index.md b/doc/3/controllers/document/delete/index.md index 845207ac..492c1265 100644 --- a/doc/3/controllers/document/delete/index.md +++ b/doc/3/controllers/document/delete/index.md @@ -1,29 +1,29 @@ --- code: true type: page -title: create -description: Creates a new document +title: delete +description: Deletes a new document --- -# create +# delete -Creates a new document in the provided index and collection. +Deletes a document in the provided index and collection. --- ## Arguments ```java -public CompletableFuture> create( +public CompletableFuture> delete( final String index, final String collection, - final ConcurrentHashMap document) + final String id) throws NotConnectedException, InternalException -public CompletableFuture> create( +public CompletableFuture> delete( final String index, final String collection, - final ConcurrentHashMap document, + final String id, final ConcurrentHashMap options) throws NotConnectedException, InternalException ``` @@ -32,7 +32,7 @@ throws NotConnectedException, InternalException | ------------------ | -------------------------------------------- | --------------------------------- | | `index` |
String
| Index | | `collection` |
String
| Collection | -| `document` |
ConcurrentHashMap
| Content of the document to create | +| `id ` |
String
| Document ID | | `options` |
ConcurrentHashMap
| Optional parameters | --- @@ -41,19 +41,17 @@ throws NotConnectedException, InternalException | Arguments | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | -| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | -| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `queuable` |
Boolean
(optional) | If true, queues the request during downtime, until connected to Kuzzle again | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| ## Return -A `ConcurrentHashMap` which has the following properties: +A `ConcurrentHashMap` which has the following property: | Property | Type | Description | |------------- |----------------------------- |--------------------------------- | -| `_source` |
ConcurrentHashMap
| Created document | -| `_id` |
String
| ID of the newly created document | -| `_version` |
Integer
| Version of the document in the persistent data storage | +| `_id` |
String
| ID of the deleted document | ## Usage -<<< ./snippets/create.java +<<< ./snippets/delete.java From 7a76118e07f58620b441e3b25a32945f1c4dcdce Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 21 Feb 2020 15:32:33 +0100 Subject: [PATCH 042/134] remove queuable --- doc/3/controllers/document/delete/index.md | 11 ++--------- .../sdk/API/Controllers/DocumentController.java | 13 ++++--------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/doc/3/controllers/document/delete/index.md b/doc/3/controllers/document/delete/index.md index 492c1265..3e88ee34 100644 --- a/doc/3/controllers/document/delete/index.md +++ b/doc/3/controllers/document/delete/index.md @@ -24,7 +24,7 @@ public CompletableFuture> delete( final String index, final String collection, final String id, - final ConcurrentHashMap options) + final Boolean waitForRefresh) throws NotConnectedException, InternalException ``` @@ -33,17 +33,10 @@ throws NotConnectedException, InternalException | `index` |
String
| Index | | `collection` |
String
| Collection | | `id ` |
String
| Document ID | -| `options` |
ConcurrentHashMap
| Optional parameters | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| --- -### options - -| Arguments | Type | Description | -| ------------------ | -------------------------------------------- | --------------------------------- | -| `queuable` |
Boolean
(optional) | If true, queues the request during downtime, until connected to Kuzzle again | -| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| - ## Return A `ConcurrentHashMap` which has the following property: diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 7877f5f4..b46fe3af 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -20,7 +20,7 @@ public DocumentController(final Kuzzle kuzzle) { * @param index * @param collection * @param id - * @param options + * @param waitForRefresh * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -29,11 +29,9 @@ public CompletableFuture> delete( final String index, final String collection, final String id, - final ConcurrentHashMap options) throws NotConnectedException, InternalException { + final Boolean waitForRefresh) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); - final KuzzleMap _options = KuzzleMap - .from(options); query .put("index", index) @@ -41,8 +39,7 @@ public CompletableFuture> delete( .put("controller", "document") .put("action", "delete") .put("_id", id) - .put("queuable", _options.getBoolean("queuable")) - .put("waitForRefresh", _options.getBoolean("waitForRefresh")); + .put("waitForRefresh", waitForRefresh); return kuzzle .query(query) @@ -65,8 +62,6 @@ public CompletableFuture> delete( final String collection, final String id) throws NotConnectedException, InternalException { - final ConcurrentHashMap options = new ConcurrentHashMap<>(); - return this.delete(index, collection, id, options); + return this.delete(index, collection, id, false); } - } From f65f9ae6e630809b1b0b66b538a6d5cc662d19d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Tue, 25 Feb 2020 10:38:08 +0100 Subject: [PATCH 043/134] RealtimeController:subscribe (#58) ## What does this PR do ? Add a `RealtimeController` with the `subscribe` method. ### How should this be manually tested? ```sh ./gradlew test ``` --- .ci/doc/templates/default.tpl.java | 1 + .travis.yml | 9 ++ doc/3/controllers/realtime/index.md | 8 ++ doc/3/controllers/realtime/subscribe/index.md | 61 +++++++++++ .../document-notifications-leave-scope.java | 38 +++++++ ...ocument-notifications-leave-scope.test.yml | 10 ++ .../snippets/document-notifications.java | 29 +++++ .../snippets/document-notifications.test.yml | 10 ++ doc/3/core-classes/subscribe-options/index.md | 28 +++++ .../realtime-notifications/index.md | 32 ++++++ .../API/Controllers/RealtimeController.java | 101 +++++++++++++++++ .../sdk/CoreClasses/Responses/Response.java | 2 +- .../sdk/Handlers/NotificationHandler.java | 7 ++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 22 +++- .../kuzzle/sdk/Options/SubscribeOptions.java | 102 ++++++++++++++++++ .../Controllers/RealtimeControllerTest.java | 86 +++++++++++++++ 16 files changed, 542 insertions(+), 4 deletions(-) create mode 100644 doc/3/controllers/realtime/index.md create mode 100644 doc/3/controllers/realtime/subscribe/index.md create mode 100644 doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.java create mode 100644 doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.test.yml create mode 100644 doc/3/controllers/realtime/subscribe/snippets/document-notifications.java create mode 100644 doc/3/controllers/realtime/subscribe/snippets/document-notifications.test.yml create mode 100644 doc/3/core-classes/subscribe-options/index.md create mode 100644 doc/3/essentials/realtime-notifications/index.md create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java create mode 100644 src/main/java/io/kuzzle/sdk/Handlers/NotificationHandler.java create mode 100644 src/main/java/io/kuzzle/sdk/Options/SubscribeOptions.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java index bb86e2d1..49b426c9 100644 --- a/.ci/doc/templates/default.tpl.java +++ b/.ci/doc/templates/default.tpl.java @@ -4,6 +4,7 @@ import io.kuzzle.sdk.Options.KuzzleOptions; import java.util.concurrent.ConcurrentHashMap; import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Options.SubscribeOptions; public class SnippetTest { private static Kuzzle kuzzle; diff --git a/.travis.yml b/.travis.yml index 1dd7a360..22b7f129 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,15 @@ jobs: - gem install typhoeus - HYDRA_MAX_CONCURRENCY=20 npm run --prefix $TRAVIS_BUILD_DIR/doc/framework dead-links + - stage: Tests + name: Documentation Snippets + if: type = pull_request OR type = push AND branch =~ /^master|[0-9]+-dev$/ OR type = cron + language: node_js + node_js: 12 + script: + - docker-compose -f .ci/doc/docker-compose.yml run doc-tests index + + - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io if: type = push AND branch =~ /^[0-9]+-dev$/ diff --git a/doc/3/controllers/realtime/index.md b/doc/3/controllers/realtime/index.md new file mode 100644 index 00000000..0609f3b0 --- /dev/null +++ b/doc/3/controllers/realtime/index.md @@ -0,0 +1,8 @@ +--- +code: true +type: branch +title: Realtime +description: Realtime Controller +--- + +# Realtime Controller diff --git a/doc/3/controllers/realtime/subscribe/index.md b/doc/3/controllers/realtime/subscribe/index.md new file mode 100644 index 00000000..bcba6c66 --- /dev/null +++ b/doc/3/controllers/realtime/subscribe/index.md @@ -0,0 +1,61 @@ +--- +code: true +type: page +title: subscribe +description: Subscribes to real-time notifications. +--- + +# Subscribe + +Subscribes by providing a set of filters: messages, document changes and, optionally, user events matching the provided filters will generate [real-time notifications](/core/2/api/essentials/notifications), sent to you in real-time by Kuzzle. + +## Arguments + +```java +public CompletableFuture subscribe( + final String index, + final String collection, + final ConcurrentHashMap filters, + final NotificationHandler handler, + final SubscribeOptions options +) throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|--------------|-----------------------------------------|----------------------------------------------------------------------------------------------------------------| +| `index` |
String/pre>                       | Index name                                                                                                     |
+| `collection` | 
String
| Collection name | +| `filters` |
ConcurrentHashMap
| ConcurrentHashMap representing a set of filters following [Koncorde syntax](/core/2/guides/cookbooks/realtime-api/terms) | +| `handler` |
NotificationHandler
| Handler function to handle notifications | +| `options` |
SubscribeOptions

(`null`) | Subscription options | + +### handler + +Handler function that will be called each time a new notification is received. +The hanlder will receive a [Response](/sdk/java/3/essentials/realtime-notifications) as its only argument. + +### options + +A [SubscribeOptions](/sdk/java/3/core-classes/subscribe-options) object. + +## Return + +The room ID. + +## Usage + +_Simple subscription to document notifications_ + +<<< ./snippets/document-notifications.java + +_Subscription to document notifications with scope option_ + +<<< ./snippets/document-notifications-leave-scope.java + +_Subscription to message notifications_ + +<<< ./snippets/message-notifications.java + +_Subscription to user notifications_ + +<<< ./snippets/user-notifications.java diff --git a/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.java b/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.java new file mode 100644 index 00000000..ad787914 --- /dev/null +++ b/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.java @@ -0,0 +1,38 @@ +SubscribeOptions options = new SubscribeOptions(); +options.setSubscribeToSelf(true); +options.setScope(SubscribeOptions.Scope.ALL); + +ConcurrentHashMap filters = new ConcurrentHashMap<>(); +ConcurrentHashMap range = new ConcurrentHashMap<>(); +ConcurrentHashMap age = new ConcurrentHashMap<>(); + +age.put("lte", 20); +range.put("age", age); +filters.put("range", range); + +kuzzle.getRealtimeController().subscribe( + "nyc-open-data", + "yellow-taxi", + filters, + notification -> { + if (notification.scope.equals(SubscribeOptions.Scope.OUT.toString())) { + System.out.println("Document left the scope"); + } else { + System.out.println("Document moved in the scope"); + } + }, options).get(); + +ConcurrentHashMap document = new ConcurrentHashMap<>(); +document.put("age", 19); +ConcurrentHashMap query = new ConcurrentHashMap<>(); +query.put("controller", "document"); +query.put("action", "create"); +query.put("index", "nyc-open-data"); +query.put("collection", "yellow-taxi"); +query.put("_id", "nina-vkote"); +query.put("body", document); +kuzzle.query(query).get(); + +query.put("action", "update"); +document.put("age", 42); +kuzzle.query(query).get(); \ No newline at end of file diff --git a/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.test.yml b/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.test.yml new file mode 100644 index 00000000..23670860 --- /dev/null +++ b/doc/3/controllers/realtime/subscribe/snippets/document-notifications-leave-scope.test.yml @@ -0,0 +1,10 @@ +name: Realtime#Subscribe-documents-leave-scope +description: Subscribes to documents leaving the scope. +hooks: + before: | + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi/ + curl -X DELETE kuzzle:7512/nyc-open-data/yellow-taxi/nina-vkote + after: +template: default +expected: Document\ moved\ in\ the\ scope \ No newline at end of file diff --git a/doc/3/controllers/realtime/subscribe/snippets/document-notifications.java b/doc/3/controllers/realtime/subscribe/snippets/document-notifications.java new file mode 100644 index 00000000..b7b5573e --- /dev/null +++ b/doc/3/controllers/realtime/subscribe/snippets/document-notifications.java @@ -0,0 +1,29 @@ +SubscribeOptions options = new SubscribeOptions(); +options.setSubscribeToSelf(true); + +ConcurrentHashMap filters = new ConcurrentHashMap<>(); +filters.put("exists", "name"); + +ConcurrentHashMap document = new ConcurrentHashMap<>(); +document.put("name", "nina-vkote"); + +kuzzle.getRealtimeController().subscribe( +"nyc-open-data", +"yellow-taxi", +filters, +notification -> { + if (notification.scope.equals(SubscribeOptions.Scope.IN.toString())) { + System.out.println("Document entered the scope"); + } else { + System.out.println("Document left the scope"); + } +}).get(); + +ConcurrentHashMap query = new ConcurrentHashMap<>(); +query.put("controller", "document"); +query.put("action", "create"); +query.put("index", "nyc-open-data"); +query.put("collection", "yellow-taxi"); +query.put("_id", "nina-vkote"); +query.put("body", document); +kuzzle.query(query).get(); \ No newline at end of file diff --git a/doc/3/controllers/realtime/subscribe/snippets/document-notifications.test.yml b/doc/3/controllers/realtime/subscribe/snippets/document-notifications.test.yml new file mode 100644 index 00000000..ae39d8d5 --- /dev/null +++ b/doc/3/controllers/realtime/subscribe/snippets/document-notifications.test.yml @@ -0,0 +1,10 @@ +name: Realtime#Subscribe-documents +description: Subscribes to document notifications. +hooks: + before: | + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi/ + curl -X DELETE kuzzle:7512/nyc-open-data/yellow-taxi/nina-vkote + after: +template: default +expected: Document entered the scope \ No newline at end of file diff --git a/doc/3/core-classes/subscribe-options/index.md b/doc/3/core-classes/subscribe-options/index.md new file mode 100644 index 00000000..f166e69d --- /dev/null +++ b/doc/3/core-classes/subscribe-options/index.md @@ -0,0 +1,28 @@ +--- +code: true +type: page +title: SubscribeOptions +description: SubscribeOptions class documentation +order: 110 +--- + +# SubscribeOptions + +This class represents the options usable with the [RealtimeController.subscribe](/sdk/java/3/controllers/realtime/subscribe) method. + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.Options.SubscribeOptions; +``` + +## Properties + +| Property | Type
(default) | Description | writable | +|----------|--------------------|------------------| ------- | +| `Scope` |
Scope

(`ALL`) | Subscribes to document entering or leaving the scope
Possible values: `ALL`, `IN`, `OUT`, `NONE`| yes | +| `Users` |
Users

(`NONE`) | Subscribes to users entering or leaving the room
Possible values: `ALL`, `IN`, `OUT`, `NONE`| yes | +| `SubscribeToSelf` |
boolean

(`true`) | Subscribes to notifications fired by our own queries | yes | +| `Volatile` |
ConcurrentHashMap

(`null`) | ConcurrentHashMap representing subscription information, used in [user join/leave notifications](/core/2/api/essentials/volatile-data) |yes | diff --git a/doc/3/essentials/realtime-notifications/index.md b/doc/3/essentials/realtime-notifications/index.md new file mode 100644 index 00000000..cddb2c16 --- /dev/null +++ b/doc/3/essentials/realtime-notifications/index.md @@ -0,0 +1,32 @@ +--- +code: false +type: page +title: Realtime notifications +description: List of realtime notifications sent by Kuzzle +order: 300 +--- + +# Notifications + +The [RealtimeController.subscribe](/sdk/java/3/controllers/realtime/subscribe) method takes a handler argument, called with a [Response](/sdk/java/3/core-classes/response) object, whose content of the `Result` property depends on the type of notification received. + +## Document & messages + +These notifications represent [documents changes & messages](/core/2/api/essentials/notifications#documents-changes-messages). + +The `Result` ConcurrentHashMap is the notification content, and it has the following structure: + +| Property | Type | Description | +| --------- | ----------------- | --------------------------------------------------------------------------------------- | +| `_id` |
String
| Document unique ID
`null` if the notification is from a real-time message | +| `_source` |
ConcurrentHashMap
| Message or full document content. Not present if the event is about a document deletion | + +## User + +These notifications represent [user events](/core/2/api/essentials/notifications#user-notification). + +The `Result` JObject is the notification content, and it has the following structure: + +| Property | Type | Description | +| -------- | ----------------- | -------------------------------------------------- | +| `count` |
Long
| Updated users count sharing that same subscription | diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java new file mode 100644 index 00000000..eae90e18 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -0,0 +1,101 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Handlers.NotificationHandler; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SubscribeOptions; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class RealtimeController extends BaseController { + private class Subscription { + public boolean subscribeToSelf; + public NotificationHandler handler; + + public Subscription(final boolean subscribeToSelf, final NotificationHandler handler) { + this.subscribeToSelf = subscribeToSelf; + this.handler = handler; + } + } + + private ConcurrentHashMap> subscriptions = new ConcurrentHashMap<>(); + + public RealtimeController(Kuzzle kuzzle) { + super(kuzzle); + kuzzle.register(Event.unhandledResponse, args -> { + Response response = (Response) args[0]; + + if (response.error != null && response.error.id.equals("security.token.expired")) { + kuzzle.trigger(Event.tokenExpired); + return; + } + + String sdkInstanceId = ""; + if (response.Volatile != null) { + sdkInstanceId = response.Volatile.get("sdkInstanceId").toString(); + } + + ArrayList subs = RealtimeController.this.subscriptions.get(((Response) args[0]).room); + + if (subs != null) { + final String instanceId = sdkInstanceId; + subs.forEach(sub -> { + if (sub != null && (instanceId.equals(kuzzle.instanceId) && sub.subscribeToSelf || !instanceId.equals(kuzzle.instanceId))) { + sub.handler.run(response); + } + }); + } + }); + } + + public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler, final SubscribeOptions options) throws NotConnectedException, InternalException { + ConcurrentHashMap queryOptions = new ConcurrentHashMap<>(); + boolean subscribeToSelf = true; + + synchronized (RealtimeController.class) { + if (options != null) { + subscribeToSelf = options.isSubscribeToSelf(); + queryOptions = options.toHashMap(); + } + } + + KuzzleMap query = new KuzzleMap(queryOptions) + .put("controller", "realtime") + .put("action", "subscribe") + .put("index", index) + .put("collection", collection) + .put("body", filters); + + boolean finalSubscribeToSelf = subscribeToSelf; + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> { + String channel = ((ConcurrentHashMap) response.result).get("channel").toString(); + Subscription subscription = new Subscription( + options == null ? new SubscribeOptions().isSubscribeToSelf() : finalSubscribeToSelf, + handler + ); + + if (subscriptions.get(channel) == null) { + ArrayList item = new ArrayList<>(); + item.add(subscription); + subscriptions.put(channel, item); + } else { + subscriptions.get(channel).add(subscription); + } + + return ((ConcurrentHashMap) response.result).get("roomId").toString(); + }); + } + + public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler) throws NotConnectedException, InternalException { + return this.subscribe(index, collection, filters, handler, null); + } +} diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java index 5dd0e94f..882d1e01 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/Responses/Response.java @@ -111,7 +111,7 @@ public void fromMap(ConcurrentHashMap map) protocol = kuzzleMap.getString("protocol"); scope = kuzzleMap.getString("scope"); state = kuzzleMap.getString("state"); - timestamp = (Long) kuzzleMap.getNumber("timestamp"); + timestamp = (kuzzleMap.getNumber("timestamp") == null ? null : kuzzleMap.getNumber("timestamp").longValue()); type = kuzzleMap.getString("type"); } diff --git a/src/main/java/io/kuzzle/sdk/Handlers/NotificationHandler.java b/src/main/java/io/kuzzle/sdk/Handlers/NotificationHandler.java new file mode 100644 index 00000000..0029030c --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Handlers/NotificationHandler.java @@ -0,0 +1,7 @@ +package io.kuzzle.sdk.Handlers; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +public interface NotificationHandler { + void run(Response notification); +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 3acb9446..e2ce0d36 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk; +import io.kuzzle.sdk.API.Controllers.RealtimeController; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.API.Controllers.AuthController; @@ -55,6 +56,8 @@ public class Kuzzle extends EventManager { protected ConcurrentHashMap> requests = new ConcurrentHashMap<>(); + private RealtimeController realtimeController; + /** * Initialize a new instance of Kuzzle * @@ -70,6 +73,20 @@ public AuthController getAuthController() { return new AuthController(this); } + /** + * @return RealtimeController + */ + public RealtimeController getRealtimeController() { + if (this.realtimeController == null) { + synchronized (Kuzzle.class) { + if (this.realtimeController == null) { + this.realtimeController = new RealtimeController(this); + } + } + } + return this.realtimeController; + } + /** * Initialize a new instance of Kuzzle * @@ -125,16 +142,15 @@ public void disconnect() { * @param payload Raw API Response */ protected void onResponseReceived(final Object... payload) { - final Response response = new Response(); try { response.fromMap(JsonSerializer.deserialize(payload[0].toString())); - } catch (final InternalException e) { + } catch (final Exception e) { e.printStackTrace(); return; } - if (response.room == null || !requests.containsKey(response.room)) { + if (requests != null && (response.room == null || !requests.containsKey(response.room))) { super.trigger(Event.unhandledResponse, response); return; } diff --git a/src/main/java/io/kuzzle/sdk/Options/SubscribeOptions.java b/src/main/java/io/kuzzle/sdk/Options/SubscribeOptions.java new file mode 100644 index 00000000..8ba87018 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/SubscribeOptions.java @@ -0,0 +1,102 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; + +public class SubscribeOptions { + public enum Scope { + ALL("all"), + IN("in"), + OUT("out"), + NONE("none"); + + private final String label; + private Scope(final String label) { + this.label = label; + } + + @Override + public String toString() { + return this.label; + } + } + public enum Users { + ALL("all"), + IN("in"), + OUT("out"), + NONE("none"); + + private final String label; + private Users(final String label) { + this.label = label; + } + + @Override + public String toString() { + return this.label; + } + } + private Scope scope = Scope.ALL; + private Users users = Users.NONE; + private boolean subscribeToSelf = true; + private ConcurrentHashMap volatiles = new ConcurrentHashMap<>(); + + /** + * Constructor + */ + public SubscribeOptions() {} + + /** + * Copy constructor + * + * @param options + */ + public SubscribeOptions(SubscribeOptions options) { + this.scope = options.getScope(); + this.users = options.getUsers(); + this.subscribeToSelf = options.isSubscribeToSelf(); + this.volatiles = options.getVolatiles(); + } + + public Scope getScope() { + return scope; + } + + public void setScope(Scope scope) { + this.scope = scope; + } + + public Users getUsers() { + return users; + } + + public void setUsers(Users users) { + this.users = users; + } + + public boolean isSubscribeToSelf() { + return subscribeToSelf; + } + + public void setSubscribeToSelf(boolean subscribeToSelf) { + this.subscribeToSelf = subscribeToSelf; + } + + public ConcurrentHashMap getVolatiles() { + return volatiles; + } + + public void setVolatiles(ConcurrentHashMap volatiles) { + this.volatiles = volatiles; + } + + public ConcurrentHashMap toHashMap() { + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + options.put("scope", this.scope.toString()); + options.put("users", this.users.toString()); + options.put("subscribeToSelf", this.subscribeToSelf); + options.put("volatile", this.volatiles); + + return options; + } +} diff --git a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java new file mode 100644 index 00000000..d8859ef1 --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java @@ -0,0 +1,86 @@ +package io.kuzzle.test.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Handlers.NotificationHandler; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SubscribeOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class RealtimeControllerTest { + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void subscribeTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getRealtimeController().subscribe("index", "collection", new ConcurrentHashMap<>(), notificationHandler, new SubscribeOptions()); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("subscribe", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("index")); + assertEquals("collection", ((KuzzleMap) arg.getValue()).getString("collection")); + } + + @Test + public void notificationHandlerTest() throws NotConnectedException, InternalException, InterruptedException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + Response response = new Response(); + response.room = "a-room"; + response.result = new ConcurrentHashMap<>(); + ((ConcurrentHashMap)response.result).put("roomId", "a-room"); + ((ConcurrentHashMap)response.result).put("channel", "a-room"); + + CompletableFuture queryResponse = new CompletableFuture(); + + doReturn(queryResponse).when(kuzzleSpy).query(any(ConcurrentHashMap.class)); + + kuzzleSpy.getRealtimeController().subscribe("index", "collection", new ConcurrentHashMap<>(), notificationHandler, new SubscribeOptions()); + queryResponse.complete(response); + Thread.sleep(1000); + kuzzleSpy.trigger(Event.unhandledResponse, response); + verify(notificationHandler).run(any(Response.class)); + } + + @Test + public void notificationHandlerWithoutSubscribeToSelfTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + Response response = new Response(); + response.room = "a-room"; + response.result = new ConcurrentHashMap<>(); + ((ConcurrentHashMap)response.result).put("roomId", "a-room"); + ((ConcurrentHashMap)response.result).put("channel", "a-room"); + response.Volatile = new ConcurrentHashMap<>(); + response.Volatile.put("sdkInstanceId", kuzzleSpy.instanceId); + + CompletableFuture queryResponse = new CompletableFuture(); + + doReturn(queryResponse).when(kuzzleSpy).query(any(ConcurrentHashMap.class)); + + SubscribeOptions options = new SubscribeOptions(); + options.setSubscribeToSelf(false); + kuzzleSpy.getRealtimeController().subscribe("index", "collection", new ConcurrentHashMap<>(), notificationHandler, options); + queryResponse.complete(response); + kuzzleSpy.trigger(Event.unhandledResponse, response); + verify(notificationHandler, never()).run(any(Response.class)); + } +} From 045c2e916b3c56b51c8a826ec76e516388bddd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Tue, 25 Feb 2020 16:31:17 +0100 Subject: [PATCH 044/134] Add Index controller (#57) ## What does this PR do ? Add Index Controller. ### How should this be manually tested? ```sh ./gradlew test ``` ### Other changes - Run documentation's tests snippet in travis - Fix a typo in enum `KuzzleExceptionCode.MISSING_QUERY` --- .travis.yml | 1 - doc/3/controllers/index/create/index.md | 25 +++++ .../index/create/snippets/create.java | 1 + .../index/create/snippets/create.test.yml | 8 ++ doc/3/controllers/index/delete/index.md | 25 +++++ .../index/delete/snippets/delete.java | 1 + .../index/delete/snippets/delete.test.yml | 8 ++ doc/3/controllers/index/exists/index.md | 29 ++++++ .../index/exists/snippets/exists.java | 1 + .../index/exists/snippets/exists.test.yml | 8 ++ doc/3/controllers/index/index.md | 8 ++ doc/3/controllers/index/list/index.md | 25 +++++ .../controllers/index/list/snippets/list.java | 1 + .../index/list/snippets/list.test.yml | 10 ++ doc/3/controllers/index/m-delete/index.md | 29 ++++++ .../index/m-delete/snippets/mDelete.java | 3 + .../index/m-delete/snippets/mDelete.test.yml | 8 ++ .../sdk/API/Controllers/IndexController.java | 98 +++++++++++++++++++ .../sdk/Exceptions/KuzzleExceptionCode.java | 2 +- src/main/java/io/kuzzle/sdk/Kuzzle.java | 13 ++- .../API/Controllers/IndexControllerTest.java | 98 +++++++++++++++++++ 21 files changed, 399 insertions(+), 3 deletions(-) create mode 100644 doc/3/controllers/index/create/index.md create mode 100644 doc/3/controllers/index/create/snippets/create.java create mode 100644 doc/3/controllers/index/create/snippets/create.test.yml create mode 100644 doc/3/controllers/index/delete/index.md create mode 100644 doc/3/controllers/index/delete/snippets/delete.java create mode 100644 doc/3/controllers/index/delete/snippets/delete.test.yml create mode 100644 doc/3/controllers/index/exists/index.md create mode 100644 doc/3/controllers/index/exists/snippets/exists.java create mode 100644 doc/3/controllers/index/exists/snippets/exists.test.yml create mode 100644 doc/3/controllers/index/index.md create mode 100644 doc/3/controllers/index/list/index.md create mode 100644 doc/3/controllers/index/list/snippets/list.java create mode 100644 doc/3/controllers/index/list/snippets/list.test.yml create mode 100644 doc/3/controllers/index/m-delete/index.md create mode 100644 doc/3/controllers/index/m-delete/snippets/mDelete.java create mode 100644 doc/3/controllers/index/m-delete/snippets/mDelete.test.yml create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/IndexController.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/IndexControllerTest.java diff --git a/.travis.yml b/.travis.yml index 22b7f129..7ebf0f8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,6 @@ jobs: script: - docker-compose -f .ci/doc/docker-compose.yml run doc-tests index - - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io if: type = push AND branch =~ /^[0-9]+-dev$/ diff --git a/doc/3/controllers/index/create/index.md b/doc/3/controllers/index/create/index.md new file mode 100644 index 00000000..8f4d03d6 --- /dev/null +++ b/doc/3/controllers/index/create/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: create +description: Creates an index. +--- + +# create + +Creates a new index in Kuzzle + +## Arguments + +```java +CompletableFuture create(final String index) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|----------|-------------------|-------------| +| `index` |
String
| Index name | + +## Usage + +<<< ./snippets/create.java diff --git a/doc/3/controllers/index/create/snippets/create.java b/doc/3/controllers/index/create/snippets/create.java new file mode 100644 index 00000000..5fa80ccf --- /dev/null +++ b/doc/3/controllers/index/create/snippets/create.java @@ -0,0 +1 @@ +kuzzle.getIndexController().create("nyc-open-data").get(); diff --git a/doc/3/controllers/index/create/snippets/create.test.yml b/doc/3/controllers/index/create/snippets/create.test.yml new file mode 100644 index 00000000..dd0311dc --- /dev/null +++ b/doc/3/controllers/index/create/snippets/create.test.yml @@ -0,0 +1,8 @@ +--- +name: Index#CreateAsync +description: Creates a new index. +hooks: + before: curl -X DELETE kuzzle:7512/nyc-open-data + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/index/delete/index.md b/doc/3/controllers/index/delete/index.md new file mode 100644 index 00000000..821b3603 --- /dev/null +++ b/doc/3/controllers/index/delete/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: delete +description: Deletes an index. +--- + +# delete + +Deletes an entire index from Kuzzle. + +## Arguments + +```java +CompletableFuture delete(final String index) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|----------|-------------------|-------------| +| `index` |
String
| Index name | + +## Usage + +<<< ./snippets/delete.java diff --git a/doc/3/controllers/index/delete/snippets/delete.java b/doc/3/controllers/index/delete/snippets/delete.java new file mode 100644 index 00000000..b126d403 --- /dev/null +++ b/doc/3/controllers/index/delete/snippets/delete.java @@ -0,0 +1 @@ +kuzzle.getIndexController().delete("nyc-open-data").get(); diff --git a/doc/3/controllers/index/delete/snippets/delete.test.yml b/doc/3/controllers/index/delete/snippets/delete.test.yml new file mode 100644 index 00000000..5f055e24 --- /dev/null +++ b/doc/3/controllers/index/delete/snippets/delete.test.yml @@ -0,0 +1,8 @@ +--- +name: Index#Delete +description: Delete an index. +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/index/exists/index.md b/doc/3/controllers/index/exists/index.md new file mode 100644 index 00000000..69e9c014 --- /dev/null +++ b/doc/3/controllers/index/exists/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: exists +description: Check for index existence. +--- + +# exists + +Checks if the given index exists in Kuzzle. + +## Arguments + +```java +CompletableFuture exists(final String index) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|----------|-------------------|-------------| +| `index` |
String
| Index name | + +## Return + +Returns a `boolean` that indicates whether the index exists or not. + +## Usage + +<<< ./snippets/exists.java diff --git a/doc/3/controllers/index/exists/snippets/exists.java b/doc/3/controllers/index/exists/snippets/exists.java new file mode 100644 index 00000000..557cb953 --- /dev/null +++ b/doc/3/controllers/index/exists/snippets/exists.java @@ -0,0 +1 @@ +Boolean result = kuzzle.getIndexController().exists("nyc-open-data").get(); diff --git a/doc/3/controllers/index/exists/snippets/exists.test.yml b/doc/3/controllers/index/exists/snippets/exists.test.yml new file mode 100644 index 00000000..d32f6f3a --- /dev/null +++ b/doc/3/controllers/index/exists/snippets/exists.test.yml @@ -0,0 +1,8 @@ +--- +name: Index#ExistsAsync +description: Test if an index exists. +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create + after: +template: print-result +expected: true \ No newline at end of file diff --git a/doc/3/controllers/index/index.md b/doc/3/controllers/index/index.md new file mode 100644 index 00000000..8d74e9c0 --- /dev/null +++ b/doc/3/controllers/index/index.md @@ -0,0 +1,8 @@ +--- +code: true +type: branch +title: Index +description: Index Controller +--- + +# Index Controller diff --git a/doc/3/controllers/index/list/index.md b/doc/3/controllers/index/list/index.md new file mode 100644 index 00000000..ddf5ee86 --- /dev/null +++ b/doc/3/controllers/index/list/index.md @@ -0,0 +1,25 @@ +--- +code: true +type: page +title: list +description: Lists the indexes. +--- + +# list + +Gets the complete list of indexes handled by Kuzzle. + +## Arguments + +```java +CompletableFuture> list() + throws NotConnectedException, InternalException +``` + +## Return + +Returns an `ArrayList` containing the list of index names handled by Kuzzle. + +## Usage + +<<< ./snippets/list.java diff --git a/doc/3/controllers/index/list/snippets/list.java b/doc/3/controllers/index/list/snippets/list.java new file mode 100644 index 00000000..eb4c1cc4 --- /dev/null +++ b/doc/3/controllers/index/list/snippets/list.java @@ -0,0 +1 @@ +ArrayList result = kuzzle.getIndexController().list().get(); diff --git a/doc/3/controllers/index/list/snippets/list.test.yml b/doc/3/controllers/index/list/snippets/list.test.yml new file mode 100644 index 00000000..4c703391 --- /dev/null +++ b/doc/3/controllers/index/list/snippets/list.test.yml @@ -0,0 +1,10 @@ +--- +name: Index#ListAsync +description: List indexes handled by Kuzzle. +hooks: + before: | + curl -X POST kuzzle:7512/admin/_resetDatabase + curl -X POST kuzzle:7512/nyc-open-data/_create + after: +template: print-result +expected: ["nyc-open-data"] diff --git a/doc/3/controllers/index/m-delete/index.md b/doc/3/controllers/index/m-delete/index.md new file mode 100644 index 00000000..212edebc --- /dev/null +++ b/doc/3/controllers/index/m-delete/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: mDelete +description: Deletes multiple indexes. +--- + +# mDelete + +Deletes multiple indexes. + +## Arguments + +```java +CompletableFuture> mDelete(final ArrayList indexes) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|-----------|-------------------|-----------------------| +| `indexes` |
ArrayList
| List of indexes names | + +## Return + +Returns an `ArrayList` containing the list of indexes names deleted. + +## Usage + +<<< ./snippets/mDelete.java diff --git a/doc/3/controllers/index/m-delete/snippets/mDelete.java b/doc/3/controllers/index/m-delete/snippets/mDelete.java new file mode 100644 index 00000000..9ac9c0be --- /dev/null +++ b/doc/3/controllers/index/m-delete/snippets/mDelete.java @@ -0,0 +1,3 @@ +ArrayList indexes = new ArrayList<>(); + indexes.add("nyc-open-data"); +ArrayList result = kuzzle.getIndexController().mDelete(indexes).get(); diff --git a/doc/3/controllers/index/m-delete/snippets/mDelete.test.yml b/doc/3/controllers/index/m-delete/snippets/mDelete.test.yml new file mode 100644 index 00000000..00423931 --- /dev/null +++ b/doc/3/controllers/index/m-delete/snippets/mDelete.test.yml @@ -0,0 +1,8 @@ +--- +name: Index#MDeleteAsync +description: Delete multiple indexes. +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create ; curl -X POST kuzzle:7512/mtp-open-data/_create + after: +template: print-result +expected: ["nyc-open-data"] \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/IndexController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/IndexController.java new file mode 100644 index 00000000..71c529c9 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/IndexController.java @@ -0,0 +1,98 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; + +public class IndexController extends BaseController { + public IndexController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Creates a new index in Kuzzle via the persistence engine. + * + * @param index + * @return A CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture create(final String index) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "index") + .put("action", "create") + .put("index", index)) + .thenApplyAsync((response) -> null); + } + + /** + * Deletes an index in Kuzzle via the persistence engine. + * + * @param index + * @return A CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture delete(final String index) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "index") + .put("action", "delete") + .put("index", index)) + .thenApplyAsync((response) -> null); + } + + /** + * Checks if an index exists in the Kuzzle persistence engine. + * + * @param index + * @return A CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture exists(final String index) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "index") + .put("action", "exists") + .put("index", index)) + .thenApplyAsync((response) -> (Boolean) response.result); + } + + /** + * Lists indexes from the Kuzzle persistence engine. + * + * @return A CompletableFuture> + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> list() throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "index") + .put("action", "list")) + .thenApplyAsync((response) -> (((KuzzleMap) response.result).getArrayList("indexes"))); + } + + /** + * Deletes multiple indexes from the Kuzzle persistence engine. + * + * @param indexes + * @return A CompletableFuture> + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> mDelete(final ArrayList indexes) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "index") + .put("action", "mDelete") + .put("body", new KuzzleMap().put("indexes", indexes))) + .thenApplyAsync((response) -> (((KuzzleMap) response.result).getArrayList("deleted"))); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java index c490c9ec..a4edf6f1 100644 --- a/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java +++ b/src/main/java/io/kuzzle/sdk/Exceptions/KuzzleExceptionCode.java @@ -2,7 +2,7 @@ public enum KuzzleExceptionCode { MISSING_REQUESTID(0, "Missing field requestId"), - MSSING_QUERY(400, "You must provide a query"), + MISSING_QUERY(400, "You must provide a query"), NOT_CONNECTED(500, "Not connected."), CONNECTION_LOST(500, "Connection lost"), WRONG_VOLATILE_TYPE( diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index e2ce0d36..062a2b4c 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk; +import io.kuzzle.sdk.API.Controllers.IndexController; import io.kuzzle.sdk.API.Controllers.RealtimeController; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; @@ -69,10 +70,20 @@ public Kuzzle(final AbstractProtocol networkProtocol) this(networkProtocol, new KuzzleOptions()); } + /** + * @return The AuthController + */ public AuthController getAuthController() { return new AuthController(this); } + /** + * @return The IndexController + */ + public IndexController getIndexController() { + return new IndexController(this); + } + /** * @return RealtimeController */ @@ -200,7 +211,7 @@ public CompletableFuture query( final ConcurrentHashMap query) throws InternalException, NotConnectedException { if (query == null) { - throw new InternalException(KuzzleExceptionCode.MSSING_QUERY); + throw new InternalException(KuzzleExceptionCode.MISSING_QUERY); } if (networkProtocol.getState() == ProtocolState.CLOSE) { diff --git a/src/test/java/io/kuzzle/test/API/Controllers/IndexControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/IndexControllerTest.java new file mode 100644 index 00000000..23d79f4f --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/IndexControllerTest.java @@ -0,0 +1,98 @@ +package io.kuzzle.test.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Events.Event; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class IndexControllerTest { + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void createTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getIndexController().create("my-index"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("create", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("my-index", ((KuzzleMap) arg.getValue()).getString("index")); + } + + @Test + public void deleteTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getIndexController().delete("my-index"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("delete", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("my-index", ((KuzzleMap) arg.getValue()).getString("index")); + } + + @Test + public void existsTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getIndexController().exists("my-index"); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("exists", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("my-index", ((KuzzleMap) arg.getValue()).getString("index")); + } + + @Test + public void listTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getIndexController().list(); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("list", ((KuzzleMap) arg.getValue()).getString("action")); + } + + @Test + public void mDeleteTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ArrayList indexes = new ArrayList<>(); + indexes.add("index1"); + indexes.add("index2"); + + kuzzleSpy.getIndexController().mDelete(indexes); + verify(kuzzleSpy, times(1)).query((KuzzleMap) arg.capture()); + + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("mDelete", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("index1", ((ArrayList)((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("indexes")).get(0)); + assertEquals("index2", ((ArrayList)((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("indexes")).get(1)); + } +} From a7f58fb97f3ed5737eaee1016a003f5269f25e55 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 26 Feb 2020 13:36:37 +0100 Subject: [PATCH 045/134] requested changes --- .../document/create/snippets/create.java | 4 +-- .../API/Controllers/DocumentController.java | 7 ++--- .../DocumentTest/DocumentTest.java | 31 +++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/doc/3/controllers/document/create/snippets/create.java b/doc/3/controllers/document/create/snippets/create.java index e8eaf818..df060d93 100644 --- a/doc/3/controllers/document/create/snippets/create.java +++ b/doc/3/controllers/document/create/snippets/create.java @@ -3,7 +3,5 @@ document.put("firstname", "John"); document.put("lastname", "Smith"); - ConcurrentHashMap options = new ConcurrentHashMap<>(); - - kuzzle.getDocumentController().create("nyc-open-data", "yellow-taxi", document, "some-id", options) + kuzzle.getDocumentController().create("nyc-open-data", "yellow-taxi", document) .get(); diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index a4dbe99e..9c23dba9 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -41,8 +41,8 @@ public CompletableFuture> create( .put("controller", "document") .put("action", "create") .put("body", document) - .put("_id", _options.getString("_id")) - .put("waitForRefresh", _options.getBoolean("waitForRefresh")); + .put("_id", _options == null ? null : _options.getString("_id")) + .put("waitForRefresh", _options == null ? null : _options.getBoolean("waitForRefresh")); return kuzzle .query(query) @@ -65,8 +65,7 @@ public CompletableFuture> create( final String collection, final ConcurrentHashMap document) throws NotConnectedException, InternalException { - final ConcurrentHashMap options = new ConcurrentHashMap<>(); - return this.create(index, collection, document, options); + return this.create(index, collection, document, null); } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index bb30f7f0..b98a133b 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -35,12 +35,43 @@ public void createDocumentTest() throws NotConnectedException, InternalException ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + ConcurrentHashMap options = new ConcurrentHashMap<>(); + options.put("_id", "some-id"); + options.put("waitForRefresh", true); + + kuzzleMock.getDocumentController().create(index, collection, document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test + public void createDocumentNoOptionsTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + kuzzleMock.getDocumentController().create(index, collection, document); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } From fbaf2c4c92156985159eb8ddc9a19592957c56c1 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 26 Feb 2020 15:40:40 +0100 Subject: [PATCH 046/134] waitForRefresh type --- doc/3/controllers/document/create/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index 845207ac..82d9f959 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -42,7 +42,7 @@ throws NotConnectedException, InternalException | Arguments | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | | `id` |
String
(optional) | Document identifier. Auto-generated if not specified | -| `waitForRefresh` |
boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| ## Return From 23fa17df0bf5df6b4c186768237b780f1437d7ba Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 26 Feb 2020 15:47:27 +0100 Subject: [PATCH 047/134] requested changes --- .../document/delete/snippets/delete.java | 2 +- .../API/Controllers/DocumentController.java | 2 +- .../DocumentTest/DocumentTest.java | 22 ++++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/3/controllers/document/delete/snippets/delete.java b/doc/3/controllers/document/delete/snippets/delete.java index 0f98c216..433a71de 100644 --- a/doc/3/controllers/document/delete/snippets/delete.java +++ b/doc/3/controllers/document/delete/snippets/delete.java @@ -1,3 +1,3 @@ - kuzzle.getDocumentController().delete("nyc-open-data", "yellow-taxi", "some_id") + kuzzle.getDocumentController().delete("nyc-open-data", "yellow-taxi", "some-id") .get(); diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index b46fe3af..c4a32edf 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -62,6 +62,6 @@ public CompletableFuture> delete( final String collection, final String id) throws NotConnectedException, InternalException { - return this.delete(index, collection, id, false); + return this.delete(index, collection, id, null); } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9579eb24..af7b8511 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -23,7 +23,26 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); @Test - public void deleteDocumentTest() throws NotConnectedException, InternalException { + public void deleteDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().delete(index, collection, "some-id", true); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + } + + @Test + public void deleteDocumentTestB() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; @@ -38,6 +57,7 @@ public void deleteDocumentTest() throws NotConnectedException, InternalException assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); } @Test(expected = NotConnectedException.class) From 01914efe2f4cfffd9b962e5a372abc1a5dd013f0 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 27 Feb 2020 10:14:00 +0100 Subject: [PATCH 048/134] Update doc/3/controllers/document/delete/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/delete/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/delete/index.md b/doc/3/controllers/document/delete/index.md index 3e88ee34..e88821c6 100644 --- a/doc/3/controllers/document/delete/index.md +++ b/doc/3/controllers/document/delete/index.md @@ -2,7 +2,7 @@ code: true type: page title: delete -description: Deletes a new document +description: Deletes a document --- # delete From b77b51d128eebf4d5e3f2e0c3a07ee6bca91e233 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 27 Feb 2020 10:16:24 +0100 Subject: [PATCH 049/134] Update doc/3/controllers/document/create/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/create/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index 82d9f959..4bb825f0 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -32,7 +32,7 @@ throws NotConnectedException, InternalException | ------------------ | -------------------------------------------- | --------------------------------- | | `index` |
String
| Index | | `collection` |
String
| Collection | -| `document` |
ConcurrentHashMap
| Content of the document to create | +| `document` |
ConcurrentHashMap
| Document content | | `options` |
ConcurrentHashMap
| Optional parameters | --- From 5c64a9a8302291b44ee14a00d7d4d74540ee4ac1 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 28 Feb 2020 13:11:18 +0100 Subject: [PATCH 050/134] @aschen requested change --- .../document/create/snippets/create.java | 15 +++++++++++++-- .../document/create/snippets/create.test.yml | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/3/controllers/document/create/snippets/create.java b/doc/3/controllers/document/create/snippets/create.java index df060d93..b5369d3a 100644 --- a/doc/3/controllers/document/create/snippets/create.java +++ b/doc/3/controllers/document/create/snippets/create.java @@ -1,7 +1,18 @@ ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("firstname", "John"); - document.put("lastname", "Smith"); - kuzzle.getDocumentController().create("nyc-open-data", "yellow-taxi", document) + ConcurrentHashMap result = kuzzle.getDocumentController().create("nyc-open-data", "yellow-taxi", document) .get(); + +/* result = + { + _source= + { + firstname=John, + _kuzzle_info={ createdAt=1582891678488, author=-1 } + }, + _id=mDmyi3ABYMAjFJ_ZO-EZ, + _version=1 + } +*/ \ No newline at end of file diff --git a/doc/3/controllers/document/create/snippets/create.test.yml b/doc/3/controllers/document/create/snippets/create.test.yml index a9c129ba..823badff 100644 --- a/doc/3/controllers/document/create/snippets/create.test.yml +++ b/doc/3/controllers/document/create/snippets/create.test.yml @@ -6,5 +6,5 @@ hooks: curl -XPOST kuzzle:7512/nyc-open-data/_create curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi after: -template: default -expected: Success \ No newline at end of file +template: print-result +expected: "firstname=John" \ No newline at end of file From d3139fe9f4c83434d7be18529cf1f1af03cb8e47 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 09:55:27 +0100 Subject: [PATCH 051/134] doc --- doc/3/controllers/document/delete/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/delete/index.md b/doc/3/controllers/document/delete/index.md index e88821c6..67b309aa 100644 --- a/doc/3/controllers/document/delete/index.md +++ b/doc/3/controllers/document/delete/index.md @@ -7,7 +7,7 @@ description: Deletes a document # delete -Deletes a document in the provided index and collection. +Deletes a document. --- From 423d220379c3784c56916b0061c7ef65cd248db6 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 2 Mar 2020 10:46:53 +0100 Subject: [PATCH 052/134] Add document:mGet (#65) --- .ci/doc/templates/default.tpl.java | 1 + .ci/doc/templates/print-result-array.tpl.java | 29 +++++++++ doc/3/controllers/document/m-get/index.md | 47 ++++++++++++++ .../document/m-get/snippets/m-get.java | 37 +++++++++++ .../document/m-get/snippets/m-get.test.yml | 14 +++++ .../API/Controllers/DocumentController.java | 46 ++++++++++++++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 10 ++- .../DocumentTest/DocumentTest.java | 63 +++++++++++++++++++ 8 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 .ci/doc/templates/print-result-array.tpl.java create mode 100644 doc/3/controllers/document/m-get/index.md create mode 100644 doc/3/controllers/document/m-get/snippets/m-get.java create mode 100644 doc/3/controllers/document/m-get/snippets/m-get.test.yml create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java index 49b426c9..03d84d23 100644 --- a/.ci/doc/templates/default.tpl.java +++ b/.ci/doc/templates/default.tpl.java @@ -1,4 +1,5 @@ import io.kuzzle.sdk.Kuzzle; +import java.util.ArrayList; import io.kuzzle.sdk.Protocol.WebSocket; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Options.KuzzleOptions; diff --git a/.ci/doc/templates/print-result-array.tpl.java b/.ci/doc/templates/print-result-array.tpl.java new file mode 100644 index 00000000..9c751d0b --- /dev/null +++ b/.ci/doc/templates/print-result-array.tpl.java @@ -0,0 +1,29 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.ArrayList; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + kuzzle.connect(); + [snippet-code] + for (Object o : result.get("successes")) { + System.out.println(o); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/doc/3/controllers/document/m-get/index.md b/doc/3/controllers/document/m-get/index.md new file mode 100644 index 00000000..4c424036 --- /dev/null +++ b/doc/3/controllers/document/m-get/index.md @@ -0,0 +1,47 @@ +--- +code: true +type: page +title: mGet +description: Gets multiple documents +--- + +# mGet + +Gets multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mGet( + final String index, + final String collection, + final ArrayList ids) +throws NotConnectedException, InternalException + +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `ids` |
ArrayList
| Document IDs | +--- + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Document content | +| `_id` |
String
| Document ID | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +The `errors` array contain the IDs of not found documents. + +## Usage + +<<< ./snippets/m-get.java diff --git a/doc/3/controllers/document/m-get/snippets/m-get.java b/doc/3/controllers/document/m-get/snippets/m-get.java new file mode 100644 index 00000000..2e3ad1ab --- /dev/null +++ b/doc/3/controllers/document/m-get/snippets/m-get.java @@ -0,0 +1,37 @@ + final ArrayList ids = new ArrayList<>(); + ids.add("some-id"); + ids.add("some-id2"); + + ConcurrentHashMap> result = kuzzle.getDocumentController().mGet("nyc-open-data", "yellow-taxi", ids) + .get(); + +/* + result = + { + successes= + [ + { + result=created, + _source= + { + key=value, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=1 + }, + { + result=created, + _source= + { + key=value, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=1 + } + ], + errors=[] + } + +*/ \ No newline at end of file diff --git a/doc/3/controllers/document/m-get/snippets/m-get.test.yml b/doc/3/controllers/document/m-get/snippets/m-get.test.yml new file mode 100644 index 00000000..0ea219d0 --- /dev/null +++ b/doc/3/controllers/document/m-get/snippets/m-get.test.yml @@ -0,0 +1,14 @@ +name: document#mGet +description: Get multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + curl -XPOST -d '{"color":"purple"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id2/_create + after: +template: print-result-array +expected: + - "id=some-id, _version=1" + - "id=some-id2, _version=1" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java new file mode 100644 index 00000000..5b2271b3 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -0,0 +1,46 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class DocumentController extends BaseController { + public DocumentController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Gets multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param ids + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mGet( + final String index, + final String collection, + final ArrayList ids) throws NotConnectedException, InternalException { + + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mGet") + .put("body", new KuzzleMap().put("ids", ids)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 062a2b4c..2584a7c4 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -1,10 +1,11 @@ package io.kuzzle.sdk; +import io.kuzzle.sdk.API.Controllers.AuthController; +import io.kuzzle.sdk.API.Controllers.DocumentController; import io.kuzzle.sdk.API.Controllers.IndexController; import io.kuzzle.sdk.API.Controllers.RealtimeController; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; -import io.kuzzle.sdk.API.Controllers.AuthController; import io.kuzzle.sdk.CoreClasses.Task; import io.kuzzle.sdk.Exceptions.*; import io.kuzzle.sdk.Options.KuzzleOptions; @@ -77,6 +78,13 @@ public AuthController getAuthController() { return new AuthController(this); } + /** + * @return The DocumentController + */ + public DocumentController getDocumentController() { + return new DocumentController(this); + } + /** * @return The IndexController */ diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java new file mode 100644 index 00000000..5721cb3d --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -0,0 +1,63 @@ +package io.kuzzle.test.API.Controllers.DocumentTest; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; + +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class DocumentTest { + + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void mGetDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + final ArrayList ids = new ArrayList<>(); + ids.add("some-id1"); + ids.add("some-id2"); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mGet(index, collection, ids); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mGet"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + final ArrayList ids = new ArrayList<>(); + ids.add("some-id1"); + ids.add("some-id2"); + + kuzzleMock.getDocumentController().mGet(index, collection, ids); + } +} From fbbea5c325d6414e8d07da1710655223fccc09c2 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 10:52:37 +0100 Subject: [PATCH 053/134] doc --- doc/3/controllers/document/create/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index 4bb825f0..4c419622 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -7,7 +7,11 @@ description: Creates a new document # create -Creates a new document in the provided index and collection. +Creates a new document in the persistent data storage. + +Throws an error if the document already exists. + +The optional parameter `waitForRefresh` can be used with the value `true` in order to wait for the document to be indexed (indexed documents are available for `search`). --- From 7f65e16f4a39c102d84065f6970875ea2ec03db3 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 11:21:53 +0100 Subject: [PATCH 054/134] test [ci skip] --- .../API/Controllers/DocumentController.java | 97 +++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 9c23dba9..2b0639ef 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -14,58 +14,57 @@ public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document, - final ConcurrentHashMap options) throws NotConnectedException, InternalException { + // /** + // * Creates a document in a given collection and index. + // * + // * @param index + // * @param collection + // * @param document + // * @param options + // * @return a CompletableFuture + // * @throws NotConnectedException + // * @throws InternalException + // */ + // public CompletableFuture> create( + // final String index, + // final String collection, + // final ConcurrentHashMap document, + // final ConcurrentHashMap options) throws NotConnectedException, InternalException { - final KuzzleMap query = new KuzzleMap(); - final KuzzleMap _options = KuzzleMap - .from(options); + // final KuzzleMap query = new KuzzleMap(); + // final KuzzleMap _options = KuzzleMap + // .from(options); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "create") - .put("body", document) - .put("_id", _options == null ? null : _options.getString("_id")) - .put("waitForRefresh", _options == null ? null : _options.getBoolean("waitForRefresh")); + // query + // .put("index", index) + // .put("collection", collection) + // .put("controller", "document") + // .put("action", "create") + // .put("body", document) + // .put("_id", _options == null ? null : _options.getString("_id")) + // .put("waitForRefresh", _options == null ? null : _options.getBoolean("waitForRefresh")); - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } - - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { + // return kuzzle + // .query(query) + // .thenApplyAsync( + // (response) -> (ConcurrentHashMap) response.result); + // } - return this.create(index, collection, document, null); - } + // /** + // * Creates a document in a given collection and index. + // * + // * @param index + // * @param collection + // * @param document + // * @return a CompletableFuture + // * @throws NotConnectedException + // * @throws InternalException + // */ + // public CompletableFuture> create( + // final String index, + // final String collection, + // final ConcurrentHashMap document) throws NotConnectedException, InternalException { + // return this.create(index, collection, document, null); + // } } From b1b15524f2c3687152adcd140b48f9281c95a11d Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 11:28:03 +0100 Subject: [PATCH 055/134] GIT brained [ci skip] --- .../DocumentTest/DocumentTest.java | 138 +++++++++--------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index b98a133b..a38c0d72 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -22,73 +22,73 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - @Test - public void createDocumentTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("_id", "some-id"); - options.put("waitForRefresh", true); - - kuzzleMock.getDocumentController().create(index, collection, document, options); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } - - @Test - public void createDocumentNoOptionsTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().create(index, collection, document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } - - @Test(expected = NotConnectedException.class) - public void queryShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - kuzzleMock.getDocumentController().create(index, collection, document); - } + // @Test + // public void createDocumentTest() throws NotConnectedException, InternalException { + + // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; + + // ConcurrentHashMap document = new ConcurrentHashMap<>(); + // document.put("name", "Yoann"); + // document.put("nickname", "El angel de la muerte que hace el JAVA"); + + // ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + // ConcurrentHashMap options = new ConcurrentHashMap<>(); + // options.put("_id", "some-id"); + // options.put("waitForRefresh", true); + + // kuzzleMock.getDocumentController().create(index, collection, document, options); + // Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + // assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + // assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + // assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + // assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + // } + + // @Test + // public void createDocumentNoOptionsTest() throws NotConnectedException, InternalException { + + // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; + + // ConcurrentHashMap document = new ConcurrentHashMap<>(); + // document.put("name", "Yoann"); + // document.put("nickname", "El angel de la muerte que hace el JAVA"); + + // ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + // kuzzleMock.getDocumentController().create(index, collection, document); + // Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + // assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + // assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + // assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + // assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + // } + + // @Test(expected = NotConnectedException.class) + // public void queryShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + // AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + // Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + // Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; + + // ConcurrentHashMap document = new ConcurrentHashMap<>(); + // document.put("name", "Yoann"); + // document.put("nickname", "El angel de la muerte que hace el JAVA"); + + // kuzzleMock.getDocumentController().create(index, collection, document); + // } } From dc218708793aa773c6fde6c3a86aaae01de89dbc Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 11:33:30 +0100 Subject: [PATCH 056/134] update Kuzzle.java --- src/main/java/io/kuzzle/sdk/Kuzzle.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 9db240d2..696f0720 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -78,10 +78,6 @@ public AuthController getAuthController() { return new AuthController(this); } - public DocumentController getDocumentController() { - return new DocumentController(this); - } - /** * @return The DocumentController */ From 95a805c4459ffc77f76382925637dc5150544532 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 11:36:46 +0100 Subject: [PATCH 057/134] conflict [ci skip] --- .../API/Controllers/DocumentController.java | 96 +++++++++---------- src/main/java/io/kuzzle/sdk/Kuzzle.java | 4 - .../DocumentTest/DocumentTest.java | 74 +++++++------- 3 files changed, 85 insertions(+), 89 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index c4a32edf..134a59c0 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -10,58 +10,58 @@ import java.util.UUID; public class DocumentController extends BaseController { - public DocumentController(final Kuzzle kuzzle) { - super(kuzzle); - } + // public DocumentController(final Kuzzle kuzzle) { + // super(kuzzle); + // } - /** - * Deletes a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @param waitForRefresh - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> delete( - final String index, - final String collection, - final String id, - final Boolean waitForRefresh) throws NotConnectedException, InternalException { + // /** + // * Deletes a document in a given collection and index. + // * + // * @param index + // * @param collection + // * @param id + // * @param waitForRefresh + // * @return a CompletableFuture + // * @throws NotConnectedException + // * @throws InternalException + // */ + // public CompletableFuture> delete( + // final String index, + // final String collection, + // final String id, + // final Boolean waitForRefresh) throws NotConnectedException, InternalException { - final KuzzleMap query = new KuzzleMap(); + // final KuzzleMap query = new KuzzleMap(); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "delete") - .put("_id", id) - .put("waitForRefresh", waitForRefresh); + // query + // .put("index", index) + // .put("collection", collection) + // .put("controller", "document") + // .put("action", "delete") + // .put("_id", id) + // .put("waitForRefresh", waitForRefresh); - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } + // return kuzzle + // .query(query) + // .thenApplyAsync( + // (response) -> (ConcurrentHashMap) response.result); + // } - /** - * Deletes a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> delete( - final String index, - final String collection, - final String id) throws NotConnectedException, InternalException { + // /** + // * Deletes a document in a given collection and index. + // * + // * @param index + // * @param collection + // * @param id + // * @return a CompletableFuture + // * @throws NotConnectedException + // * @throws InternalException + // */ + // public CompletableFuture> delete( + // final String index, + // final String collection, + // final String id) throws NotConnectedException, InternalException { - return this.delete(index, collection, id, null); - } + // return this.delete(index, collection, id, null); + // } } diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 00289727..0f753bc8 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -78,10 +78,6 @@ public AuthController getAuthController() { return new AuthController(this); } - public DocumentController getDocumentController() { - return new DocumentController(this); - } - /** * @return The IndexController */ diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index af7b8511..1c00f84b 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -22,53 +22,53 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - @Test - public void deleteDocumentTestA() throws NotConnectedException, InternalException { + // @Test + // public void deleteDocumentTestA() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + // ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().delete(index, collection, "some-id", true); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + // kuzzleMock.getDocumentController().delete(index, collection, "some-id", true); + // Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - } + // assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + // assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + // } - @Test - public void deleteDocumentTestB() throws NotConnectedException, InternalException { + // @Test + // public void deleteDocumentTestB() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + // ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().delete(index, collection, "some-id"); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + // kuzzleMock.getDocumentController().delete(index, collection, "some-id"); + // Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - } + // assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + // assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + // assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + // } - @Test(expected = NotConnectedException.class) - public void deleteDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + // @Test(expected = NotConnectedException.class) + // public void deleteDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + // AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + // Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + // Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + // String index = "nyc-open-data"; + // String collection = "yellow-taxi"; - kuzzleMock.getDocumentController().delete(index, collection, "some-id"); - } + // kuzzleMock.getDocumentController().delete(index, collection, "some-id"); + // } } From 09f8ba6222cfec3aa2209d926c72056b86e053e3 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 2 Mar 2020 11:48:21 +0100 Subject: [PATCH 058/134] snippet --- doc/3/controllers/document/delete/snippets/delete.test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/controllers/document/delete/snippets/delete.test.yml b/doc/3/controllers/document/delete/snippets/delete.test.yml index c9082ef1..46aeccbb 100644 --- a/doc/3/controllers/document/delete/snippets/delete.test.yml +++ b/doc/3/controllers/document/delete/snippets/delete.test.yml @@ -1,5 +1,5 @@ -name: document#create -description: Creates a new document +name: document#delete +description: deletes a document hooks: before: | curl -XDELETE kuzzle:7512/nyc-open-data From b00e7c6b9a7d9dbf6098c13e6b809e8da67567e2 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 2 Mar 2020 13:08:25 +0100 Subject: [PATCH 059/134] Add document:replace (#62) What does this PR do ? This PR implements the document:replace method with its unit tests. --- doc/3/controllers/document/replace/index.md | 55 ++++++++++++++++ .../document/replace/snippets/replace.java | 19 ++++++ .../replace/snippets/replace.test.yml | 11 ++++ .../API/Controllers/DocumentController.java | 56 ++++++++++++++++ .../DocumentTest/DocumentTest.java | 66 +++++++++++++++++++ 5 files changed, 207 insertions(+) create mode 100644 doc/3/controllers/document/replace/index.md create mode 100644 doc/3/controllers/document/replace/snippets/replace.java create mode 100644 doc/3/controllers/document/replace/snippets/replace.test.yml diff --git a/doc/3/controllers/document/replace/index.md b/doc/3/controllers/document/replace/index.md new file mode 100644 index 00000000..43dde4e7 --- /dev/null +++ b/doc/3/controllers/document/replace/index.md @@ -0,0 +1,55 @@ +--- +code: true +type: page +title: replace +description: Replaces a document +--- + +# replace + +Replaces the content of an existing document. + +--- + +## Arguments + +```java +public CompletableFuture> replace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException + +public CompletableFuture> replace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `id` |
String
| Document ID | +| `document` |
ConcurrentHashMap
| Updated ocument content | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + +--- + +## Return + +A `ConcurrentHashMap` which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Document content | +| `_id` |
String
| ID of the document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/replace.java diff --git a/doc/3/controllers/document/replace/snippets/replace.java b/doc/3/controllers/document/replace/snippets/replace.java new file mode 100644 index 00000000..68c90c11 --- /dev/null +++ b/doc/3/controllers/document/replace/snippets/replace.java @@ -0,0 +1,19 @@ + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("firstname", "John"); + + ConcurrentHashMap result = kuzzle.getDocumentController().replace("nyc-open-data", "yellow-taxi", "some-id", document) + .get(); + + /* + result = + { + _source= + { + firstname=John, + _kuzzle_info={ createdAt=1582892606555, author=-1, updatedAt=1582892606555, updater=-1 } + }, + _id=some-id, + _version=2 + } + */ \ No newline at end of file diff --git a/doc/3/controllers/document/replace/snippets/replace.test.yml b/doc/3/controllers/document/replace/snippets/replace.test.yml new file mode 100644 index 00000000..4b53e0ba --- /dev/null +++ b/doc/3/controllers/document/replace/snippets/replace.test.yml @@ -0,0 +1,11 @@ +name: document#replace +description: replaces a document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + after: +template: print-result +expected: "firstname=John" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 21a24844..88d9e4b6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -14,6 +14,62 @@ public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } + /** + * Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> replace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "replace") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> replace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.replace(index, collection, id, document, null); + } + /** * Deletes a document in a given collection and index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 7b703774..fd909eea 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -23,6 +23,72 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void replaceDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().replace(index, collection, "some-id", document, true); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "replace"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test + public void replaceDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().replace(index, collection, "some-id", document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "replace"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test(expected = NotConnectedException.class) + public void replaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + kuzzleMock.getDocumentController().replace(index, collection, "some-id", document); + } + @Test public void deleteDocumentTestA() throws NotConnectedException, InternalException { From 0b89323a148739b399c7fb5e9b8e596cc95793c8 Mon Sep 17 00:00:00 2001 From: jenow Date: Tue, 3 Mar 2020 15:59:32 +0100 Subject: [PATCH 060/134] realtime controller --- doc/3/controllers/realtime/count/index.md | 33 +++++++++ .../realtime/count/snippets/count.java | 22 ++++++ .../realtime/count/snippets/count.test.yml | 7 ++ doc/3/controllers/realtime/publish/index.md | 38 ++++++++++ .../realtime/publish/snippets/publish.java | 4 ++ .../publish/snippets/publish.test.yml | 7 ++ .../controllers/realtime/unsubscribe/index.md | 29 ++++++++ .../unsubscribe/snippets/unsubscribe.java | 22 ++++++ .../unsubscribe/snippets/unsubscribe.test.yml | 7 ++ .../API/Controllers/RealtimeController.java | 69 +++++++++++++++++++ .../Controllers/RealtimeControllerTest.java | 45 ++++++++++++ 11 files changed, 283 insertions(+) create mode 100644 doc/3/controllers/realtime/count/index.md create mode 100644 doc/3/controllers/realtime/count/snippets/count.java create mode 100644 doc/3/controllers/realtime/count/snippets/count.test.yml create mode 100644 doc/3/controllers/realtime/publish/index.md create mode 100644 doc/3/controllers/realtime/publish/snippets/publish.java create mode 100644 doc/3/controllers/realtime/publish/snippets/publish.test.yml create mode 100644 doc/3/controllers/realtime/unsubscribe/index.md create mode 100644 doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.java create mode 100644 doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.test.yml diff --git a/doc/3/controllers/realtime/count/index.md b/doc/3/controllers/realtime/count/index.md new file mode 100644 index 00000000..71102aea --- /dev/null +++ b/doc/3/controllers/realtime/count/index.md @@ -0,0 +1,33 @@ +--- +code: true +type: page +title: count +description: Returns the number of other connections sharing the same subscription. +--- + +# count + +Returns the number of other connections sharing the same subscription. + +## Arguments + +```java +public CompletableFuture count(final String roomId) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|-----------|-------------------|----------------------| +| `room_id` |
String
| Subscription room ID | + +## Return + +Returns the number of active connections using the same provided subscription room. + +## Exceptions + +Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). + +## Usage + +<<< ./snippets/count.java diff --git a/doc/3/controllers/realtime/count/snippets/count.java b/doc/3/controllers/realtime/count/snippets/count.java new file mode 100644 index 00000000..f5748e60 --- /dev/null +++ b/doc/3/controllers/realtime/count/snippets/count.java @@ -0,0 +1,22 @@ +SubscribeOptions options = new SubscribeOptions(); +options.setSubscribeToSelf(true); + +ConcurrentHashMap filters = new ConcurrentHashMap<>(); +filters.put("exists", "name"); + +ConcurrentHashMap document = new ConcurrentHashMap<>(); +document.put("name", "nina-vkote"); + +final String roomId = kuzzle.getRealtimeController().subscribe( + "nyc-open-data", + "yellow-taxi", + filters, + notification -> { + if (notification.scope.equals(SubscribeOptions.Scope.IN.toString())) { + System.out.println("Document entered the scope"); + } else { + System.out.println("Document left the scope"); + } +}).get(); + +final Integer result = kuzzle.getRealtimeController().count(roomId).get(); \ No newline at end of file diff --git a/doc/3/controllers/realtime/count/snippets/count.test.yml b/doc/3/controllers/realtime/count/snippets/count.test.yml new file mode 100644 index 00000000..0392ea47 --- /dev/null +++ b/doc/3/controllers/realtime/count/snippets/count.test.yml @@ -0,0 +1,7 @@ +name: Realtime#count +description: Counts subscribers for a subscription room. +hooks: + before: + after: +template: print-result +expected: 1 \ No newline at end of file diff --git a/doc/3/controllers/realtime/publish/index.md b/doc/3/controllers/realtime/publish/index.md new file mode 100644 index 00000000..9e372ac3 --- /dev/null +++ b/doc/3/controllers/realtime/publish/index.md @@ -0,0 +1,38 @@ +--- +code: true +type: page +title: publish +description: Publishes a real-time message. +--- + +# publish + +Sends a real-time message to Kuzzle. The message will be broadcasted to all clients with subscriptions matching the index, the collection and the message content. + +The index and collection are indicative and serve only to distinguish the rooms. They are not required to exist in the database. + +**Note:** real-time messages are not persisted in the database. + +## Arguments + +```java +public CompletableFuture publish( + final String index, + final String collection, + final ConcurrentHashMap message) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|--------------|--------------------|-------------------------------------| +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `message` |
ConcurrentHashMap
| ConcurrentHashMap representing a JSON payload | + +## Exceptions + +Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). + +## Usage + +<<< ./snippets/publish.java diff --git a/doc/3/controllers/realtime/publish/snippets/publish.java b/doc/3/controllers/realtime/publish/snippets/publish.java new file mode 100644 index 00000000..db209db1 --- /dev/null +++ b/doc/3/controllers/realtime/publish/snippets/publish.java @@ -0,0 +1,4 @@ +ConcurrentHashMap document = new ConcurrentHashMap<>(); +document.put("name", "nina-vkote"); + +kuzzle.getRealtimeController().publish("my-index", "my-collection", document); \ No newline at end of file diff --git a/doc/3/controllers/realtime/publish/snippets/publish.test.yml b/doc/3/controllers/realtime/publish/snippets/publish.test.yml new file mode 100644 index 00000000..579119b6 --- /dev/null +++ b/doc/3/controllers/realtime/publish/snippets/publish.test.yml @@ -0,0 +1,7 @@ +name: Realtime#publish +description: Publishes a realtime message. +hooks: + before: + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/realtime/unsubscribe/index.md b/doc/3/controllers/realtime/unsubscribe/index.md new file mode 100644 index 00000000..da23b8ef --- /dev/null +++ b/doc/3/controllers/realtime/unsubscribe/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: unsubscribe +description: Removes a subscription. +--- + +# unsubscribe + +Removes a subscription. + +## Arguments + +```java +public CompletableFuture unsubscribe(final String roomId) + throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +|-----------|--------------------|----------------------| +| `room_id` |
String
| Subscription room ID | + +## Exceptions + +Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). + +## Usage + +<<< ./snippets/unsubscribe.java diff --git a/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.java b/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.java new file mode 100644 index 00000000..8efafdba --- /dev/null +++ b/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.java @@ -0,0 +1,22 @@ +SubscribeOptions options = new SubscribeOptions(); +options.setSubscribeToSelf(true); + +ConcurrentHashMap filters = new ConcurrentHashMap<>(); +filters.put("exists", "name"); + +ConcurrentHashMap document = new ConcurrentHashMap<>(); +document.put("name", "nina-vkote"); + +final String roomId = kuzzle.getRealtimeController().subscribe( + "nyc-open-data", + "yellow-taxi", + filters, + notification -> { + if (notification.scope.equals(SubscribeOptions.Scope.IN.toString())) { + System.out.println("Document entered the scope"); + } else { + System.out.println("Document left the scope"); + } +}).get(); + +kuzzle.getRealtimeController().unsubscribe(roomId).get(); \ No newline at end of file diff --git a/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.test.yml b/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.test.yml new file mode 100644 index 00000000..909e8388 --- /dev/null +++ b/doc/3/controllers/realtime/unsubscribe/snippets/unsubscribe.test.yml @@ -0,0 +1,7 @@ +name: Realtime#unsubscribe +description: Removes a subscription. +hooks: + before: + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index eae90e18..05b10412 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -54,6 +54,58 @@ public RealtimeController(Kuzzle kuzzle) { }); } + /** + * Returns the number of other connections sharing the same subscription. + * + * @param roomId + * @return + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture count(final String roomId) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "realtime") + .put("action", "count") + .put("body", new KuzzleMap().put("room_id", roomId))) + .thenApplyAsync((response) -> ((KuzzleMap) response.result).getNumber("count").intValue()); + } + + /** + * Sends a real-time message to Kuzzle. The message will be dispatched to + * all clients with subscriptions matching the index, the collection and + * the message content. + * + * @param index + * @param collection + * @param message + * @return + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture publish(final String index, final String collection, final ConcurrentHashMap message) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "realtime") + .put("action", "publish") + .put("index", index) + .put("collection", collection) + .put("body", new KuzzleMap().put("message", message))) + .thenApplyAsync((response) -> null); + } + + /** + * Subscribe to a collection. + * + * @param index + * @param collection + * @param filters + * @param handler + * @param options + * @return + * @throws NotConnectedException + * @throws InternalException + */ public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler, final SubscribeOptions options) throws NotConnectedException, InternalException { ConcurrentHashMap queryOptions = new ConcurrentHashMap<>(); boolean subscribeToSelf = true; @@ -98,4 +150,21 @@ public CompletableFuture subscribe(final String index, final String coll public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler) throws NotConnectedException, InternalException { return this.subscribe(index, collection, filters, handler, null); } + + /** + * Removes a subscription + * + * @param roomId + * @return + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture unsubscribe(final String roomId) throws NotConnectedException, InternalException { + return kuzzle + .query(new KuzzleMap() + .put("controller", "realtime") + .put("action", "unsubscribe") + .put("body", new KuzzleMap().put("room_id", roomId))) + .thenApplyAsync((response) -> null); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java index d8859ef1..fe73a32f 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java @@ -23,6 +23,36 @@ public class RealtimeControllerTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void countTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getRealtimeController().count("roomId"); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("test", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("room_id")); + } + + @Test + public void publishTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getRealtimeController().unsubscribe("roomId"); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("publish", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("bar", ((KuzzleMap)((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).get("message")).getString("foo")); + } + @Test public void subscribeTest() throws NotConnectedException, InternalException { Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); @@ -83,4 +113,19 @@ public void notificationHandlerWithoutSubscribeToSelfTest() throws NotConnectedE kuzzleSpy.trigger(Event.unhandledResponse, response); verify(notificationHandler, never()).run(any(Response.class)); } + + @Test + public void unsubscribeTest() throws NotConnectedException, InternalException { + Kuzzle kuzzleSpy = spy(new Kuzzle(networkProtocol)); + NotificationHandler notificationHandler = mock(NotificationHandler.class); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleSpy.getRealtimeController().unsubscribe("roomId"); + verify(kuzzleSpy).query((KuzzleMap) arg.capture()); + + assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); + assertEquals("unsubscribe", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("room_id")); + } } From c42ff05773ef714dc5ee2029d906f494c97bdb04 Mon Sep 17 00:00:00 2001 From: jenow Date: Tue, 3 Mar 2020 16:06:41 +0100 Subject: [PATCH 061/134] fix unit tests --- .../test/API/Controllers/RealtimeControllerTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java index fe73a32f..5fdf18e0 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java @@ -34,7 +34,7 @@ public void countTest() throws NotConnectedException, InternalException { verify(kuzzleSpy).query((KuzzleMap) arg.capture()); assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); - assertEquals("test", ((KuzzleMap) arg.getValue()).getString("action")); + assertEquals("count", ((KuzzleMap) arg.getValue()).getString("action")); assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("room_id")); } @@ -45,12 +45,17 @@ public void publishTest() throws NotConnectedException, InternalException { ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleSpy.getRealtimeController().unsubscribe("roomId"); + ConcurrentHashMap message = new ConcurrentHashMap<>(); + message.put("foo", "bar"); + + kuzzleSpy.getRealtimeController().publish("index", "collection", message); verify(kuzzleSpy).query((KuzzleMap) arg.capture()); assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); assertEquals("publish", ((KuzzleMap) arg.getValue()).getString("action")); - assertEquals("bar", ((KuzzleMap)((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).get("message")).getString("foo")); + assertEquals("index", ((KuzzleMap) arg.getValue()).getString("index")); + assertEquals("collection", ((KuzzleMap) arg.getValue()).getString("collection")); + assertEquals("bar", ((ConcurrentHashMap)((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).get("message")).get("foo").toString()); } @Test From 30d55539f11188c81eb87389de9315f8c0065bf7 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 15:35:55 +0100 Subject: [PATCH 062/134] @jenow requested changes --- .ci/doc/templates/default.tpl.java | 1 + .ci/doc/templates/print-result.tpl.java | 1 + doc/3/controllers/document/create/index.md | 9 ++-- doc/3/core-classes/document-options/index.md | 26 ++++++++++ .../API/Controllers/DocumentController.java | 17 ++++--- .../kuzzle/sdk/Options/DocumentOptions.java | 48 +++++++++++++++++++ .../DocumentTest/DocumentTest.java | 7 +-- 7 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 doc/3/core-classes/document-options/index.md create mode 100644 src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java index 49b426c9..ca43d447 100644 --- a/.ci/doc/templates/default.tpl.java +++ b/.ci/doc/templates/default.tpl.java @@ -5,6 +5,7 @@ import java.util.concurrent.ConcurrentHashMap; import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.Options.SubscribeOptions; +import io.kuzzle.sdk.Options.DocumentOptions; public class SnippetTest { private static Kuzzle kuzzle; diff --git a/.ci/doc/templates/print-result.tpl.java b/.ci/doc/templates/print-result.tpl.java index 1e7b1e39..12f427e3 100644 --- a/.ci/doc/templates/print-result.tpl.java +++ b/.ci/doc/templates/print-result.tpl.java @@ -2,6 +2,7 @@ import io.kuzzle.sdk.Protocol.WebSocket; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.DocumentOptions; import io.kuzzle.sdk.CoreClasses.Responses.Response; import java.util.concurrent.ConcurrentHashMap; diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index 4bb825f0..da2457df 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -24,7 +24,7 @@ public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final ConcurrentHashMap options) + final DocumentOptions options) throws NotConnectedException, InternalException ``` @@ -33,16 +33,13 @@ throws NotConnectedException, InternalException | `index` |
String
| Index | | `collection` |
String
| Collection | | `document` |
ConcurrentHashMap
| Document content | -| `options` |
ConcurrentHashMap
| Optional parameters | +| `options` |
DocumentOptions

(`null`) | Document options | --- ### options -| Arguments | Type | Description | -| ------------------ | -------------------------------------------- | --------------------------------- | -| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | -| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +A [DocumentOptions](/sdk/java/3/core-classes/document-options) object. ## Return diff --git a/doc/3/core-classes/document-options/index.md b/doc/3/core-classes/document-options/index.md new file mode 100644 index 00000000..ec80c13e --- /dev/null +++ b/doc/3/core-classes/document-options/index.md @@ -0,0 +1,26 @@ +--- +code: true +type: page +title: DocumentOptions +description: DocumentOptions class documentation +order: 110 +--- + +# DocumentOptions + +This class represents the options usable with the [DocumentController](/sdk/java/3/controllers/document). + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.Options.DocumentOptions; +``` + +## Properties + +| Property | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 9c23dba9..be1edf47 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -4,10 +4,10 @@ import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.DocumentOptions; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.UUID; public class DocumentController extends BaseController { public DocumentController(final Kuzzle kuzzle) { @@ -29,11 +29,16 @@ public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final ConcurrentHashMap options) throws NotConnectedException, InternalException { + final DocumentOptions options) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); - final KuzzleMap _options = KuzzleMap - .from(options); + + String id = null; + Boolean waitForRefresh = null; + if (options != null) { + waitForRefresh = options.getWaitForRefresh(); + id = options.getId(); + } query .put("index", index) @@ -41,8 +46,8 @@ public CompletableFuture> create( .put("controller", "document") .put("action", "create") .put("body", document) - .put("_id", _options == null ? null : _options.getString("_id")) - .put("waitForRefresh", _options == null ? null : _options.getBoolean("waitForRefresh")); + .put("_id", id) + .put("waitForRefresh", waitForRefresh); return kuzzle .query(query) diff --git a/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java b/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java new file mode 100644 index 00000000..64fb3bd6 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java @@ -0,0 +1,48 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; + +public class DocumentOptions { + + private String id; + private Boolean waitForRefresh; + /** + * Constructor + */ + public DocumentOptions() {} + + /** + * Copy constructor + * + * @param options + */ + public DocumentOptions(DocumentOptions options) { + this.id = options.getId(); + this.waitForRefresh = options.getWaitForRefresh(); + } + + public Boolean getWaitForRefresh() { + return waitForRefresh; + } + + public String getId() { + return id; + } + + public void setWaitForRefresh(Boolean waitForRefresh) { + this.waitForRefresh = waitForRefresh; + } + + public void setId(String id) { + this.id = id; + } + + public ConcurrentHashMap toHashMap() { + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + options.put("scope", this.id); + options.put("users", this.waitForRefresh); + + return options; + } +} diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index b98a133b..09f06776 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -4,6 +4,7 @@ import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.DocumentOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; import io.kuzzle.sdk.Protocol.WebSocket; @@ -35,9 +36,9 @@ public void createDocumentTest() throws NotConnectedException, InternalException ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("_id", "some-id"); - options.put("waitForRefresh", true); + DocumentOptions options = new DocumentOptions(); + options.setId("some-id"); + options.setWaitForRefresh(true); kuzzleMock.getDocumentController().create(index, collection, document, options); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); From 98d1aeddc879e1eb7274c98af051efd983db5b84 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 15:39:00 +0100 Subject: [PATCH 063/134] conflict [ci skip] --- .../API/Controllers/DocumentController.java | 176 +++++++------- .../DocumentTest/DocumentTest.java | 214 +++++++++--------- 2 files changed, 195 insertions(+), 195 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 37403b27..6d0761e9 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -15,92 +15,92 @@ public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document, - final DocumentOptions options) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - - String id = null; - Boolean waitForRefresh = null; - if (options != null) { - waitForRefresh = options.getWaitForRefresh(); - id = options.getId(); - } - - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "create") - .put("body", document) - .put("_id", id) - .put("waitForRefresh", waitForRefresh); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } - - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - - return this.create(index, collection, document, null); - } - - /** - * Gets multiple documents in a given collection and index. - * - * @param index - * @param collection - * @param ids - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture>> mGet( - final String index, - final String collection, - final ArrayList ids) throws NotConnectedException, InternalException { - - - final KuzzleMap query = new KuzzleMap(); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "mGet") - .put("body", new KuzzleMap().put("ids", ids)); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap>) response.result); - } +// /** +// * Creates a document in a given collection and index. +// * +// * @param index +// * @param collection +// * @param document +// * @param options +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture> create( +// final String index, +// final String collection, +// final ConcurrentHashMap document, +// final DocumentOptions options) throws NotConnectedException, InternalException { +// +// final KuzzleMap query = new KuzzleMap(); +// +// String id = null; +// Boolean waitForRefresh = null; +// if (options != null) { +// waitForRefresh = options.getWaitForRefresh(); +// id = options.getId(); +// } +// +// query +// .put("index", index) +// .put("collection", collection) +// .put("controller", "document") +// .put("action", "create") +// .put("body", document) +// .put("_id", id) +// .put("waitForRefresh", waitForRefresh); +// +// return kuzzle +// .query(query) +// .thenApplyAsync( +// (response) -> (ConcurrentHashMap) response.result); +// } +// +// /** +// * Creates a document in a given collection and index. +// * +// * @param index +// * @param collection +// * @param document +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture> create( +// final String index, +// final String collection, +// final ConcurrentHashMap document) throws NotConnectedException, InternalException { +// +// return this.create(index, collection, document, null); +// } +// +// /** +// * Gets multiple documents in a given collection and index. +// * +// * @param index +// * @param collection +// * @param ids +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture>> mGet( +// final String index, +// final String collection, +// final ArrayList ids) throws NotConnectedException, InternalException { +// +// +// final KuzzleMap query = new KuzzleMap(); +// query +// .put("index", index) +// .put("collection", collection) +// .put("controller", "document") +// .put("action", "mGet") +// .put("body", new KuzzleMap().put("ids", ids)); +// +// return kuzzle +// .query(query) +// .thenApplyAsync( +// (response) -> (ConcurrentHashMap>) response.result); +// } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 51857848..370e6e18 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -24,111 +24,111 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - @Test - public void createDocumentTestA() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - DocumentOptions options = new DocumentOptions(); - options.setId("some-id"); - options.setWaitForRefresh(true); - - kuzzleMock.getDocumentController().create(index, collection, document, options); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } - - @Test - public void createDocumentTestB() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().create(index, collection, document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } - - @Test(expected = NotConnectedException.class) - public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - - kuzzleMock.getDocumentController().create(index, collection, document); - } - - @Test - public void mGetDocumentTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - final ArrayList ids = new ArrayList<>(); - ids.add("some-id1"); - ids.add("some-id2"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().mGet(index, collection, ids); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "mGet"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); - } - - @Test(expected = NotConnectedException.class) - public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - final ArrayList ids = new ArrayList<>(); - ids.add("some-id1"); - ids.add("some-id2"); - - kuzzleMock.getDocumentController().mGet(index, collection, ids); - } +// @Test +// public void createDocumentTestA() throws NotConnectedException, InternalException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap document = new ConcurrentHashMap<>(); +// document.put("name", "Yoann"); +// document.put("nickname", "El angel de la muerte que hace el JAVA"); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// +// DocumentOptions options = new DocumentOptions(); +// options.setId("some-id"); +// options.setWaitForRefresh(true); +// +// kuzzleMock.getDocumentController().create(index, collection, document, options); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); +// +// assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); +// assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); +// assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); +// assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); +// } +// +// @Test +// public void createDocumentTestB() throws NotConnectedException, InternalException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap document = new ConcurrentHashMap<>(); +// document.put("name", "Yoann"); +// document.put("nickname", "El angel de la muerte que hace el JAVA"); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// +// kuzzleMock.getDocumentController().create(index, collection, document); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); +// +// assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); +// assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); +// assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); +// assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); +// } +// +// @Test(expected = NotConnectedException.class) +// public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap document = new ConcurrentHashMap<>(); +// document.put("name", "Yoann"); +// document.put("nickname", "El angel de la muerte que hace el JAVA"); +// +// kuzzleMock.getDocumentController().create(index, collection, document); +// } +// +// @Test +// public void mGetDocumentTest() throws NotConnectedException, InternalException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// final ArrayList ids = new ArrayList<>(); +// ids.add("some-id1"); +// ids.add("some-id2"); +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// +// kuzzleMock.getDocumentController().mGet(index, collection, ids); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "mGet"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); +// assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); +// } +// +// @Test(expected = NotConnectedException.class) +// public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// final ArrayList ids = new ArrayList<>(); +// ids.add("some-id1"); +// ids.add("some-id2"); +// +// kuzzleMock.getDocumentController().mGet(index, collection, ids); +// } } From 904f2c82dbac6fa57ce8dacb667bf7e1639d03c1 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 15:42:55 +0100 Subject: [PATCH 064/134] update DocumentController.java --- doc/3/controllers/document/replace/index.md | 2 +- .../API/Controllers/DocumentController.java | 30 --------------- .../DocumentTest/DocumentTest.java | 37 ------------------- 3 files changed, 1 insertion(+), 68 deletions(-) diff --git a/doc/3/controllers/document/replace/index.md b/doc/3/controllers/document/replace/index.md index 43dde4e7..08d1f804 100644 --- a/doc/3/controllers/document/replace/index.md +++ b/doc/3/controllers/document/replace/index.md @@ -35,7 +35,7 @@ throws NotConnectedException, InternalException | `index` |
String
| Index | | `collection` |
String
| Collection | | `id` |
String
| Document ID | -| `document` |
ConcurrentHashMap
| Updated ocument content | +| `document` |
ConcurrentHashMap
| New content of the document to update | | `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| --- diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 00340bb0..77787abd 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -74,36 +74,6 @@ public CompletableFuture> create( return this.create(index, collection, document, null); } - /** - * Gets multiple documents in a given collection and index. - * - * @param index - * @param collection - * @param ids - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture>> mGet( - final String index, - final String collection, - final ArrayList ids) throws NotConnectedException, InternalException { - - - final KuzzleMap query = new KuzzleMap(); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "mGet") - .put("body", new KuzzleMap().put("ids", ids)); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap>) response.result); - } - /** * Replace a document in a given collection and index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 1b0af529..1161e11a 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -94,43 +94,6 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException, kuzzleMock.getDocumentController().create(index, collection, document); } - @Test - public void mGetDocumentTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - final ArrayList ids = new ArrayList<>(); - ids.add("some-id1"); - ids.add("some-id2"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().mGet(index, collection, ids); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "mGet"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); - } - - @Test(expected = NotConnectedException.class) - public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - final ArrayList ids = new ArrayList<>(); - ids.add("some-id1"); - ids.add("some-id2"); - - kuzzleMock.getDocumentController().mGet(index, collection, ids); - } @Test public void replaceDocumentTestA() throws NotConnectedException, InternalException { From fb944a69eb14d42fe45340ecd73f65e10acaa4eb Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 16:19:48 +0100 Subject: [PATCH 065/134] update doc --- doc/3/core-classes/document-options/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/3/core-classes/document-options/index.md b/doc/3/core-classes/document-options/index.md index ec80c13e..f953e2c0 100644 --- a/doc/3/core-classes/document-options/index.md +++ b/doc/3/core-classes/document-options/index.md @@ -24,3 +24,5 @@ import io.kuzzle.sdk.Options.DocumentOptions; | ------------------ | -------------------------------------------- | --------------------------------- | | `id` |
String
(optional) | Document identifier. Auto-generated if not specified | | `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `retryOnConflict` |
Number
| The number of times the database layer should retry in case of version conflict | +| `source` |
Boolean
| If true, returns the updated document inside the response | From bea99e508bce999d308eaf55403ad85561f9cdc9 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 16:39:39 +0100 Subject: [PATCH 066/134] doc --- doc/3/controllers/document/create/index.md | 8 ++++++++ doc/3/core-classes/document-options/index.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index b146be4a..b4a3d54a 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -45,6 +45,14 @@ throws NotConnectedException, InternalException A [DocumentOptions](/sdk/java/3/core-classes/document-options) object. +The `create` method takes into account those following argument: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + + ## Return A `ConcurrentHashMap` which has the following properties: diff --git a/doc/3/core-classes/document-options/index.md b/doc/3/core-classes/document-options/index.md index f953e2c0..0d7490b8 100644 --- a/doc/3/core-classes/document-options/index.md +++ b/doc/3/core-classes/document-options/index.md @@ -24,5 +24,5 @@ import io.kuzzle.sdk.Options.DocumentOptions; | ------------------ | -------------------------------------------- | --------------------------------- | | `id` |
String
(optional) | Document identifier. Auto-generated if not specified | | `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| -| `retryOnConflict` |
Number
| The number of times the database layer should retry in case of version conflict | +| `retryOnConflict` |
Integer
| The number of times the database layer should retry in case of version conflict | | `source` |
Boolean
| If true, returns the updated document inside the response | From 28ca5caed7a8fcb475522e0e1026fd20e40f9eef Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 4 Mar 2020 16:58:22 +0100 Subject: [PATCH 067/134] Add document:mDelete (#66) This PR implements the mDelete method with its unit tests. --- doc/3/controllers/document/m-delete/index.md | 46 ++++++++++++++ .../document/m-delete/snippets/m-delete.java | 14 +++++ .../m-delete/snippets/m-delete.test.yml | 14 +++++ doc/3/controllers/document/replace/index.md | 2 +- .../API/Controllers/DocumentController.java | 53 +++++++++++++++- .../DocumentTest/DocumentTest.java | 62 +++++++++++++++++++ 6 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 doc/3/controllers/document/m-delete/index.md create mode 100644 doc/3/controllers/document/m-delete/snippets/m-delete.java create mode 100644 doc/3/controllers/document/m-delete/snippets/m-delete.test.yml diff --git a/doc/3/controllers/document/m-delete/index.md b/doc/3/controllers/document/m-delete/index.md new file mode 100644 index 00000000..d7de90bd --- /dev/null +++ b/doc/3/controllers/document/m-delete/index.md @@ -0,0 +1,46 @@ +--- +code: true +type: page +title: mDelete +description: Deletes multiple documents +--- + +# mDelete + +Deletes multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mDelete( + final String index, + final String collection, + final ArrayList ids) +throws NotConnectedException, InternalException + +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `ids` |
ArrayList
| Document IDs | +--- + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +The `successes` array contains the successfully deleted document IDs. + +Each deletion error is an object of the errors array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_id` |
String
| Document ID | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-delete.java \ No newline at end of file diff --git a/doc/3/controllers/document/m-delete/snippets/m-delete.java b/doc/3/controllers/document/m-delete/snippets/m-delete.java new file mode 100644 index 00000000..513b6071 --- /dev/null +++ b/doc/3/controllers/document/m-delete/snippets/m-delete.java @@ -0,0 +1,14 @@ + final ArrayList ids = new ArrayList<>(); + ids.add("some-id"); + ids.add("some-id2"); + + ConcurrentHashMap> result = kuzzle.getDocumentController().mDelete("nyc-open-data", "yellow-taxi", ids) + .get(); +/* + result = + { + successes=[some-id, some-id2], + errors=[] + } + +*/ \ No newline at end of file diff --git a/doc/3/controllers/document/m-delete/snippets/m-delete.test.yml b/doc/3/controllers/document/m-delete/snippets/m-delete.test.yml new file mode 100644 index 00000000..a7dd0966 --- /dev/null +++ b/doc/3/controllers/document/m-delete/snippets/m-delete.test.yml @@ -0,0 +1,14 @@ +name: document#mDelete +description: Delete multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + curl -XPOST -d '{"color":"purple"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id2/_create + after: +template: print-result-array +expected: + - "some-id" + - "some-id2" \ No newline at end of file diff --git a/doc/3/controllers/document/replace/index.md b/doc/3/controllers/document/replace/index.md index 43dde4e7..fc3bb906 100644 --- a/doc/3/controllers/document/replace/index.md +++ b/doc/3/controllers/document/replace/index.md @@ -35,7 +35,7 @@ throws NotConnectedException, InternalException | `index` |
String
| Index | | `collection` |
String
| Collection | | `id` |
String
| Document ID | -| `document` |
ConcurrentHashMap
| Updated ocument content | +| `document` |
ConcurrentHashMap
| New content of the document to update | | `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| --- diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 88d9e4b6..10f153d4 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -5,15 +5,66 @@ import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.ArrayList; public class DocumentController extends BaseController { public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } + /** + * Deletes multiple documents. + * + * @param index + * @param collection + * @param ids + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mDelete( + final String index, + final String collection, + final ArrayList ids, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mDelete") + .put("waitForRefresh", waitForRefresh) + .put("body", new KuzzleMap().put("ids", ids)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Deletes multiple documents. + * + * @param index + * @param collection + * @param ids + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mDelete( + final String index, + final String collection, + final ArrayList ids) throws NotConnectedException, InternalException { + + return mDelete(index, collection, ids, null); + } + /** * Replace a document in a given collection and index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index fd909eea..1b0d1906 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -23,6 +23,68 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void mDeleteDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + final ArrayList ids = new ArrayList<>(); + ids.add("some-id1"); + ids.add("some-id2"); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mDelete(index, collection, ids); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mDelete"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + } + + @Test + public void mDeleteDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + final ArrayList ids = new ArrayList<>(); + ids.add("some-id1"); + ids.add("some-id2"); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mDelete(index, collection, ids, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mDelete"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mDeleteDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + final ArrayList ids = new ArrayList<>(); + ids.add("some-id1"); + ids.add("some-id2"); + + kuzzleMock.getDocumentController().mDelete(index, collection, ids); + } + @Test public void replaceDocumentTestA() throws NotConnectedException, InternalException { From f42797b78439af3e93c123e4400ded3503dd1da4 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 18:24:53 +0100 Subject: [PATCH 068/134] update DocumentOptions.java --- src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java b/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java index 64fb3bd6..5f615912 100644 --- a/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java @@ -40,8 +40,8 @@ public void setId(String id) { public ConcurrentHashMap toHashMap() { ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("scope", this.id); - options.put("users", this.waitForRefresh); + options.put("id", this.id); + options.put("waitForRefresh", this.waitForRefresh); return options; } From f175d944cceb957e64011ccb3238544a3f0b7cfe Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 4 Mar 2020 18:34:15 +0100 Subject: [PATCH 069/134] add missing import --- .ci/doc/templates/print-result-array.tpl.java | 1 + .ci/doc/templates/print-result.tpl.java | 1 + 2 files changed, 2 insertions(+) diff --git a/.ci/doc/templates/print-result-array.tpl.java b/.ci/doc/templates/print-result-array.tpl.java index 9c751d0b..c4fd68cd 100644 --- a/.ci/doc/templates/print-result-array.tpl.java +++ b/.ci/doc/templates/print-result-array.tpl.java @@ -2,6 +2,7 @@ import io.kuzzle.sdk.Protocol.WebSocket; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.SubscribeOptions; import io.kuzzle.sdk.CoreClasses.Responses.Response; import java.util.concurrent.ConcurrentHashMap; diff --git a/.ci/doc/templates/print-result.tpl.java b/.ci/doc/templates/print-result.tpl.java index 1e7b1e39..ea361e66 100644 --- a/.ci/doc/templates/print-result.tpl.java +++ b/.ci/doc/templates/print-result.tpl.java @@ -2,6 +2,7 @@ import io.kuzzle.sdk.Protocol.WebSocket; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.SubscribeOptions; import io.kuzzle.sdk.CoreClasses.Responses.Response; import java.util.concurrent.ConcurrentHashMap; From c98c283364f9fb9c46922d35794743c566d33023 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 5 Mar 2020 09:27:03 +0100 Subject: [PATCH 070/134] fix --- .../java/io/kuzzle/sdk/API/Controllers/RealtimeController.java | 2 +- .../io/kuzzle/test/API/Controllers/RealtimeControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index 05b10412..34e7969b 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -164,7 +164,7 @@ public CompletableFuture unsubscribe(final String roomId) throws NotConnec .query(new KuzzleMap() .put("controller", "realtime") .put("action", "unsubscribe") - .put("body", new KuzzleMap().put("room_id", roomId))) + .put("body", new KuzzleMap().put("roomId", roomId))) .thenApplyAsync((response) -> null); } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java index 5fdf18e0..d04c03e0 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java @@ -131,6 +131,6 @@ public void unsubscribeTest() throws NotConnectedException, InternalException { assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); assertEquals("unsubscribe", ((KuzzleMap) arg.getValue()).getString("action")); - assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("room_id")); + assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("roomId")); } } From 1d5a448c96f1a4271dfa637efd8b07e66d840082 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 5 Mar 2020 09:31:32 +0100 Subject: [PATCH 071/134] Update doc/3/controllers/realtime/unsubscribe/index.md --- doc/3/controllers/realtime/unsubscribe/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/realtime/unsubscribe/index.md b/doc/3/controllers/realtime/unsubscribe/index.md index da23b8ef..5e7075c0 100644 --- a/doc/3/controllers/realtime/unsubscribe/index.md +++ b/doc/3/controllers/realtime/unsubscribe/index.md @@ -18,7 +18,7 @@ public CompletableFuture unsubscribe(final String roomId) | Argument | Type | Description | |-----------|--------------------|----------------------| -| `room_id` |
String
| Subscription room ID | +| `room_id` |
String
| Subscription room ID | ## Exceptions From 2d9e0453c2ffab34c9752337fc4e01b25256247d Mon Sep 17 00:00:00 2001 From: jenow Date: Thu, 5 Mar 2020 10:38:51 +0100 Subject: [PATCH 072/134] do not document basic exception --- doc/3/controllers/realtime/count/index.md | 4 ---- doc/3/controllers/realtime/publish/index.md | 4 ---- doc/3/controllers/realtime/unsubscribe/index.md | 4 ---- 3 files changed, 12 deletions(-) diff --git a/doc/3/controllers/realtime/count/index.md b/doc/3/controllers/realtime/count/index.md index 71102aea..36066ea6 100644 --- a/doc/3/controllers/realtime/count/index.md +++ b/doc/3/controllers/realtime/count/index.md @@ -24,10 +24,6 @@ public CompletableFuture count(final String roomId) Returns the number of active connections using the same provided subscription room. -## Exceptions - -Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). - ## Usage <<< ./snippets/count.java diff --git a/doc/3/controllers/realtime/publish/index.md b/doc/3/controllers/realtime/publish/index.md index 9e372ac3..9df4a740 100644 --- a/doc/3/controllers/realtime/publish/index.md +++ b/doc/3/controllers/realtime/publish/index.md @@ -29,10 +29,6 @@ public CompletableFuture publish( | `collection` |
String
| Collection name | | `message` |
ConcurrentHashMap
| ConcurrentHashMap representing a JSON payload | -## Exceptions - -Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). - ## Usage <<< ./snippets/publish.java diff --git a/doc/3/controllers/realtime/unsubscribe/index.md b/doc/3/controllers/realtime/unsubscribe/index.md index 5e7075c0..aeb14d05 100644 --- a/doc/3/controllers/realtime/unsubscribe/index.md +++ b/doc/3/controllers/realtime/unsubscribe/index.md @@ -20,10 +20,6 @@ public CompletableFuture unsubscribe(final String roomId) |-----------|--------------------|----------------------| | `room_id` |
String
| Subscription room ID | -## Exceptions - -Throws a `KuzzleException` if there is an error. See how to [handle error](/sdk/java/3/essentials/error-handling). - ## Usage <<< ./snippets/unsubscribe.java From e1d6b32d6654dd345d16e7f7f624a0a659c22c24 Mon Sep 17 00:00:00 2001 From: jenow Date: Thu, 5 Mar 2020 15:41:57 +0100 Subject: [PATCH 073/134] remove subscription after unsubscribe --- .../io/kuzzle/sdk/API/Controllers/RealtimeController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index 34e7969b..3dd1c888 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -165,6 +165,9 @@ public CompletableFuture unsubscribe(final String roomId) throws NotConnec .put("controller", "realtime") .put("action", "unsubscribe") .put("body", new KuzzleMap().put("roomId", roomId))) - .thenApplyAsync((response) -> null); + .thenApplyAsync((response) -> { + subscriptions.get("roomId").clear(); + return null; + }); } } From c7264f3f77a2fe9b11384383fef1e8ca9ecfec4d Mon Sep 17 00:00:00 2001 From: jenow Date: Thu, 5 Mar 2020 17:59:36 +0100 Subject: [PATCH 074/134] fix --- .../java/io/kuzzle/sdk/API/Controllers/RealtimeController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index 3dd1c888..fefd03e9 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -166,7 +166,7 @@ public CompletableFuture unsubscribe(final String roomId) throws NotConnec .put("action", "unsubscribe") .put("body", new KuzzleMap().put("roomId", roomId))) .thenApplyAsync((response) -> { - subscriptions.get("roomId").clear(); + subscriptions.get(roomId).clear(); return null; }); } From 26c378c693c97b42da203ef2ae1bd2036285fe04 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 6 Mar 2020 10:31:27 +0100 Subject: [PATCH 075/134] Add document:mCreate (#64) ## What does this PR do ? This PR implements the `mCreate` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data` and a `yellow-taxi` collection in the admin console. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class mCreateDocument { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); ConcurrentHashMap document1 = new ConcurrentHashMap<>(); ConcurrentHashMap body1 = new ConcurrentHashMap<>(); ConcurrentHashMap document2 = new ConcurrentHashMap<>(); ConcurrentHashMap body2 = new ConcurrentHashMap<>(); document1.put("_id", "some-id1"); body1.put("key", "value"); document1.put("body", body1); document2.put("_id", "some-id2"); body2.put("key", "value"); document2.put("body", body2); ArrayList> documents = new ArrayList<>(); documents.add(document1); documents.add(document2); ConcurrentHashMap response = kuzzle.getDocumentController().mCreate("nyc-open-data", "yellow-taxi", documents) .get(); System.out.println(response); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` You should see the documents in your collection. --- doc/3/controllers/document/m-create/index.md | 70 ++++++++++++ .../document/m-create/snippets/m-create.java | 54 ++++++++++ .../m-create/snippets/m-create.test.yml | 12 +++ .../API/Controllers/DocumentController.java | 50 +++++++++ .../DocumentTest/DocumentTest.java | 101 ++++++++++++++++++ 5 files changed, 287 insertions(+) create mode 100644 doc/3/controllers/document/m-create/index.md create mode 100644 doc/3/controllers/document/m-create/snippets/m-create.java create mode 100644 doc/3/controllers/document/m-create/snippets/m-create.test.yml diff --git a/doc/3/controllers/document/m-create/index.md b/doc/3/controllers/document/m-create/index.md new file mode 100644 index 00000000..f26864fa --- /dev/null +++ b/doc/3/controllers/document/m-create/index.md @@ -0,0 +1,70 @@ +--- +code: true +type: page +title: mCreate +description: Creates multiple documents +--- + +# mCreate + +Creates multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents) +throws NotConnectedException, InternalException + +public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `documents` |
ArrayList>
| ArrayList containing the documents to create | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | + +--- + +### documents + +Each document has the following properties: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `_id` |
String
| Optional document ID. Will be auto-generated if not defined. | +| `body` |
ConcurrentHashMap
| Document body | + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the newly created document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-create.java diff --git a/doc/3/controllers/document/m-create/snippets/m-create.java b/doc/3/controllers/document/m-create/snippets/m-create.java new file mode 100644 index 00000000..24f9696f --- /dev/null +++ b/doc/3/controllers/document/m-create/snippets/m-create.java @@ -0,0 +1,54 @@ +ConcurrentHashMap document1 = new ConcurrentHashMap<>(); +ConcurrentHashMap document2 = new ConcurrentHashMap<>(); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + +body.put("Agent", "Smith"); +body2.put("Gordon", "Freeman"); + +document1.put("_id", "some-id"); +document1.put("body", body); + +document2.put("_id", "some-id2"); +document2.put("body", body2); + +final ArrayList> documents = new ArrayList<>(); +documents.add(document1); +documents.add(document2); + +ConcurrentHashMap> result = kuzzle + .getDocumentController() + .mCreate("nyc-open-data", "yellow-taxi", documents) + .get(); + +/* +result = + { + successes= + [ + { + result=created, + _source= + { + Agent=Smith, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=1, + status=201 + }, + { + result=created, + _source= + { + Gordon=Freeman, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=1, + status=201 + } + ], + errors=[] + } +*/ diff --git a/doc/3/controllers/document/m-create/snippets/m-create.test.yml b/doc/3/controllers/document/m-create/snippets/m-create.test.yml new file mode 100644 index 00000000..a513ed5a --- /dev/null +++ b/doc/3/controllers/document/m-create/snippets/m-create.test.yml @@ -0,0 +1,12 @@ +name: document#mCreate +description: Creates multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result-array +expected: + - "id=some-id, _version=1, status=201" + - "id=some-id2, _version=1, status=201" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index ad4f7c84..c3c97cd6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -74,6 +74,56 @@ public CompletableFuture> create( return this.create(index, collection, document, null); } + /** + * Creates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mCreate") + .put("body", new KuzzleMap().put("documents", documents)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Creates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents) throws NotConnectedException, InternalException { + + return this.mCreate(index, collection, documents, null); + } + /** * Deletes multiple documents. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 72f40540..9bf7177c 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -95,6 +95,107 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException, } + @Test + public void mCreateDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test + public void mCreateDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mCreateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents); + } + @Test public void mDeleteDocumentTestA() throws NotConnectedException, InternalException { From 25b3f223f2f0f9acff96b8a81fb3454093496191 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 6 Mar 2020 11:18:46 +0100 Subject: [PATCH 076/134] add document:exists --- doc/3/controllers/document/exists/index.md | 42 +++++++++++++++++++ .../document/exists/snippets/exists.java | 2 + .../document/exists/snippets/exists.test.yml | 11 +++++ doc/3/controllers/realtime/subscribe/index.md | 8 ---- .../API/Controllers/DocumentController.java | 29 +++++++++++++ .../DocumentTest/DocumentTest.java | 32 ++++++++++++++ 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 doc/3/controllers/document/exists/index.md create mode 100644 doc/3/controllers/document/exists/snippets/exists.java create mode 100644 doc/3/controllers/document/exists/snippets/exists.test.yml diff --git a/doc/3/controllers/document/exists/index.md b/doc/3/controllers/document/exists/index.md new file mode 100644 index 00000000..637548cc --- /dev/null +++ b/doc/3/controllers/document/exists/index.md @@ -0,0 +1,42 @@ +--- +code: true +type: page +title: exists +description: Checks if a document exists +--- + +# exists + +Checks if a document exists. + +--- + +## Arguments + +```java +public CompletableFuture> exists( + final String index, + final String collection, + final String id) +throws NotConnectedException, InternalException + +``` + +--- + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `id ` |
String
| Document ID | + + +--- + +## Return + +Returns a boolean. + +## Usage + +<<< ./snippets/exists.java \ No newline at end of file diff --git a/doc/3/controllers/document/exists/snippets/exists.java b/doc/3/controllers/document/exists/snippets/exists.java new file mode 100644 index 00000000..e92dcff0 --- /dev/null +++ b/doc/3/controllers/document/exists/snippets/exists.java @@ -0,0 +1,2 @@ +Boolean result = kuzzle.getDocumentController().exists("nyc-open-data", "yellow-taxi", "some-id") + .get(); \ No newline at end of file diff --git a/doc/3/controllers/document/exists/snippets/exists.test.yml b/doc/3/controllers/document/exists/snippets/exists.test.yml new file mode 100644 index 00000000..2f36ca7b --- /dev/null +++ b/doc/3/controllers/document/exists/snippets/exists.test.yml @@ -0,0 +1,11 @@ +name: document#exists +description: Check if document exists +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + after: +template: print-result +expected: "true" \ No newline at end of file diff --git a/doc/3/controllers/realtime/subscribe/index.md b/doc/3/controllers/realtime/subscribe/index.md index bcba6c66..0a487307 100644 --- a/doc/3/controllers/realtime/subscribe/index.md +++ b/doc/3/controllers/realtime/subscribe/index.md @@ -51,11 +51,3 @@ _Simple subscription to document notifications_ _Subscription to document notifications with scope option_ <<< ./snippets/document-notifications-leave-scope.java - -_Subscription to message notifications_ - -<<< ./snippets/message-notifications.java - -_Subscription to user notifications_ - -<<< ./snippets/user-notifications.java diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index c3c97cd6..3bd0247e 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -311,4 +311,33 @@ public CompletableFuture>> mGet( .thenApplyAsync( (response) -> (ConcurrentHashMap>) response.result); } + + /** + * Tells if a document exists in a given collection and index. + * + * @param index + * @param collection + * @param id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture exists( + final String index, + final String collection, + final String id) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "exists") + .put("_id", id); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (Boolean) response.result); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9bf7177c..3e758b44 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -411,4 +411,36 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti kuzzleMock.getDocumentController().mGet(index, collection, ids); } + + @Test + public void existsDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().exists(index, collection, "some-id"); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "exists"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("_id"), "some-id"); + } + + @Test(expected = NotConnectedException.class) + public void existsDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().exists(index, collection, "some-id"); + } + } From 05399c3560a91564381c471018852349ab19183e Mon Sep 17 00:00:00 2001 From: jenow Date: Fri, 6 Mar 2020 11:43:12 +0100 Subject: [PATCH 077/134] clear subscriptionsCache after resubscribing --- .../io/kuzzle/sdk/API/Controllers/RealtimeController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index fefd03e9..d1aa0ca2 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -166,7 +166,10 @@ public CompletableFuture unsubscribe(final String roomId) throws NotConnec .put("action", "unsubscribe") .put("body", new KuzzleMap().put("roomId", roomId))) .thenApplyAsync((response) -> { - subscriptions.get(roomId).clear(); + ArrayList subs = subscriptions.get(roomId); + if (subs != null) { + subscriptions.get(roomId).clear(); + } return null; }); } From 0900cb776adcd44c843dd624201cf2f7ee529614 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 6 Mar 2020 11:43:21 +0100 Subject: [PATCH 078/134] Add document:createOrReplace (#61) This PR implements the document:createOrReplace method with its unit tests. --- .../document/create-or-replace/index.md | 55 ++++++++++++++++ .../snippets/create-or-replace.java | 25 +++++++ .../snippets/create-or-replace.test.yml | 10 +++ doc/3/controllers/realtime/subscribe/index.md | 7 -- .../API/Controllers/DocumentController.java | 56 ++++++++++++++++ .../DocumentTest/DocumentTest.java | 66 +++++++++++++++++++ 6 files changed, 212 insertions(+), 7 deletions(-) create mode 100644 doc/3/controllers/document/create-or-replace/index.md create mode 100644 doc/3/controllers/document/create-or-replace/snippets/create-or-replace.java create mode 100644 doc/3/controllers/document/create-or-replace/snippets/create-or-replace.test.yml diff --git a/doc/3/controllers/document/create-or-replace/index.md b/doc/3/controllers/document/create-or-replace/index.md new file mode 100644 index 00000000..1a3ef99f --- /dev/null +++ b/doc/3/controllers/document/create-or-replace/index.md @@ -0,0 +1,55 @@ +--- +code: true +type: page +title: createOrReplace +description: Creates or replaces a document +--- + +# createOrReplace + +Creates a new document in the persistent data storage, or replaces its content if it already exists. + +--- + +## Arguments + +```java +public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException + +public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `id` |
String
| Document ID | +| `document` |
ConcurrentHashMap
| Document content | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + +--- + +## Return + +A `ConcurrentHashMap` which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Document content | +| `_id` |
String
| ID of the document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/create-or-replace.java diff --git a/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.java b/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.java new file mode 100644 index 00000000..f88a3796 --- /dev/null +++ b/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.java @@ -0,0 +1,25 @@ + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("firstname", "John"); + + ConcurrentHashMap result = kuzzle + .getDocumentController() + .createOrReplace("nyc-open-data", "yellow-taxi", "some-id", document) + .get(); + +/* + { + _source= + { + firstname=John, + _kuzzle_info={ + createdAt=1582892323254, + author=-1, + updatedAt=1582892323254, + updater=-1 + } + }, + _id=some-id, + _version=1 + } + */ diff --git a/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.test.yml b/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.test.yml new file mode 100644 index 00000000..fe3e45b8 --- /dev/null +++ b/doc/3/controllers/document/create-or-replace/snippets/create-or-replace.test.yml @@ -0,0 +1,10 @@ +name: document#createOrReplace +description: Creates or Replace a document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result +expected: "firstname=John" \ No newline at end of file diff --git a/doc/3/controllers/realtime/subscribe/index.md b/doc/3/controllers/realtime/subscribe/index.md index bcba6c66..24feb86b 100644 --- a/doc/3/controllers/realtime/subscribe/index.md +++ b/doc/3/controllers/realtime/subscribe/index.md @@ -52,10 +52,3 @@ _Subscription to document notifications with scope option_ <<< ./snippets/document-notifications-leave-scope.java -_Subscription to message notifications_ - -<<< ./snippets/message-notifications.java - -_Subscription to user notifications_ - -<<< ./snippets/user-notifications.java diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index c3c97cd6..4e87cd9f 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -16,6 +16,62 @@ public DocumentController(final Kuzzle kuzzle) { } /** + * Creates or Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "createOrReplace") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Creates or Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.createOrReplace(index, collection, id, document, null); + } + + /** * Creates a document in a given collection and index. * * @param index diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9bf7177c..775ca99a 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -24,6 +24,72 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document, true); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test + public void createOrReplaceDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getString("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test(expected = NotConnectedException.class) + public void createOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); + } + @Test public void createDocumentTestA() throws NotConnectedException, InternalException { From 1f8dc6770c4c547581258f31701236bd0b41947d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Cottinet?= Date: Fri, 6 Mar 2020 12:00:32 +0100 Subject: [PATCH 079/134] code wrap --- doc/3/controllers/document/exists/snippets/exists.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/3/controllers/document/exists/snippets/exists.java b/doc/3/controllers/document/exists/snippets/exists.java index e92dcff0..2121d858 100644 --- a/doc/3/controllers/document/exists/snippets/exists.java +++ b/doc/3/controllers/document/exists/snippets/exists.java @@ -1,2 +1,4 @@ -Boolean result = kuzzle.getDocumentController().exists("nyc-open-data", "yellow-taxi", "some-id") - .get(); \ No newline at end of file +Boolean result = kuzzle + .getDocumentController() + .exists("nyc-open-data", "yellow-taxi", "some-id") + .get(); From 9109e7277aaae2dc73982e81ca0597a53c7e91c2 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 6 Mar 2020 15:23:06 +0100 Subject: [PATCH 080/134] update doc --- doc/3/controllers/document/exists/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/exists/index.md b/doc/3/controllers/document/exists/index.md index 637548cc..b682d867 100644 --- a/doc/3/controllers/document/exists/index.md +++ b/doc/3/controllers/document/exists/index.md @@ -14,7 +14,7 @@ Checks if a document exists. ## Arguments ```java -public CompletableFuture> exists( +public CompletableFuture exists( final String index, final String collection, final String id) From 88c1f4ba2ed38c8867dd8333a5d5d7c31c5e2bb8 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 6 Mar 2020 16:17:58 +0100 Subject: [PATCH 081/134] Add document:get (#60) This PR implements the document:get method with its unit tests. --- doc/3/controllers/document/get/index.md | 45 +++++++++++++++++++ .../document/get/snippets/get.java | 16 +++++++ .../document/get/snippets/get.test.yml | 11 +++++ .../API/Controllers/DocumentController.java | 30 +++++++++++++ .../DocumentTest/DocumentTest.java | 31 +++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 doc/3/controllers/document/get/index.md create mode 100644 doc/3/controllers/document/get/snippets/get.java create mode 100644 doc/3/controllers/document/get/snippets/get.test.yml diff --git a/doc/3/controllers/document/get/index.md b/doc/3/controllers/document/get/index.md new file mode 100644 index 00000000..d143f19b --- /dev/null +++ b/doc/3/controllers/document/get/index.md @@ -0,0 +1,45 @@ +--- +code: true +type: page +title: get +description: Gets a document +--- + +# get + +Gets a document. + +--- + +## Arguments + +```java +public CompletableFuture> get( + final String index, + final String collection, + final String id) +throws NotConnectedException, InternalException + +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `id ` |
String
| Document ID | + +--- + +## Return + +A `ConcurrentHashMap` which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------------------------------------- | +| `_source` |
ConcurrentHashMap
| Document content | +| `_id` |
String
| ID of the document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/get.java diff --git a/doc/3/controllers/document/get/snippets/get.java b/doc/3/controllers/document/get/snippets/get.java new file mode 100644 index 00000000..46119495 --- /dev/null +++ b/doc/3/controllers/document/get/snippets/get.java @@ -0,0 +1,16 @@ + ConcurrentHashMap result = + kuzzle.getDocumentController().get("nyc-open-data", "yellow-taxi", "some-id") + .get(); + +/* + { + _source= + { + key1=value1, + key2=value2, + _kuzzle_info= { createdAt=1582892127577, author=-1} + }, + _id=some-id, + _version=1 + } +*/ diff --git a/doc/3/controllers/document/get/snippets/get.test.yml b/doc/3/controllers/document/get/snippets/get.test.yml new file mode 100644 index 00000000..7c66a85b --- /dev/null +++ b/doc/3/controllers/document/get/snippets/get.test.yml @@ -0,0 +1,11 @@ +name: document#get +description: Get a document from kuzzle +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + after: +template: print-result +expected: "_id=some-id" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 4e87cd9f..3a43412a 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -15,6 +15,36 @@ public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } + /** + * Gets a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> get( + final String index, + final String collection, + final String id) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "get") + .put("_id", id); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + /** * Creates or Replace a document in a given collection and index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 775ca99a..e9c9d1b8 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -4,6 +4,7 @@ import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; + import io.kuzzle.sdk.Options.DocumentOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; @@ -24,6 +25,36 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void getDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + } + + @Test(expected = NotConnectedException.class) + public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + } + @Test public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException { From f83c01df68b876e9da21edcb01ba941dbd0bf4fe Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 12 Mar 2020 12:53:48 +0100 Subject: [PATCH 082/134] Add document:update (#59) This PR implements the document:update method with its unit tests. --- .ci/doc/templates/default.tpl.java | 3 +- .ci/doc/templates/print-result.tpl.java | 3 +- doc/3/controllers/document/create/index.md | 8 +- doc/3/controllers/document/update/index.md | 67 +++++++ .../document/update/snippets/update.java | 14 ++ .../document/update/snippets/update.test.yml | 11 ++ doc/3/core-classes/create-options/index.md | 26 +++ .../index.md | 13 +- .../API/Controllers/DocumentController.java | 163 ++++++++++++------ ...ocumentOptions.java => CreateOptions.java} | 8 +- .../io/kuzzle/sdk/Options/UpdateOptions.java | 59 +++++++ .../DocumentTest/DocumentTest.java | 139 +++++++++++---- 12 files changed, 416 insertions(+), 98 deletions(-) create mode 100644 doc/3/controllers/document/update/index.md create mode 100644 doc/3/controllers/document/update/snippets/update.java create mode 100644 doc/3/controllers/document/update/snippets/update.test.yml create mode 100644 doc/3/core-classes/create-options/index.md rename doc/3/core-classes/{document-options => update-options}/index.md (64%) rename src/main/java/io/kuzzle/sdk/Options/{DocumentOptions.java => CreateOptions.java} (84%) create mode 100644 src/main/java/io/kuzzle/sdk/Options/UpdateOptions.java diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java index 9ba31fa1..8052865d 100644 --- a/.ci/doc/templates/default.tpl.java +++ b/.ci/doc/templates/default.tpl.java @@ -6,7 +6,8 @@ import java.util.concurrent.ConcurrentHashMap; import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.Options.SubscribeOptions; -import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.UpdateOptions; +import io.kuzzle.sdk.Options.CreateOptions; public class SnippetTest { private static Kuzzle kuzzle; diff --git a/.ci/doc/templates/print-result.tpl.java b/.ci/doc/templates/print-result.tpl.java index 86ff8f9c..7ab9a27f 100644 --- a/.ci/doc/templates/print-result.tpl.java +++ b/.ci/doc/templates/print-result.tpl.java @@ -3,7 +3,8 @@ import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.SubscribeOptions; -import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.UpdateOptions; +import io.kuzzle.sdk.Options.CreateOptions; import io.kuzzle.sdk.CoreClasses.Responses.Response; import java.util.concurrent.ConcurrentHashMap; diff --git a/doc/3/controllers/document/create/index.md b/doc/3/controllers/document/create/index.md index b4a3d54a..5c3041fd 100644 --- a/doc/3/controllers/document/create/index.md +++ b/doc/3/controllers/document/create/index.md @@ -28,7 +28,7 @@ public CompletableFuture> create( final String index, final String collection, final ConcurrentHashMap document, - final DocumentOptions options) + final CreateOptions options) throws NotConnectedException, InternalException ``` @@ -37,15 +37,15 @@ throws NotConnectedException, InternalException | `index` |
String
| Index | | `collection` |
String
| Collection | | `document` |
ConcurrentHashMap
| Document content | -| `options` |
DocumentOptions

(`null`) | Document options | +| `options` |
CreateOptions

(`null`) | Create options | --- ### options -A [DocumentOptions](/sdk/java/3/core-classes/document-options) object. +A [CreateOptions](/sdk/java/3/core-classes/create-options) object. -The `create` method takes into account those following argument: +The following options can be set: | Arguments | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | diff --git a/doc/3/controllers/document/update/index.md b/doc/3/controllers/document/update/index.md new file mode 100644 index 00000000..35f59888 --- /dev/null +++ b/doc/3/controllers/document/update/index.md @@ -0,0 +1,67 @@ +--- +code: true +type: page +title: update +description: Updates a document +--- + +# update + +Updates a document. + +--- + +## Arguments + +```java +public CompletableFuture> update( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException + +public CompletableFuture> update( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final UpdateOptions options) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `id ` |
String
| Document ID | +| `document` |
ConcurrentHashMap
| Partial document content | +| `options` |
UpdateOptions

(`null`) | Optional parameters | + +--- + +### options + +A [UpdateOptions](/sdk/java/3/core-classes/update-options) object. + +The following options can be set: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `retryOnConflict` |
Integer
| The number of times the database layer should retry in case of version conflict | +| `source` |
Boolean
| If true, returns the updated document inside the response | + +## Return + +A `ConcurrentHashMap` which has the following properties: + +| Property | Type | Description | +|------------- |----------------------------- |--------------------------------------------------------------- | +| `_source` |
ConcurrentHashMap
| Updated document (If source option set to true) | +| `_id` |
String
| ID of the updated document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +## Usage + +<<< ./snippets/update.java diff --git a/doc/3/controllers/document/update/snippets/update.java b/doc/3/controllers/document/update/snippets/update.java new file mode 100644 index 00000000..ead423c8 --- /dev/null +++ b/doc/3/controllers/document/update/snippets/update.java @@ -0,0 +1,14 @@ + ConcurrentHashMap content = new ConcurrentHashMap<>(); + content.put("name", "Johny"); + + ConcurrentHashMap result = + kuzzle.getDocumentController().update("nyc-open-data", "yellow-taxi", "some-id", content) + .get(); + +/* + response = + { + _id=some-id, + _version=2 + } +*/ \ No newline at end of file diff --git a/doc/3/controllers/document/update/snippets/update.test.yml b/doc/3/controllers/document/update/snippets/update.test.yml new file mode 100644 index 00000000..f16f3719 --- /dev/null +++ b/doc/3/controllers/document/update/snippets/update.test.yml @@ -0,0 +1,11 @@ +name: document#update +description: Update a document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + after: +template: print-result +expected: "{_id=some-id, _version=2}" \ No newline at end of file diff --git a/doc/3/core-classes/create-options/index.md b/doc/3/core-classes/create-options/index.md new file mode 100644 index 00000000..4380195f --- /dev/null +++ b/doc/3/core-classes/create-options/index.md @@ -0,0 +1,26 @@ +--- +code: true +type: page +title: CreateOptions +description: CreateOptions class documentation +order: 110 +--- + +# CreateOptions + +This class represents the options usable with the [`create`](/sdk/java/3/controllers/document/create) method of the [DocumentController](/sdk/java/3/controllers/document). + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.Options.CreateOptions; +``` + +## Properties + +| Property | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| diff --git a/doc/3/core-classes/document-options/index.md b/doc/3/core-classes/update-options/index.md similarity index 64% rename from doc/3/core-classes/document-options/index.md rename to doc/3/core-classes/update-options/index.md index 0d7490b8..a13db359 100644 --- a/doc/3/core-classes/document-options/index.md +++ b/doc/3/core-classes/update-options/index.md @@ -1,28 +1,27 @@ --- code: true type: page -title: DocumentOptions -description: DocumentOptions class documentation +title: UpdateOptions +description: UpdateOptions class documentation order: 110 --- -# DocumentOptions +# UpdateOptions -This class represents the options usable with the [DocumentController](/sdk/java/3/controllers/document). +This class represents the options usable with the [`update`](/sdk/java/3/controllers/document/update) method of the [DocumentController](/sdk/java/3/controllers/document). ## Namespace You must include the following package: ```java -import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.UpdateOptions; ``` ## Properties | Property | Type | Description | | ------------------ | -------------------------------------------- | --------------------------------- | -| `id` |
String
(optional) | Document identifier. Auto-generated if not specified | -| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | | `retryOnConflict` |
Integer
| The number of times the database layer should retry in case of version conflict | | `source` |
Boolean
| If true, returns the updated document inside the response | diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index e48a3517..66295235 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -4,7 +4,8 @@ import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; -import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.UpdateOptions; +import io.kuzzle.sdk.Options.CreateOptions; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; @@ -15,29 +16,104 @@ public DocumentController(final Kuzzle kuzzle) { super(kuzzle); } + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document, + final CreateOptions options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + String id = null; + Boolean waitForRefresh = null; + if (options != null) { + waitForRefresh = options.getWaitForRefresh(); + id = options.getId(); + } + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "create") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Creates a document in a given collection and index. + * + * @param index + * @param collection + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> create( + final String index, + final String collection, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.create(index, collection, document, null); + } + /** - * Gets a document in a given collection and index. + * Updates a document in a given collection and index. * * @param index * @param collection * @param id + * @param document + * @param options * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture> get( + public CompletableFuture> update( final String index, final String collection, - final String id) throws NotConnectedException, InternalException { + final String id, + final ConcurrentHashMap document, + final UpdateOptions options) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); + Integer retryOnConflict = null; + Boolean waitForRefresh = null; + Boolean source = null; + if (options != null) { + retryOnConflict = options.getRetryOnConflict(); + source = options.getSource(); + waitForRefresh = options.getWaitForRefresh(); + } query .put("index", index) .put("collection", collection) .put("controller", "document") - .put("action", "get") - .put("_id", id); + .put("action", "update") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh) + .put("retryOnConflict", retryOnConflict) + .put("source", source); return kuzzle .query(query) @@ -46,23 +122,39 @@ public CompletableFuture> get( } /** - * Creates or Replace a document in a given collection and index. + * Updates a document in a given collection and index. * * @param index * @param collection * @param id * @param document - * @param waitForRefresh * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture> createOrReplace( + public CompletableFuture> update( final String index, final String collection, final String id, - final ConcurrentHashMap document, - final Boolean waitForRefresh) throws NotConnectedException, InternalException { + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.update(index, collection, id, document, null); + } + + /** + * Gets a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> get( + final String index, + final String collection, + final String id) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); @@ -70,10 +162,8 @@ public CompletableFuture> createOrReplace( .put("index", index) .put("collection", collection) .put("controller", "document") - .put("action", "createOrReplace") - .put("body", document) - .put("_id", id) - .put("waitForRefresh", waitForRefresh); + .put("action", "get") + .put("_id", id); return kuzzle .query(query) @@ -88,6 +178,7 @@ public CompletableFuture> createOrReplace( * @param collection * @param id * @param document + * @param waitForRefresh * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -96,42 +187,16 @@ public CompletableFuture> createOrReplace( final String index, final String collection, final String id, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - - return this.createOrReplace(index, collection, id, document, null); - } - - /** - * Creates a document in a given collection and index. - * - * @param index - * @param collection - * @param document - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> create( - final String index, - final String collection, final ConcurrentHashMap document, - final DocumentOptions options) throws NotConnectedException, InternalException { + final Boolean waitForRefresh) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); - String id = null; - Boolean waitForRefresh = null; - if (options != null) { - waitForRefresh = options.getWaitForRefresh(); - id = options.getId(); - } - query .put("index", index) .put("collection", collection) .put("controller", "document") - .put("action", "create") + .put("action", "createOrReplace") .put("body", document) .put("_id", id) .put("waitForRefresh", waitForRefresh); @@ -143,21 +208,23 @@ public CompletableFuture> create( } /** - * Creates a document in a given collection and index. + * Creates or Replace a document in a given collection and index. * * @param index * @param collection + * @param id * @param document * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture> create( + public CompletableFuture> createOrReplace( final String index, final String collection, + final String id, final ConcurrentHashMap document) throws NotConnectedException, InternalException { - return this.create(index, collection, document, null); + return this.createOrReplace(index, collection, id, document, null); } /** @@ -288,7 +355,7 @@ public CompletableFuture> replace( .put("controller", "document") .put("action", "replace") .put("body", document) - .put("_id", id) + .put("_id", id) .put("waitForRefresh", waitForRefresh); return kuzzle @@ -341,7 +408,7 @@ public CompletableFuture> delete( .put("collection", collection) .put("controller", "document") .put("action", "delete") - .put("_id", id) + .put("_id", id) .put("waitForRefresh", waitForRefresh); return kuzzle diff --git a/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java b/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java similarity index 84% rename from src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java rename to src/main/java/io/kuzzle/sdk/Options/CreateOptions.java index 5f615912..a66060af 100644 --- a/src/main/java/io/kuzzle/sdk/Options/DocumentOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java @@ -2,21 +2,21 @@ import java.util.concurrent.ConcurrentHashMap; -public class DocumentOptions { +public class CreateOptions { private String id; private Boolean waitForRefresh; /** * Constructor */ - public DocumentOptions() {} + public CreateOptions() {} /** * Copy constructor * * @param options */ - public DocumentOptions(DocumentOptions options) { + public CreateOptions(CreateOptions options) { this.id = options.getId(); this.waitForRefresh = options.getWaitForRefresh(); } @@ -40,7 +40,7 @@ public void setId(String id) { public ConcurrentHashMap toHashMap() { ConcurrentHashMap options = new ConcurrentHashMap<>(); - options.put("id", this.id); + options.put("_id", this.id); options.put("waitForRefresh", this.waitForRefresh); return options; diff --git a/src/main/java/io/kuzzle/sdk/Options/UpdateOptions.java b/src/main/java/io/kuzzle/sdk/Options/UpdateOptions.java new file mode 100644 index 00000000..9bf7d2e2 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/UpdateOptions.java @@ -0,0 +1,59 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; + +public class UpdateOptions { + + private Integer retryOnConflict; + private Boolean source; + private Boolean waitForRefresh; + /** + * Constructor + */ + public UpdateOptions() {} + + /** + * Copy constructor + * + * @param options + */ + public UpdateOptions(UpdateOptions options) { + this.waitForRefresh = options.getWaitForRefresh(); + this.retryOnConflict = options.getRetryOnConflict(); + this.source = options.getSource(); + } + + public Boolean getWaitForRefresh() { + return waitForRefresh; + } + + public int getRetryOnConflict() { + return retryOnConflict; + } + + public Boolean getSource() { + return source; + } + + public void setWaitForRefresh(Boolean waitForRefresh) { + this.waitForRefresh = waitForRefresh; + } + + public void setRetryOnConflict(int retryOnConflict) { + this.retryOnConflict = retryOnConflict; + } + + public void setSource(Boolean source) { + this.source = source; + } + + public ConcurrentHashMap toHashMap() { + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + options.put("source", this.source); + options.put("waitForRefresh", this.waitForRefresh); + options.put("retryOnConflict", this.retryOnConflict); + + return options; + } +} diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index dd7150b1..573e06f7 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -4,8 +4,9 @@ import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.UpdateOptions; +import io.kuzzle.sdk.Options.CreateOptions; -import io.kuzzle.sdk.Options.DocumentOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; import io.kuzzle.sdk.Protocol.WebSocket; @@ -124,74 +125,146 @@ public void createOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConne @Test public void createDocumentTestA() throws NotConnectedException, InternalException { + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + CreateOptions options = new CreateOptions(); + options.setId("some-id"); + options.setWaitForRefresh(true); + + kuzzleMock.getDocumentController().create(index, collection, document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test + public void createDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().create(index, collection, document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } + + @Test(expected = NotConnectedException.class) + public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); + + kuzzleMock.getDocumentController().create(index, collection, document); + } + + @Test + public void udpateDocumentTestA() throws NotConnectedException, InternalException { + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); - DocumentOptions options = new DocumentOptions(); - options.setId("some-id"); - options.setWaitForRefresh(true); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().create(index, collection, document, options); + kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); } @Test - public void createDocumentTestB() throws NotConnectedException, InternalException { + public void udpateDocumentTestB() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); + document.put("name", "Yoann"); ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().create(index, collection, document); + kuzzleMock.getDocumentController().update(index, collection, "some-id", document); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), null); assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), null); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); } @Test(expected = NotConnectedException.class) - public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { + public void updateShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; + String id = "some-id"; ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); - kuzzleMock.getDocumentController().create(index, collection, document); + kuzzleMock.getDocumentController().update(index, collection, id, document); } - @Test public void mCreateDocumentTestA() throws NotConnectedException, InternalException { @@ -312,8 +385,8 @@ public void mDeleteDocumentTestA() throws NotConnectedException, InternalExcepti assertEquals((arg.getValue()).getString("action"), "mDelete"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); } @Test @@ -335,8 +408,8 @@ public void mDeleteDocumentTestB() throws NotConnectedException, InternalExcepti assertEquals((arg.getValue()).getString("action"), "mDelete"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); } @Test(expected = NotConnectedException.class) @@ -376,8 +449,8 @@ public void replaceDocumentTestA() throws NotConnectedException, InternalExcepti assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @Test @@ -401,8 +474,8 @@ public void replaceDocumentTestB() throws NotConnectedException, InternalExcepti assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @Test(expected = NotConnectedException.class) @@ -489,8 +562,8 @@ public void mGetDocumentTest() throws NotConnectedException, InternalException { assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "mGet"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); - assertEquals(((ArrayList)(((KuzzleMap)(arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); + assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); } @Test(expected = NotConnectedException.class) From 64b2d1758ea6c4dd75f27370a6e669eb422875b3 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 12 Mar 2020 14:06:33 +0100 Subject: [PATCH 083/134] wip [ci skip] --- doc/3/controllers/document/search/index.md | 76 ++++++++++++ .../document/search/snippets/search.java | 0 .../document/search/snippets/search.test.yml | 0 doc/3/core-classes/SearchResults/index.md | 0 .../SearchResults/introduction/index.md | 0 .../core-classes/SearchResults/next/index.md | 0 .../API/Controllers/DocumentController.java | 65 +++++++++- .../kuzzle/sdk/CoreClasses/SearchResult.java | 115 ++++++++++++++++++ .../io/kuzzle/sdk/Options/SearchOptions.java | 59 +++++++++ .../DocumentTest/DocumentTest.java | 73 +++++++++++ 10 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 doc/3/controllers/document/search/index.md create mode 100644 doc/3/controllers/document/search/snippets/search.java create mode 100644 doc/3/controllers/document/search/snippets/search.test.yml create mode 100644 doc/3/core-classes/SearchResults/index.md create mode 100644 doc/3/core-classes/SearchResults/introduction/index.md create mode 100644 doc/3/core-classes/SearchResults/next/index.md create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java create mode 100644 src/main/java/io/kuzzle/sdk/Options/SearchOptions.java diff --git a/doc/3/controllers/document/search/index.md b/doc/3/controllers/document/search/index.md new file mode 100644 index 00000000..67c85da9 --- /dev/null +++ b/doc/3/controllers/document/search/index.md @@ -0,0 +1,76 @@ +--- +code: true +type: page +title: search +description: Searches a document +--- + +# search + +Searches document. + +There is a limit to how many documents can be returned by a single search query. +That limit is by default set at 10000 documents, and you can't get over it even with the from and size pagination options. + +:::info +When processing a large number of documents (i.e. more than 1000), it is advised to paginate the results using [SearchResult.next](/sdk/java/3/core-classes/search-result/next) rather than increasing the size parameter. +::: + +::: warning +When using a cursor with the `scroll` option, Elasticsearch has to duplicate the transaction log to keep the same result during the entire scroll session. +It can lead to memory leaks if a scroll duration too great is provided, or if too many scroll sessions are open simultaneously. +::: + +::: info + +You can restrict the scroll session maximum duration under the `services.storage.maxScrollDuration` configuration key. +::: + +--- + +## Arguments + +```java +public CompletableFuture>>> search( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final SearchOptions options) throws NotConnectedException, InternalException + +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `searchQuery` |
ConcurrentHashMap
| Search query | +| `options` |
SearchOptions
| Query options | +--- + +### searchQuery body properties: + +- `query`: the search query itself, using the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html) syntax. +- `aggregations`: control how the search results should be [aggregated](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-aggregations.html) +- `sort`: contains a list of fields, used to [sort search results](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/search-request-sort.html), in order of importance. + +An empty body matches all documents in the queried collection. + +### options + +A [SearchOptions](/sdk/java/3/core-classes/search-options) object. + +The following options can be set: + +| Options | Type
(default) | Description | +| ---------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `from` |
Integer

(`0`) | Offset of the first document to fetch | +| `size` |
Integer

(`10`) | Maximum number of documents to retrieve per page | +| `scroll` |
String

(`""`) | When set, gets a forward-only cursor having its ttl set to the given value (ie `30s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | + +## Return + +Returns a [SearchResult](/sdk/java/3/core-classes/search-result) object. + +## Usage + +<<< ./snippets/search.java diff --git a/doc/3/controllers/document/search/snippets/search.java b/doc/3/controllers/document/search/snippets/search.java new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/controllers/document/search/snippets/search.test.yml b/doc/3/controllers/document/search/snippets/search.test.yml new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/core-classes/SearchResults/index.md b/doc/3/core-classes/SearchResults/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/core-classes/SearchResults/introduction/index.md b/doc/3/core-classes/SearchResults/introduction/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/core-classes/SearchResults/next/index.md b/doc/3/core-classes/SearchResults/next/index.md new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index c3c97cd6..942adc1c 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -1,10 +1,13 @@ package io.kuzzle.sdk.API.Controllers; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.SearchResult; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.SearchOptions; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; @@ -311,4 +314,64 @@ public CompletableFuture>> mGet( .thenApplyAsync( (response) -> (ConcurrentHashMap>) response.result); } -} + + /** + * Searches documents. + * + * @param index + * @param collection + * @param searchQuery + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture search( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final SearchOptions options) throws NotConnectedException, InternalException { + + Integer from = null; + String scroll = null; + Integer size = null; + if (options != null) { + from = options.getFrom(); + scroll = options.getScroll(); + size = options.getSize(); + } + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "search") + .put("from", from) + .put("scroll", scroll) + .put("size", size) + .put("body", new KuzzleMap().put("query", searchQuery)); + + CompletableFuture response = kuzzle + .query(query); + return new SearchResult(this.kuzzle, query, options, response); + } + + /** + * Searches documents. + * + * @param index + * @param collection + * @param searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture search( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + return this.search(index, collection, searchQuery, null); + } +} \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java new file mode 100644 index 00000000..0c72ea16 --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -0,0 +1,115 @@ +package io.kuzzle.sdk.CoreClasses; + +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SearchOptions; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +public class SearchResult { + + private SearchOptions options; + private ConcurrentHashMap request; + private String scrollAction = "scroll"; + private Kuzzle kuzzle; + + public ConcurrentHashMap aggregations; + public ArrayList> hits; + public Integer total; + public Integer fetched; + public String scrollId; + + public SearchResult( + Kuzzle kuzzle, + ConcurrentHashMap request, + SearchOptions options, + Response response) { + + ConcurrentHashMap _response = response.toMap(); + + this.kuzzle = kuzzle; + this.options = options; + this.request = request; + + this.aggregations = (ConcurrentHashMap)((ConcurrentHashMap)_response.get("result")).get("aggregations"); + this.hits = (ArrayList>)((ConcurrentHashMap)_response.get("result")).get("hits"); + this.total = (Integer)((ConcurrentHashMap)_response.get("result")).get("total"); + this.fetched = hits.size(); + this.scrollId = (String)((ConcurrentHashMap)_response.get("result")).get("scrollId"); + } + + public SearchResult( + Kuzzle kuzzle, + ConcurrentHashMap request, + SearchOptions options, + Response response, + Integer previouslyFetched) { + + ConcurrentHashMap _response = response.toMap(); + + this.kuzzle = kuzzle; + this.options = options; + this.request = request; + + this.aggregations = (ConcurrentHashMap)((ConcurrentHashMap)_response.get("result")).get("aggregations"); + this.hits = (ArrayList>)((ConcurrentHashMap)_response.get("result")).get("hits"); + this.total = (Integer)((ConcurrentHashMap)_response.get("result")).get("total"); + this.fetched = hits.size() + previouslyFetched; + this.scrollId = (String)((ConcurrentHashMap)_response.get("result")).get("scrollId"); + } + + private ConcurrentHashMap getScrollRequest() { + final ConcurrentHashMap obj = new ConcurrentHashMap<>(); + + obj.put("controller", this.request.get("controller")); + obj.put("action", this.scrollAction); + obj.put("scrollId", this.scrollId); + return obj; + } + + private ConcurrentHashMap getSearchAfterRequest() { + ConcurrentHashMap nextRequest = this.request; + ConcurrentHashMap lastItem = this.hits.get(this.hits.size()); + ArrayList searchAfter = new ArrayList<>(); + + + //this.request.put(this.request.get("body").get("sort"), searchAfter); + return null; + } + + private SearchResult next() throws NotConnectedException, InternalException { + if (this.fetched >= this.total) return null; + + ConcurrentHashMap nextRequest = new ConcurrentHashMap<>(); + + if (this.scrollId != null) { + nextRequest = this.getScrollRequest(); + } + + else if (options.getSize() != null + && ((ConcurrentHashMap)this.request.get("body")).get("sort") != null) { + nextRequest = this.getSearchAfterRequest(); + } + + else if (options.getSize() != null) { + if (options.getFrom() != null && options.getFrom() > this.total) { + return null; + } + options.setFrom(this.fetched); + nextRequest = this.request; + } + + if (nextRequest == null) { + return null; + } + + Response response = this.kuzzle.query(nextRequest); + + return new SearchResult(this.kuzzle, nextRequest, this.options, response, this.fetched); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java new file mode 100644 index 00000000..54d0badb --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java @@ -0,0 +1,59 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; + +public class SearchOptions { + + private Integer from; + private String scroll; + private Integer size; + /** + * Constructor + */ + public SearchOptions() {} + + /** + * Copy constructor + * + * @param options + */ + public SearchOptions(SearchOptions options) { + this.from = options.getFrom(); + this.scroll = options.getScroll(); + this.size = options.getSize(); + } + + public Integer getFrom() { + return from; + } + + public Integer getSize() { + return size; + } + + public String getScroll() { + return scroll; + } + + public void setFrom(Integer from) { + this.from = from; + } + + public void setSize(Integer size) { + this.size = size; + } + + public void setScroll(String scroll) { + this.scroll = scroll; + } + + public ConcurrentHashMap toHashMap() { + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + options.put("from", this.from); + options.put("scroll", this.scroll); + options.put("size", this.size); + + return options; + } +} diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9bf7177c..9e287977 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -5,6 +5,7 @@ import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; import io.kuzzle.sdk.Options.DocumentOptions; +import io.kuzzle.sdk.Options.SearchOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; import io.kuzzle.sdk.Protocol.WebSocket; @@ -411,4 +412,76 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti kuzzleMock.getDocumentController().mGet(index, collection, ids); } + +// @Test +// public void searchDocumentTestA() throws NotConnectedException, InternalException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// } +// +// @Test +// public void searchDocumentTestB() throws NotConnectedException, InternalException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// SearchOptions options = new SearchOptions(); +// options.setFrom(0); +// options.setScroll("30s"); +// options.setSize(20); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// +// kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals((arg.getValue()).getString("scroll"), "30s"); +// assertEquals((arg.getValue()).getNumber("size"), 20); +// assertEquals((arg.getValue()).getNumber("from"), 0); +// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test(expected = NotConnectedException.class) +// public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// } } From a2da48b2064c0314ac1312a21664b14ad978b4d4 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 13 Mar 2020 14:00:18 +0100 Subject: [PATCH 084/134] searchresult --- .../API/Controllers/DocumentController.java | 37 ++++++------ .../kuzzle/sdk/CoreClasses/SearchResult.java | 56 +++++++++++++------ .../io/kuzzle/sdk/Options/SearchOptions.java | 4 +- .../DocumentTest/DocumentTest.java | 41 +++++++------- 4 files changed, 79 insertions(+), 59 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 942adc1c..eaa6194b 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; public class DocumentController extends BaseController { public DocumentController(final Kuzzle kuzzle) { @@ -326,20 +327,11 @@ public CompletableFuture>> mGet( * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture search( + public SearchResult search( final String index, final String collection, final ConcurrentHashMap searchQuery, - final SearchOptions options) throws NotConnectedException, InternalException { - - Integer from = null; - String scroll = null; - Integer size = null; - if (options != null) { - from = options.getFrom(); - scroll = options.getScroll(); - size = options.getSize(); - } + final SearchOptions options) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { final KuzzleMap query = new KuzzleMap(); query @@ -347,14 +339,19 @@ public CompletableFuture search( .put("collection", collection) .put("controller", "document") .put("action", "search") - .put("from", from) - .put("scroll", scroll) - .put("size", size) .put("body", new KuzzleMap().put("query", searchQuery)); - CompletableFuture response = kuzzle - .query(query); - return new SearchResult(this.kuzzle, query, options, response); + if (options != null) { + query + .put("from", options.getFrom()) + .put("size", options.getSize()); + if (options.getScroll() != null) { + query.put("scroll", options.getScroll()); + } + } + + Response response = kuzzle.query(query).get(); + return new SearchResult(kuzzle, query, options, response); } /** @@ -367,11 +364,11 @@ public CompletableFuture search( * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture search( + public SearchResult search( final String index, final String collection, - final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - return this.search(index, collection, searchQuery, null); + return this.search(index, collection, searchQuery, new SearchOptions()); } } \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index 0c72ea16..19af6147 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk.CoreClasses; +import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; @@ -10,6 +11,8 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.jar.JarOutputStream; public class SearchResult { @@ -36,11 +39,11 @@ public SearchResult( this.options = options; this.request = request; - this.aggregations = (ConcurrentHashMap)((ConcurrentHashMap)_response.get("result")).get("aggregations"); - this.hits = (ArrayList>)((ConcurrentHashMap)_response.get("result")).get("hits"); - this.total = (Integer)((ConcurrentHashMap)_response.get("result")).get("total"); + this.aggregations = (ConcurrentHashMap) ((ConcurrentHashMap) _response.get("result")).get("aggregations"); + this.hits = (ArrayList>) ((ConcurrentHashMap) _response.get("result")).get("hits"); + this.total = ((LazilyParsedNumber) ((ConcurrentHashMap) _response.get("result")).get("total")).intValue(); this.fetched = hits.size(); - this.scrollId = (String)((ConcurrentHashMap)_response.get("result")).get("scrollId"); + this.scrollId = (String) ((ConcurrentHashMap) _response.get("result")).get("scrollId"); } public SearchResult( @@ -56,11 +59,11 @@ public SearchResult( this.options = options; this.request = request; - this.aggregations = (ConcurrentHashMap)((ConcurrentHashMap)_response.get("result")).get("aggregations"); - this.hits = (ArrayList>)((ConcurrentHashMap)_response.get("result")).get("hits"); - this.total = (Integer)((ConcurrentHashMap)_response.get("result")).get("total"); + this.aggregations = (ConcurrentHashMap) ((ConcurrentHashMap) _response.get("result")).get("aggregations"); + this.hits = (ArrayList>) ((ConcurrentHashMap) _response.get("result")).get("hits"); + this.total = ((LazilyParsedNumber) ((ConcurrentHashMap) _response.get("result")).get("total")).intValue(); this.fetched = hits.size() + previouslyFetched; - this.scrollId = (String)((ConcurrentHashMap)_response.get("result")).get("scrollId"); + this.scrollId = (String) ((ConcurrentHashMap) _response.get("result")).get("scrollId"); } private ConcurrentHashMap getScrollRequest() { @@ -76,13 +79,30 @@ private ConcurrentHashMap getSearchAfterRequest() { ConcurrentHashMap nextRequest = this.request; ConcurrentHashMap lastItem = this.hits.get(this.hits.size()); ArrayList searchAfter = new ArrayList<>(); + ArrayList sort = (ArrayList) ((ConcurrentHashMap) this.request.get("body")).get("sort"); + ((ConcurrentHashMap) this.request.get("body")).put("search_after", searchAfter); - //this.request.put(this.request.get("body").get("sort"), searchAfter); - return null; + for (Object value : sort) { + String key; + + if (value instanceof String) { + key = value.toString(); + } else { + key = ((ConcurrentHashMap) value).get("First").toString(); + } + + if (key.equals("_uid")) { + searchAfter.add(this.request.get("collection").toString() + "#" + lastItem.get("_id").toString()); + } else { + ConcurrentHashMap _source = (ConcurrentHashMap) lastItem.get("_source"); + searchAfter.add(_source.get(key)); + } + } + return nextRequest; } - private SearchResult next() throws NotConnectedException, InternalException { + public SearchResult next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { if (this.fetched >= this.total) return null; ConcurrentHashMap nextRequest = new ConcurrentHashMap<>(); @@ -91,16 +111,18 @@ private SearchResult next() throws NotConnectedException, InternalException { nextRequest = this.getScrollRequest(); } - else if (options.getSize() != null - && ((ConcurrentHashMap)this.request.get("body")).get("sort") != null) { + else if (this.options.getSize() != null + && ((ConcurrentHashMap) this.request.get("body")).get("sort") != null) { nextRequest = this.getSearchAfterRequest(); } - else if (options.getSize() != null) { - if (options.getFrom() != null && options.getFrom() > this.total) { + else if (this.options.getSize() != null) { + + if (this.options.getFrom() != null && this.options.getFrom() > this.total) { return null; } - options.setFrom(this.fetched); + + this.options.setFrom(this.fetched); nextRequest = this.request; } @@ -108,7 +130,7 @@ else if (options.getSize() != null) { return null; } - Response response = this.kuzzle.query(nextRequest); + Response response = this.kuzzle.query(nextRequest).get(); return new SearchResult(this.kuzzle, nextRequest, this.options, response, this.fetched); } diff --git a/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java index 54d0badb..9bd6feff 100644 --- a/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java @@ -4,9 +4,9 @@ public class SearchOptions { - private Integer from; + private Integer from = 0; private String scroll; - private Integer size; + private Integer size = 10; /** * Constructor */ diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9e287977..808914a8 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; @@ -414,7 +415,7 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti } // @Test -// public void searchDocumentTestA() throws NotConnectedException, InternalException { +// public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { // // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); // String index = "nyc-open-data"; @@ -435,9 +436,9 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti // assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); // assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); // } -// + // @Test -// public void searchDocumentTestB() throws NotConnectedException, InternalException { +// public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { // // Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); // String index = "nyc-open-data"; @@ -467,21 +468,21 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti // assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); // // } -// -// @Test(expected = NotConnectedException.class) -// public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { -// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); -// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); -// -// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); -// String index = "nyc-open-data"; -// String collection = "yellow-taxi"; -// -// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); -// ConcurrentHashMap match = new ConcurrentHashMap<>(); -// match.put("Hello", "Clarisse"); -// searchQuery.put("match", match); -// -// kuzzleMock.getDocumentController().search(index, collection, searchQuery); -// } + + @Test(expected = NotConnectedException.class) + public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getDocumentController().search(index, collection, searchQuery); + } } From 4ea7ce742dcf6d7b483c06debb535085e048e9dd Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 13 Mar 2020 14:42:13 +0100 Subject: [PATCH 085/134] Add document:mReplace (#69) This PR implements the mReplace method with its unit tests. --- doc/3/controllers/document/m-replace/index.md | 70 ++++++++++++ .../m-replace/snippets/m-replace.java | 54 ++++++++++ .../m-replace/snippets/m-replace.test.yml | 14 +++ .../API/Controllers/DocumentController.java | 50 +++++++++ .../DocumentTest/DocumentTest.java | 102 +++++++++++++++++- 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 doc/3/controllers/document/m-replace/index.md create mode 100644 doc/3/controllers/document/m-replace/snippets/m-replace.java create mode 100644 doc/3/controllers/document/m-replace/snippets/m-replace.test.yml diff --git a/doc/3/controllers/document/m-replace/index.md b/doc/3/controllers/document/m-replace/index.md new file mode 100644 index 00000000..c70fb82e --- /dev/null +++ b/doc/3/controllers/document/m-replace/index.md @@ -0,0 +1,70 @@ +--- +code: true +type: page +title: mReplace +description: Replaces multiple documents +--- + +# mReplace + +Replaces multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mReplace( + final String index, + final String collection, + final ArrayList> documents) +throws NotConnectedException, InternalException + +public CompletableFuture>> mReplace( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `documents` |
ArrayList>
| ArrayList containing the documents to replace | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | + +--- + +### documents + +Each document has the following properties: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `_id` |
String
| Optional document ID. Will be auto-generated if not defined. | +| `body` |
ConcurrentHashMap
| Document body | + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the replaced document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-replace.java diff --git a/doc/3/controllers/document/m-replace/snippets/m-replace.java b/doc/3/controllers/document/m-replace/snippets/m-replace.java new file mode 100644 index 00000000..f9651db0 --- /dev/null +++ b/doc/3/controllers/document/m-replace/snippets/m-replace.java @@ -0,0 +1,54 @@ +ConcurrentHashMap document1 = new ConcurrentHashMap<>(); +ConcurrentHashMap document2 = new ConcurrentHashMap<>(); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + +body.put("name", "Smith"); +body2.put("name", "Freeman"); + +document1.put("_id", "some-id"); +document1.put("body", body); + +document2.put("_id", "some-id2"); +document2.put("body", body2); + +final ArrayList> documents = new ArrayList<>(); +documents.add(document1); +documents.add(document2); + +ConcurrentHashMap> result = kuzzle + .getDocumentController() + .mReplace("nyc-open-data", "yellow-taxi", documents) + .get(); + +/* + result = + { + successes= + [ + { + result=created, + _source= + { + Agent=Smith, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=2, + status=200 + }, + { + result=created, + _source= + { + Gordon=Freeman, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=2, + status=200 + } + ], + errors=[] + } +*/ diff --git a/doc/3/controllers/document/m-replace/snippets/m-replace.test.yml b/doc/3/controllers/document/m-replace/snippets/m-replace.test.yml new file mode 100644 index 00000000..f38b2746 --- /dev/null +++ b/doc/3/controllers/document/m-replace/snippets/m-replace.test.yml @@ -0,0 +1,14 @@ +name: document#mReplace +description: Replaces multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id2/_create + after: +template: print-result-array +expected: + - "id=some-id, _version=2, status=200" + - "id=some-id2, _version=2, status=200" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 66295235..e1483526 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -465,6 +465,56 @@ public CompletableFuture>> mGet( (response) -> (ConcurrentHashMap>) response.result); } + /** + * Replaces multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mReplace( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mReplace") + .put("body", new KuzzleMap().put("documents", documents)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Replaces multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mReplace( + final String index, + final String collection, + final ArrayList> documents) throws NotConnectedException, InternalException { + + return this.mReplace(index, collection, documents, null); + } + /** * Tells if a document exists in a given collection and index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 573e06f7..1e1e24f8 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -582,6 +582,107 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti kuzzleMock.getDocumentController().mGet(index, collection, ids); } + @Test + public void mReplaceDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mReplace(index, collection, documents); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mReplace"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test + public void mReplaceDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mReplace(index, collection, documents, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mReplace"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mReplaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + kuzzleMock.getDocumentController().mReplace(index, collection, documents); + } + @Test public void existsDocumentTest() throws NotConnectedException, InternalException { @@ -612,5 +713,4 @@ public void existsDocumentShouldThrowWhenNotConnected() throws NotConnectedExcep kuzzleMock.getDocumentController().exists(index, collection, "some-id"); } - } From 407d0d0519791bef198257598998210a32712917 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 13 Mar 2020 14:53:20 +0100 Subject: [PATCH 086/134] Add document:mCreateOrReplace (#68) This PR implements the mCreateOrReplace method with its unit tests. --- .../document/m-create-or-replace/index.md | 70 ++++++++++++ .../snippets/m-create-or-replace.java | 54 ++++++++++ .../snippets/m-create-or-replace.test.yml | 12 +++ .../API/Controllers/DocumentController.java | 50 +++++++++ .../DocumentTest/DocumentTest.java | 101 ++++++++++++++++++ 5 files changed, 287 insertions(+) create mode 100644 doc/3/controllers/document/m-create-or-replace/index.md create mode 100644 doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.java create mode 100644 doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.test.yml diff --git a/doc/3/controllers/document/m-create-or-replace/index.md b/doc/3/controllers/document/m-create-or-replace/index.md new file mode 100644 index 00000000..d67f5ecb --- /dev/null +++ b/doc/3/controllers/document/m-create-or-replace/index.md @@ -0,0 +1,70 @@ +--- +code: true +type: page +title: mCreateOrReplace +description: Creates or replaces multiple documents +--- + +# mCreateOrReplace + +Creates or replaces multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mCreateOrReplace( + final String index, + final String collection, + final ArrayList> documents) +throws NotConnectedException, InternalException + +public CompletableFuture>> mCreateOrReplace( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `documents` |
ArrayList>
| ArrayList containing the documents to create | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | + +--- + +### documents + +Each document has the following properties: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `_id` |
String
| Optional document ID. Will be auto-generated if not defined. | +| `body` |
ConcurrentHashMap
| Document body | + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the newly created document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-create-or-replace.java diff --git a/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.java b/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.java new file mode 100644 index 00000000..48af041c --- /dev/null +++ b/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.java @@ -0,0 +1,54 @@ +ConcurrentHashMap document1 = new ConcurrentHashMap<>(); +ConcurrentHashMap document2 = new ConcurrentHashMap<>(); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + +body.put("Agent", "Smith"); +body2.put("Gordon", "Freeman"); + +document1.put("_id", "some-id"); +document1.put("body", body); + +document2.put("_id", "some-id2"); +document2.put("body", body2); + +final ArrayList> documents = new ArrayList<>(); +documents.add(document1); +documents.add(document2); + +ConcurrentHashMap> result = kuzzle + .getDocumentController() + .mCreateOrReplace("nyc-open-data", "yellow-taxi", documents) + .get(); + +/* + result = + { + successes= + [ + { + result=created, + _source= + { + Agent=Smith, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=1, + status=201 + }, + { + result=created, + _source= + { + Gordon=Freeman, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=1, + status=201 + } + ], + errors=[] + } +*/ diff --git a/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.test.yml b/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.test.yml new file mode 100644 index 00000000..f38114bf --- /dev/null +++ b/doc/3/controllers/document/m-create-or-replace/snippets/m-create-or-replace.test.yml @@ -0,0 +1,12 @@ +name: document#mCreateOrReplace +description: Creates or replaces multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result-array +expected: + - "id=some-id, _version=1, status=201" + - "id=some-id2, _version=1, status=201" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index e1483526..5ecd9e1f 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -543,4 +543,54 @@ public CompletableFuture exists( .thenApplyAsync( (response) -> (Boolean) response.result); } + + /** + * Creates or replaces multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreateOrReplace( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mCreateOrReplace") + .put("body", new KuzzleMap().put("documents", documents)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Creates or replaces multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreateOrReplace( + final String index, + final String collection, + final ArrayList> documents) throws NotConnectedException, InternalException { + + return this.mCreateOrReplace(index, collection, documents, null); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 1e1e24f8..ee3a3950 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -713,4 +713,105 @@ public void existsDocumentShouldThrowWhenNotConnected() throws NotConnectedExcep kuzzleMock.getDocumentController().exists(index, collection, "some-id"); } + + @Test + public void mCreateOrReplaceDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreateOrReplace"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test + public void mCreateOrReplaceDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreateOrReplace"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); + } } From 5d2df58086947640201ef7473fa0a9cfe082b481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Blondel?= Date: Mon, 16 Mar 2020 17:18:44 +0100 Subject: [PATCH 087/134] Auto reconnect/resubscribe (#71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * online tools * fix * clear subscriptionsCache after resubscribing * clear subscriptionsCache after resubscribing * fix merge errors * fix count * adapt count test * remove old import in snippet * Apply suggestions from code review Co-Authored-By: Sébastien Cottinet Co-authored-by: Sébastien Cottinet Co-authored-by: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> --- doc/3/core-classes/kuzzle-options/index.md | 10 +- .../network-loss-resilience/index.md | 19 ++++ doc/3/protocols/websocket-options/index.md | 20 +++- .../API/Controllers/RealtimeController.java | 91 +++++++++++++++---- src/main/java/io/kuzzle/sdk/Kuzzle.java | 16 +++- .../io/kuzzle/sdk/Options/KuzzleOptions.java | 12 +++ .../Options/Protocol/WebSocketOptions.java | 30 ++++++ .../io/kuzzle/sdk/Protocol/ProtocolState.java | 1 + .../io/kuzzle/sdk/Protocol/WebSocket.java | 90 ++++++++++++++---- .../Controllers/RealtimeControllerTest.java | 2 +- 10 files changed, 243 insertions(+), 48 deletions(-) create mode 100644 doc/3/essentials/network-loss-resilience/index.md diff --git a/doc/3/core-classes/kuzzle-options/index.md b/doc/3/core-classes/kuzzle-options/index.md index 193fa890..8f7aa867 100644 --- a/doc/3/core-classes/kuzzle-options/index.md +++ b/doc/3/core-classes/kuzzle-options/index.md @@ -55,13 +55,11 @@ public int getMaxRequestDelay() public KuzzleOptions setMaxRequestDelay(int maxRequestDelay) ``` -### queueFilter +### autoResubscribe -Function to filter the request queue before replaying requests. +Automatically renew all subscriptions on a `reconnected` event. ```java -public Predicate> getQueueFilter() -public KuzzleOptions setQueueFilter( - Predicate> filter -) +public boolean isAutoResubscribe(); +public KuzzleOptions setAutoResubscribe(boolean autoResubscribe); ``` diff --git a/doc/3/essentials/network-loss-resilience/index.md b/doc/3/essentials/network-loss-resilience/index.md new file mode 100644 index 00000000..ecda8d05 --- /dev/null +++ b/doc/3/essentials/network-loss-resilience/index.md @@ -0,0 +1,19 @@ +--- +code: false +type: page +title: Network Loss Resilience +description: Learn how to use the Kuzzle JAVA SDK with an instable network +order: 400 +--- + +# Network Loss Resilience + +The Kuzzle JAVA SDK provides tools that allow it to be used with an unstable network connection. + +## Automatic reconnection & resubscription + +The Kuzzle JAVA SDK can automatically reconnect in case of a network disconnection and it can renew realtime subscriptions if there are any. + +To control the auto reconnection feature with WebSocket (enabled by default), refer to the `autoReconnect` option of the [WebSocketOptions](/sdk/java/3/protocols/websocket-options) object. + +To control the auto resubscription (enabled by default), refer to the `autoResubscribe` option of the [KuzzleOptions](/sdk/java/3/core-classes/kuzzle-options) object. diff --git a/doc/3/protocols/websocket-options/index.md b/doc/3/protocols/websocket-options/index.md index fc0801ea..0c0cd749 100644 --- a/doc/3/protocols/websocket-options/index.md +++ b/doc/3/protocols/websocket-options/index.md @@ -52,5 +52,23 @@ If the websocket auto reconnects. ```java public boolean getAutoReconnect() -public KuzzleOptions setAutoReconnect(boolean autoReconnect) +public WebSocketOptions setAutoReconnect(boolean autoReconnect) +``` + +### reconnectionDelay + +Time between each reconnection attempt. + +```java +public long getReconnectionDelay(); +public WebSocketOptions setReconnectionDelay(long reconnectionDelay); +``` + +### reconnectionRetries + +Number of attempts to try and reconnect. -1 for infinite attempts until the connection is established again. + +```java +public long getReconnectionRetries(); +public WebSocketOptions setReconnectionRetries(long reconnectionRetries); ``` diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java index d1aa0ca2..acdc03b6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/RealtimeController.java @@ -8,23 +8,36 @@ import io.kuzzle.sdk.Handlers.NotificationHandler; import io.kuzzle.sdk.Kuzzle; import io.kuzzle.sdk.Options.SubscribeOptions; +import io.kuzzle.sdk.Protocol.ProtocolState; import java.util.ArrayList; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; public class RealtimeController extends BaseController { private class Subscription { - public boolean subscribeToSelf; + public String index; + public String collection; + public ConcurrentHashMap filter; public NotificationHandler handler; - - public Subscription(final boolean subscribeToSelf, final NotificationHandler handler) { - this.subscribeToSelf = subscribeToSelf; + public SubscribeOptions options; + + public Subscription(final String index, + final String collection, + final ConcurrentHashMap filter, + final NotificationHandler handler, + final SubscribeOptions options) { + this.index = index; + this.collection = collection; + this.filter = filter; this.handler = handler; + this.options = (options != null ? options : new SubscribeOptions()); } } - private ConcurrentHashMap> subscriptions = new ConcurrentHashMap<>(); + private ConcurrentHashMap> currentSubscriptions = new ConcurrentHashMap<>(); + private ConcurrentHashMap> subscriptionsCache = new ConcurrentHashMap<>(); public RealtimeController(Kuzzle kuzzle) { super(kuzzle); @@ -41,17 +54,22 @@ public RealtimeController(Kuzzle kuzzle) { sdkInstanceId = response.Volatile.get("sdkInstanceId").toString(); } - ArrayList subs = RealtimeController.this.subscriptions.get(((Response) args[0]).room); + ArrayList subs = RealtimeController.this.currentSubscriptions.get(((Response) args[0]).room); if (subs != null) { final String instanceId = sdkInstanceId; subs.forEach(sub -> { - if (sub != null && (instanceId.equals(kuzzle.instanceId) && sub.subscribeToSelf || !instanceId.equals(kuzzle.instanceId))) { + if (sub != null && (instanceId.equals(kuzzle.instanceId) && sub.options.isSubscribeToSelf() || !instanceId.equals(kuzzle.instanceId))) { sub.handler.run(response); } }); } }); + kuzzle.register(Event.networkStateChange, state -> { + if (state[0] == ProtocolState.CLOSE) { + this.currentSubscriptions.clear(); + } + }); } /** @@ -67,7 +85,7 @@ public CompletableFuture count(final String roomId) throws NotConnected .query(new KuzzleMap() .put("controller", "realtime") .put("action", "count") - .put("body", new KuzzleMap().put("room_id", roomId))) + .put("body", new KuzzleMap().put("roomId", roomId))) .thenApplyAsync((response) -> ((KuzzleMap) response.result).getNumber("count").intValue()); } @@ -94,6 +112,22 @@ public CompletableFuture publish(final String index, final String collecti .thenApplyAsync((response) -> null); } + public void renewSubscriptions() { + for (Map.Entry sub : subscriptionsCache.entrySet()) { + subscriptionsCache.get(sub.getKey()).clear(); + ((ArrayList) sub.getValue()).forEach(subscription -> + { + try { + subscribe(subscription); + } catch (NotConnectedException e) { + e.printStackTrace(); + } catch (InternalException e) { + e.printStackTrace(); + } + }); + } + } + /** * Subscribe to a collection. * @@ -108,12 +142,11 @@ public CompletableFuture publish(final String index, final String collecti */ public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler, final SubscribeOptions options) throws NotConnectedException, InternalException { ConcurrentHashMap queryOptions = new ConcurrentHashMap<>(); - boolean subscribeToSelf = true; + final SubscribeOptions opts = (options == null ? new SubscribeOptions() : new SubscribeOptions(options)); synchronized (RealtimeController.class) { - if (options != null) { - subscribeToSelf = options.isSubscribeToSelf(); - queryOptions = options.toHashMap(); + if (opts != null) { + queryOptions = opts.toHashMap(); } } @@ -124,29 +157,43 @@ public CompletableFuture subscribe(final String index, final String coll .put("collection", collection) .put("body", filters); - boolean finalSubscribeToSelf = subscribeToSelf; return kuzzle .query(query) .thenApplyAsync( (response) -> { String channel = ((ConcurrentHashMap) response.result).get("channel").toString(); Subscription subscription = new Subscription( - options == null ? new SubscribeOptions().isSubscribeToSelf() : finalSubscribeToSelf, - handler + index, + collection, + filters, + handler, + opts ); - if (subscriptions.get(channel) == null) { + if (currentSubscriptions.get(channel) == null) { ArrayList item = new ArrayList<>(); item.add(subscription); - subscriptions.put(channel, item); + currentSubscriptions.put(channel, item); + subscriptionsCache.put(channel, item); } else { - subscriptions.get(channel).add(subscription); + currentSubscriptions.get(channel).add(subscription); + subscriptionsCache.get(channel).add(subscription); } return ((ConcurrentHashMap) response.result).get("roomId").toString(); }); } + private CompletableFuture subscribe(final Subscription subscribe) throws NotConnectedException, InternalException { + return subscribe( + subscribe.index, + subscribe.collection, + subscribe.filter, + subscribe.handler, + subscribe.options + ); + } + public CompletableFuture subscribe(final String index, final String collection, final ConcurrentHashMap filters, final NotificationHandler handler) throws NotConnectedException, InternalException { return this.subscribe(index, collection, filters, handler, null); } @@ -166,9 +213,13 @@ public CompletableFuture unsubscribe(final String roomId) throws NotConnec .put("action", "unsubscribe") .put("body", new KuzzleMap().put("roomId", roomId))) .thenApplyAsync((response) -> { - ArrayList subs = subscriptions.get(roomId); + ArrayList subs = currentSubscriptions.get(roomId); + if (subs != null) { + currentSubscriptions.get(roomId).clear(); + } + subs = subscriptionsCache.get(roomId); if (subs != null) { - subscriptions.get(roomId).clear(); + subscriptionsCache.get(roomId).clear(); } return null; }); diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 696f0720..b77a28ae 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -60,6 +60,8 @@ public class Kuzzle extends EventManager { private RealtimeController realtimeController; + private boolean autoResubscribe; + /** * Initialize a new instance of Kuzzle * @@ -134,6 +136,8 @@ public Kuzzle(final AbstractProtocol networkProtocol, kOptions.getRefreshedTokenDuration()); this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); + this.autoResubscribe = options.isAutoResubscribe(); + this.version = "3"; this.instanceId = UUID.randomUUID().toString(); this.sdkName = "java@" + version; @@ -199,11 +203,13 @@ protected void onResponseReceived(final Object... payload) { protected void onStateChanged(final Object... args) { // If not connected anymore: close tasks and clean up the requests buffer - if ((ProtocolState) args[0] == ProtocolState.CLOSE) { + if (args[0] == ProtocolState.CLOSE) { for (final Task task : requests.values()) { task.setException(new ConnectionLostException()); } requests.clear(); + } else if (args[0] == ProtocolState.OPEN && realtimeController != null && autoResubscribe) { + realtimeController.renewSubscriptions(); } } @@ -281,4 +287,12 @@ public void setAuthenticationToken(final String token) { } authenticationToken.set(token); } + + public boolean isAutoResubscribe() { + return autoResubscribe; + } + + public void setAutoResubscribe(boolean autoResubscribe) { + this.autoResubscribe = autoResubscribe; + } } diff --git a/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java index 59376c6b..fed2d840 100644 --- a/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/KuzzleOptions.java @@ -33,6 +33,8 @@ public class KuzzleOptions { private Predicate> queueFilter = ( ConcurrentHashMap obj) -> true; + private boolean autoResubscribe = true; + /** * Initialize a new KuzzleOptions instance. */ @@ -48,6 +50,7 @@ public KuzzleOptions(KuzzleOptions options) { this.maxQueueSize = options.maxQueueSize; this.minTokenDuration = options.minTokenDuration; this.refreshedTokenDuration = options.refreshedTokenDuration; + this.autoResubscribe = options.autoResubscribe; this.maxRequestDelay = options.maxRequestDelay; @@ -147,4 +150,13 @@ public KuzzleOptions setQueueFilter( (ConcurrentHashMap obj) -> true); return this; } + + public boolean isAutoResubscribe() { + return autoResubscribe; + } + + public KuzzleOptions setAutoResubscribe(boolean autoResubscribe) { + this.autoResubscribe = autoResubscribe; + return this; + } } diff --git a/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java index 4ebf007e..40c72496 100644 --- a/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/Protocol/WebSocketOptions.java @@ -22,6 +22,16 @@ public class WebSocketOptions { */ private boolean autoReconnect = true; + /** + * The number of milliseconds between 2 automatic reconnection attempts. + */ + private long reconnectionDelay = 1000; + + /** + * The maximum number of automatic reconnection attempts. + */ + private long reconnectionRetries = 20; + /** * Initialize a new WebSocketOptions instance. */ @@ -39,6 +49,8 @@ public WebSocketOptions(WebSocketOptions other) { this.ssl = other.ssl; this.connectionTimeout = other.connectionTimeout; this.autoReconnect = other.autoReconnect; + this.reconnectionDelay = other.reconnectionDelay; + this.reconnectionRetries = other.reconnectionRetries; } /** @@ -112,4 +124,22 @@ public WebSocketOptions setAutoReconnect(boolean autoReconnect) { this.autoReconnect = autoReconnect; return this; } + + public long getReconnectionDelay() { + return reconnectionDelay; + } + + public WebSocketOptions setReconnectionDelay(long reconnectionDelay) { + this.reconnectionDelay = reconnectionDelay; + return this; + } + + public long getReconnectionRetries() { + return reconnectionRetries; + } + + public WebSocketOptions setReconnectionRetries(long reconnectionRetries) { + this.reconnectionRetries = reconnectionRetries; + return this; + } } diff --git a/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java b/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java index 5b3dcf6b..e53af578 100644 --- a/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java +++ b/src/main/java/io/kuzzle/sdk/Protocol/ProtocolState.java @@ -3,4 +3,5 @@ public enum ProtocolState { CLOSE, // The network protocol does not accept requests. OPEN, // The network protocol accepts new requests. + RECONNECTING, } diff --git a/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java index dca6e8ef..89e7cf02 100644 --- a/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java +++ b/src/main/java/io/kuzzle/sdk/Protocol/WebSocket.java @@ -3,6 +3,7 @@ import com.neovisionaries.ws.client.WebSocketAdapter; import com.neovisionaries.ws.client.WebSocketException; import com.neovisionaries.ws.client.WebSocketFactory; +import com.neovisionaries.ws.client.WebSocketFrame; import io.kuzzle.sdk.CoreClasses.Json.JsonSerializer; import io.kuzzle.sdk.Events.Event; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; @@ -11,22 +12,22 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.concurrent.*; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingDeque; public class WebSocket extends AbstractProtocol { + protected final boolean ssl; + protected final int port; protected BlockingDeque> queue; protected com.neovisionaries.ws.client.WebSocket socket; protected ProtocolState state = ProtocolState.CLOSE; protected URI uri; - - protected final boolean ssl; - protected final int port; protected int connectionTimeout; - - public ProtocolState getState() { - return state; - } + protected boolean autoReconnect; + protected long reconnectionDelay; + protected long reconnectionRetries; public WebSocket(URI uri) throws Exception { WebSocketOptions options = new WebSocketOptions(); @@ -45,6 +46,9 @@ public WebSocket(URI uri) throws Exception { ssl = wsOptions.isSsl(); port = wsOptions.getPort(); connectionTimeout = wsOptions.getConnectionTimeout(); + autoReconnect = wsOptions.isAutoReconnect(); + reconnectionDelay = wsOptions.getReconnectionDelay(); + reconnectionRetries = wsOptions.getReconnectionRetries(); this.uri = new URI( (ssl ? "wss" : "ws") + "://" + uri.getHost() + ":" + port + "/"); @@ -62,10 +66,8 @@ public WebSocket(String host) } /** - * @param host - * Kuzzle host address - * @param options - * WebSocket options + * @param host Kuzzle host address + * @param options WebSocket options * @throws URISyntaxException * @throws IllegalArgumentException */ @@ -79,6 +81,9 @@ public WebSocket(String host, WebSocketOptions options) ssl = wsOptions.isSsl(); port = wsOptions.getPort(); connectionTimeout = wsOptions.getConnectionTimeout(); + autoReconnect = wsOptions.isAutoReconnect(); + reconnectionDelay = wsOptions.getReconnectionDelay(); + reconnectionRetries = wsOptions.getReconnectionRetries(); if (host == null || host.isEmpty()) { throw new IllegalArgumentException("Host name/address can't be empty"); @@ -87,6 +92,10 @@ public WebSocket(String host, WebSocketOptions options) this.queue = new LinkedBlockingDeque<>(); } + public ProtocolState getState() { + return state; + } + @Override public void send(ConcurrentHashMap payload) { queue.add(payload); @@ -136,23 +145,66 @@ public void onTextMessage( super.onTextMessage(websocket, text); WebSocket.super.trigger(Event.networkResponseReceived, text); } + + @Override + public void onDisconnected(com.neovisionaries.ws.client.WebSocket websocket, + WebSocketFrame serverCloseFrame, + WebSocketFrame clientCloseFrame, + boolean closedByServer) { + socket.clearListeners(); + socket = null; + CloseState(autoReconnect); + } }); } + private void tryToReconnect() { + if (state == ProtocolState.RECONNECTING) { + return; + } + + state = ProtocolState.RECONNECTING; + super.trigger(Event.networkStateChange, state); + for (int i = 0; i < reconnectionRetries; i++) { + try { + connect(); + break; + } catch (WebSocketException e) { + try { + socket = null; + Thread.sleep(reconnectionDelay); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } catch (IOException e) { + try { + socket = null; + Thread.sleep(reconnectionDelay); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + } + } + /** * Disconnects this instance. */ @Override public void disconnect() { - CloseState(); + CloseState(false); } - protected void CloseState() { - if (socket != null) { - socket.disconnect(); - state = ProtocolState.CLOSE; - socket = null; - super.trigger(Event.networkStateChange, state); + synchronized protected void CloseState(final boolean tryToReconnect) { + if (state != ProtocolState.CLOSE) { + if (tryToReconnect) { + tryToReconnect(); + } else { + socket.disconnect(); + state = ProtocolState.CLOSE; + socket = null; + super.trigger(Event.networkStateChange, state); + } } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java index d04c03e0..e078d14c 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/RealtimeControllerTest.java @@ -35,7 +35,7 @@ public void countTest() throws NotConnectedException, InternalException { assertEquals("realtime", ((KuzzleMap) arg.getValue()).getString("controller")); assertEquals("count", ((KuzzleMap) arg.getValue()).getString("action")); - assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("room_id")); + assertEquals("roomId", ((KuzzleMap)((KuzzleMap) arg.getValue()).get("body")).getString("roomId")); } @Test From 0ff2787860e82a82da0a43f6af9c448dfe78786d Mon Sep 17 00:00:00 2001 From: jenow Date: Wed, 18 Mar 2020 10:56:43 +0100 Subject: [PATCH 088/134] fix null options --- src/main/java/io/kuzzle/sdk/Kuzzle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index b77a28ae..cd4f6815 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -136,7 +136,7 @@ public Kuzzle(final AbstractProtocol networkProtocol, kOptions.getRefreshedTokenDuration()); this.maxRequestDelay = new AtomicInteger(kOptions.getMaxRequestDelay()); - this.autoResubscribe = options.isAutoResubscribe(); + this.autoResubscribe = kOptions.isAutoResubscribe(); this.version = "3"; this.instanceId = UUID.randomUUID().toString(); From e96b03553bda002eee8884b3bfaec9e7862d5e98 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 18 Mar 2020 11:51:12 +0100 Subject: [PATCH 089/134] add document:count --- doc/3/controllers/document/count/index.md | 53 ++++++++++++++++++ .../document/count/snippets/count.java | 5 ++ .../document/count/snippets/count.test.yml | 18 ++++++ .../API/Controllers/DocumentController.java | 48 ++++++++++++++++ .../DocumentTest/DocumentTest.java | 55 +++++++++++++++++++ 5 files changed, 179 insertions(+) create mode 100644 doc/3/controllers/document/count/index.md create mode 100644 doc/3/controllers/document/count/snippets/count.java create mode 100644 doc/3/controllers/document/count/snippets/count.test.yml diff --git a/doc/3/controllers/document/count/index.md b/doc/3/controllers/document/count/index.md new file mode 100644 index 00000000..9759dc11 --- /dev/null +++ b/doc/3/controllers/document/count/index.md @@ -0,0 +1,53 @@ +--- +code: true +type: page +title: count +description: Counts documents in a collection. +--- + +# count + +Counts documents in a collection. + +A query can be provided to alter the count result, otherwise returns the total number of documents in the collection. + +Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html) syntax. + +--- + +## Arguments + +```java +public CompletableFuture count( + final String index, + final String collection) +throws NotConnectedException, InternalException + +``` + +```java +public CompletableFuture count( + final String index, + final String collection, + final ConcurrentHaspMap searchQuery) +throws NotConnectedException, InternalException + +``` + +--- + +| Argument | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
string
| Index name | +| `collection` |
string
| Collection name | +| `query` |
object
| Query to match | + +--- + +## Return + +Returns an Integer. + +## Usage + +<<< ./snippets/count.java \ No newline at end of file diff --git a/doc/3/controllers/document/count/snippets/count.java b/doc/3/controllers/document/count/snippets/count.java new file mode 100644 index 00000000..dbe7db26 --- /dev/null +++ b/doc/3/controllers/document/count/snippets/count.java @@ -0,0 +1,5 @@ + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + Integer result = kuzzle.getDocumentController().count("nyc-open-data", "yellow-taxi", searchQuery).get(); \ No newline at end of file diff --git a/doc/3/controllers/document/count/snippets/count.test.yml b/doc/3/controllers/document/count/snippets/count.test.yml new file mode 100644 index 00000000..4e7b4670 --- /dev/null +++ b/doc/3/controllers/document/count/snippets/count.test.yml @@ -0,0 +1,18 @@ +--- +name: document#count +description: Counts documents matching the given query +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{"Hello": "Clarisse"}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh + after: +template: print-result +expected: 5 \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 5ecd9e1f..abd29e69 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk.API.Controllers; +import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; @@ -593,4 +594,51 @@ public CompletableFuture>> mCreateOr return this.mCreateOrReplace(index, collection, documents, null); } + + /** + * Counts documents in a collection. + * + * @param index + * @param collection + * @paran searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture count( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("body", new KuzzleMap().put("query", searchQuery)) + .put("action", "count"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> ((LazilyParsedNumber) ((ConcurrentHashMap)response.result).get("count")).intValue()); + } + + /** + * Counts documents in a collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture count( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + + return this.count(index, collection, searchQuery); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index ee3a3950..ceb110e9 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -814,4 +814,59 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); } + + @Test + public void countDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().count(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "count"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test + public void countDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getDocumentController().count(index, collection, searchQuery); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "count"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test(expected = NotConnectedException.class) + public void countDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().count(index, collection); + } } From f972d68f8a4fd11a139066d44506f32a9ea56d87 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 18 Mar 2020 11:55:39 +0100 Subject: [PATCH 090/134] update doc --- doc/3/controllers/document/count/index.md | 10 +++++----- doc/3/controllers/document/count/snippets/count.java | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/3/controllers/document/count/index.md b/doc/3/controllers/document/count/index.md index 9759dc11..8bfd42eb 100644 --- a/doc/3/controllers/document/count/index.md +++ b/doc/3/controllers/document/count/index.md @@ -36,11 +36,11 @@ throws NotConnectedException, InternalException --- -| Argument | Type | Description | -| ------------ | ----------------- | --------------- | -| `index` |
string
| Index name | -| `collection` |
string
| Collection name | -| `query` |
object
| Query to match | +| Argument | Type | Description | +| ------------------ | -------------------------------------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `searchQuery` |
ConcurrentHashMap
| Query to match | --- diff --git a/doc/3/controllers/document/count/snippets/count.java b/doc/3/controllers/document/count/snippets/count.java index dbe7db26..9fd3ad56 100644 --- a/doc/3/controllers/document/count/snippets/count.java +++ b/doc/3/controllers/document/count/snippets/count.java @@ -2,4 +2,7 @@ ConcurrentHashMap match = new ConcurrentHashMap<>(); match.put("Hello", "Clarisse"); searchQuery.put("match", match); - Integer result = kuzzle.getDocumentController().count("nyc-open-data", "yellow-taxi", searchQuery).get(); \ No newline at end of file + Integer result = kuzzle + .getDocumentController() + .count("nyc-open-data", "yellow-taxi", searchQuery) + .get(); \ No newline at end of file From f8344e7e70ae0260b00e905a205e1038fc6bfe6a Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 18 Mar 2020 14:37:16 +0100 Subject: [PATCH 091/134] Update doc/3/controllers/document/count/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/count/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/controllers/document/count/index.md b/doc/3/controllers/document/count/index.md index 8bfd42eb..7be36d87 100644 --- a/doc/3/controllers/document/count/index.md +++ b/doc/3/controllers/document/count/index.md @@ -11,7 +11,7 @@ Counts documents in a collection. A query can be provided to alter the count result, otherwise returns the total number of documents in the collection. -Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html) syntax. +Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax. --- @@ -50,4 +50,4 @@ Returns an Integer. ## Usage -<<< ./snippets/count.java \ No newline at end of file +<<< ./snippets/count.java From be2c706b5667cdaaaa1535184b558d7c3ffa7bb5 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 19 Mar 2020 16:47:15 +0100 Subject: [PATCH 092/134] wip test --- .../DocumentTest/DocumentTest.java | 153 +++++++++++------- 1 file changed, 99 insertions(+), 54 deletions(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 808914a8..b0b4c61a 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -1,6 +1,10 @@ package io.kuzzle.test.API.Controllers.DocumentTest; +import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.ErrorResponse; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.SearchResult; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; @@ -16,9 +20,12 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; +import java.lang.Thread; + import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; @@ -414,60 +421,98 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti kuzzleMock.getDocumentController().mGet(index, collection, ids); } -// @Test -// public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { -// -// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); -// String index = "nyc-open-data"; -// String collection = "yellow-taxi"; -// -// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); -// ConcurrentHashMap match = new ConcurrentHashMap<>(); -// match.put("Hello", "Clarisse"); -// searchQuery.put("match", match); -// -// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); -// -// kuzzleMock.getDocumentController().search(index, collection, searchQuery); -// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); -// -// assertEquals((arg.getValue()).getString("controller"), "document"); -// assertEquals((arg.getValue()).getString("action"), "search"); -// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); -// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); -// } - -// @Test -// public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { -// -// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); -// String index = "nyc-open-data"; -// String collection = "yellow-taxi"; -// -// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); -// ConcurrentHashMap match = new ConcurrentHashMap<>(); -// match.put("Hello", "Clarisse"); -// searchQuery.put("match", match); -// -// SearchOptions options = new SearchOptions(); -// options.setFrom(0); -// options.setScroll("30s"); -// options.setSize(20); -// -// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); -// -// kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); -// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); -// -// assertEquals((arg.getValue()).getString("controller"), "document"); -// assertEquals((arg.getValue()).getString("action"), "search"); -// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); -// assertEquals((arg.getValue()).getString("scroll"), "30s"); -// assertEquals((arg.getValue()).getNumber("size"), 20); -// assertEquals((arg.getValue()).getNumber("from"), 0); -// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); -// -// } + @Test + public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + CompletableFuture queryResponse = new CompletableFuture<>(); + + + Response r = new Response(); + r.result = new ConcurrentHashMap(); + ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); + ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); + ((ConcurrentHashMap)r.result).put("scrollId", ""); + ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); + doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); + + new Thread(() -> { + try { + kuzzleMock.getDocumentController().search(index, collection, searchQuery); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + queryResponse.complete(r); + Thread.sleep(1000); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "search"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test + public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + SearchOptions options = new SearchOptions(); + options.setSize(10); + options.setFrom(0); + options.setScroll("30s"); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + CompletableFuture queryResponse = new CompletableFuture<>(); + + Response r = new Response(); + r.result = new ConcurrentHashMap(); + ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); + ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); + ((ConcurrentHashMap)r.result).put("scrollId", ""); + ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); + doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); + + new Thread(() -> { + try { + kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + queryResponse.complete(r); + Thread.sleep(1000); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "search"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getNumber("from"), 0); + assertEquals((arg.getValue()).getNumber("size"), 10); + assertEquals((arg.getValue()).getString("scroll"), "30s"); + + assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test(expected = NotConnectedException.class) public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { From 69ae9aa28faf3a6374601b6d13470866c56de49f Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 19 Mar 2020 17:03:40 +0100 Subject: [PATCH 093/134] conflict [ci skip] --- .../API/Controllers/DocumentController.java | 110 ++++----- .../DocumentTest/DocumentTest.java | 216 +++++++++--------- 2 files changed, 162 insertions(+), 164 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index eaa6194b..7ebe82ab 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -316,59 +316,59 @@ public CompletableFuture>> mGet( (response) -> (ConcurrentHashMap>) response.result); } - /** - * Searches documents. - * - * @param index - * @param collection - * @param searchQuery - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public SearchResult search( - final String index, - final String collection, - final ConcurrentHashMap searchQuery, - final SearchOptions options) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - final KuzzleMap query = new KuzzleMap(); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "search") - .put("body", new KuzzleMap().put("query", searchQuery)); - - if (options != null) { - query - .put("from", options.getFrom()) - .put("size", options.getSize()); - if (options.getScroll() != null) { - query.put("scroll", options.getScroll()); - } - } - - Response response = kuzzle.query(query).get(); - return new SearchResult(kuzzle, query, options, response); - } - - /** - * Searches documents. - * - * @param index - * @param collection - * @param searchQuery - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public SearchResult search( - final String index, - final String collection, - final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - return this.search(index, collection, searchQuery, new SearchOptions()); - } +// /** +// * Searches documents. +// * +// * @param index +// * @param collection +// * @param searchQuery +// * @param options +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public SearchResult search( +// final String index, +// final String collection, +// final ConcurrentHashMap searchQuery, +// final SearchOptions options) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// final KuzzleMap query = new KuzzleMap(); +// query +// .put("index", index) +// .put("collection", collection) +// .put("controller", "document") +// .put("action", "search") +// .put("body", new KuzzleMap().put("query", searchQuery)); +// +// if (options != null) { +// query +// .put("from", options.getFrom()) +// .put("size", options.getSize()); +// if (options.getScroll() != null) { +// query.put("scroll", options.getScroll()); +// } +// } +// +// Response response = kuzzle.query(query).get(); +// return new SearchResult(kuzzle, query, options, response); +// } +// +// /** +// * Searches documents. +// * +// * @param index +// * @param collection +// * @param searchQuery +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public SearchResult search( +// final String index, +// final String collection, +// final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// return this.search(index, collection, searchQuery, new SearchOptions()); +// } } \ No newline at end of file diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index b0b4c61a..8df139c0 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -421,113 +421,111 @@ public void mGetDocumentShouldThrowWhenNotConnected() throws NotConnectedExcepti kuzzleMock.getDocumentController().mGet(index, collection, ids); } - @Test - public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - searchQuery.put("match", match); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap)r.result).put("scrollId", ""); - ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getDocumentController().search(index, collection, searchQuery); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "search"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - - } - - @Test - public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - SearchOptions options = new SearchOptions(); - options.setSize(10); - options.setFrom(0); - options.setScroll("30s"); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - searchQuery.put("match", match); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap)r.result).put("scrollId", ""); - ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "search"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getNumber("from"), 0); - assertEquals((arg.getValue()).getNumber("size"), 10); - assertEquals((arg.getValue()).getString("scroll"), "30s"); - - assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - - } - - - - @Test(expected = NotConnectedException.class) - public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - searchQuery.put("match", match); - - kuzzleMock.getDocumentController().search(index, collection, searchQuery); - } +// @Test +// public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap)r.result).put("scrollId", ""); +// ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test +// public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// SearchOptions options = new SearchOptions(); +// options.setSize(10); +// options.setFrom(0); +// options.setScroll("30s"); +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap)r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap)r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap)r.result).put("scrollId", ""); +// ((ConcurrentHashMap)r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals((arg.getValue()).getNumber("from"), 0); +// assertEquals((arg.getValue()).getNumber("size"), 10); +// assertEquals((arg.getValue()).getString("scroll"), "30s"); +// +// assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test(expected = NotConnectedException.class) +// public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// } } From 7fc17ea4f2ae0533e09c3796841ad8350b4d1bff Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 19 Mar 2020 17:09:05 +0100 Subject: [PATCH 094/134] update documentcontroller.java --- .../java/io/kuzzle/sdk/API/Controllers/DocumentController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 725edf51..9afa68a2 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -607,7 +607,6 @@ public CompletableFuture>> mCreateOr * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException - * @paran searchQuery */ public CompletableFuture count( final String index, From e220c08ba1fd2cc66f18dba23c0abb903bec6439 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:05:39 +0100 Subject: [PATCH 095/134] Add document:mUpdate (#70) ## What does this PR do ? This PR implements the `mUpdate` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data` and a `yellow-taxi` collection in the admin console. Create 2 documents `some-id1` and `some-id2`. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class mUpdateDocument { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); ConcurrentHashMap document1 = new ConcurrentHashMap<>(); ConcurrentHashMap body1 = new ConcurrentHashMap<>(); ConcurrentHashMap document2 = new ConcurrentHashMap<>(); ConcurrentHashMap body2 = new ConcurrentHashMap<>(); document1.put("_id", "some-id1"); body1.put("key", "value"); document1.put("body", body1); document2.put("_id", "some-id2"); body2.put("key", "value"); document2.put("body", body2); ArrayList> content = new ArrayList<>(); content.add(document1); content.add(document2); ConcurrentHashMap response = kuzzle.getDocumentController().mUpdate("nyc-open-data", "yellow-taxi", content) .get(); System.out.println(response); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` You should see the documents updated. --- doc/3/controllers/document/m-update/index.md | 82 ++++ .../document/m-update/snippets/m-update.java | 54 +++ .../m-update/snippets/m-update.test.yml | 14 + .../API/Controllers/DocumentController.java | 360 ++++++++------- .../io/kuzzle/sdk/Options/CreateOptions.java | 11 + .../DocumentTest/DocumentTest.java | 426 +++++++++++------- 6 files changed, 635 insertions(+), 312 deletions(-) create mode 100644 doc/3/controllers/document/m-update/index.md create mode 100644 doc/3/controllers/document/m-update/snippets/m-update.java create mode 100644 doc/3/controllers/document/m-update/snippets/m-update.test.yml diff --git a/doc/3/controllers/document/m-update/index.md b/doc/3/controllers/document/m-update/index.md new file mode 100644 index 00000000..fb9a72df --- /dev/null +++ b/doc/3/controllers/document/m-update/index.md @@ -0,0 +1,82 @@ +--- +code: true +type: page +title: mUpdate +description: Updates multiple documents +--- + +# mUpdate + +Updates multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mUpdate( + final String index, + final String collection, + final ArrayList> documents) +throws NotConnectedException, InternalException + +public CompletableFuture>> mUpdate( + final String index, + final String collection, + final ArrayList> documents, + final UpdateOptions options) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `documents` |
ArrayList>
| ArrayList containing the documents to update | +| `options` |
UpdateOptions

(`null`) | Query options | + +--- + +### documents + +Each document has the following properties: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `_id` |
String
| Document ID | +| `body` |
ConcurrentHashMap
| Document body | + +### options + +An [UpdateOptions](/sdk/java/3/core-classes/update-options) object. + +The `mUpdate` method takes into account those following arguments: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `retryOnConflict` |
Integer
(optional) | The number of times the database layer should retry in case of version conflict | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | + + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Updated document | +| `_id` |
String
| ID of the updated document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-update.java diff --git a/doc/3/controllers/document/m-update/snippets/m-update.java b/doc/3/controllers/document/m-update/snippets/m-update.java new file mode 100644 index 00000000..3e271495 --- /dev/null +++ b/doc/3/controllers/document/m-update/snippets/m-update.java @@ -0,0 +1,54 @@ +ConcurrentHashMap document1 = new ConcurrentHashMap<>(); +ConcurrentHashMap document2 = new ConcurrentHashMap<>(); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + +body.put("name", "Smith"); +body2.put("name", "Freeman"); + +document1.put("_id", "some-id"); +document1.put("body", body); + +document2.put("_id", "some-id2"); +document2.put("body", body2); + +final ArrayList> documents = new ArrayList<>(); +documents.add(document1); +documents.add(document2); + +ConcurrentHashMap> result = kuzzle + .getDocumentController() + .mUpdate("nyc-open-data", "yellow-taxi", documents) + .get(); + +/* +result = + { + successes= + [ + { + result=created, + _source= + { + Agent=Smith, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=1, + status=200 + }, + { + result=created, + _source= + { + Gordon=Freeman, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=1, + status=200 + } + ], + errors=[] + } +*/ diff --git a/doc/3/controllers/document/m-update/snippets/m-update.test.yml b/doc/3/controllers/document/m-update/snippets/m-update.test.yml new file mode 100644 index 00000000..29ccba1f --- /dev/null +++ b/doc/3/controllers/document/m-update/snippets/m-update.test.yml @@ -0,0 +1,14 @@ +name: document#mUpdate +description: Updates multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id/_create + curl -XPOST -d '{"name":"John"}' -H "Content-Type: application/json" kuzzle:7512/nyc-open-data/yellow-taxi/some-id2/_create + after: +template: print-result-array +expected: + - "id=some-id, status=200" + - "id=some-id2, status=200" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index abd29e69..a11de943 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -76,157 +76,157 @@ public CompletableFuture> create( return this.create(index, collection, document, null); } - /** - * Updates a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @param document - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> update( - final String index, - final String collection, - final String id, - final ConcurrentHashMap document, - final UpdateOptions options) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - Integer retryOnConflict = null; - Boolean waitForRefresh = null; - Boolean source = null; - if (options != null) { - retryOnConflict = options.getRetryOnConflict(); - source = options.getSource(); - waitForRefresh = options.getWaitForRefresh(); - } - - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "update") - .put("body", document) - .put("_id", id) - .put("waitForRefresh", waitForRefresh) - .put("retryOnConflict", retryOnConflict) - .put("source", source); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } - - /** - * Updates a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> update( - final String index, - final String collection, - final String id, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - - return this.update(index, collection, id, document, null); - } - - /** - * Gets a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> get( - final String index, - final String collection, - final String id) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "get") - .put("_id", id); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } - - /** - * Creates or Replace a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @param document - * @param waitForRefresh - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> createOrReplace( - final String index, - final String collection, - final String id, - final ConcurrentHashMap document, - final Boolean waitForRefresh) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "createOrReplace") - .put("body", document) - .put("_id", id) - .put("waitForRefresh", waitForRefresh); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (ConcurrentHashMap) response.result); - } - - /** - * Creates or Replace a document in a given collection and index. - * - * @param index - * @param collection - * @param id - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture> createOrReplace( - final String index, - final String collection, - final String id, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - - return this.createOrReplace(index, collection, id, document, null); - } + /** + * Updates a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> update( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final UpdateOptions options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + Integer retryOnConflict = null; + Boolean waitForRefresh = null; + Boolean source = null; + if (options != null) { + retryOnConflict = options.getRetryOnConflict(); + source = options.getSource(); + waitForRefresh = options.getWaitForRefresh(); + } + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "update") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh) + .put("retryOnConflict", retryOnConflict) + .put("source", source); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Updates a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> update( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.update(index, collection, id, document, null); + } + + /** + * Gets a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> get( + final String index, + final String collection, + final String id) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "get") + .put("_id", id); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Creates or Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "createOrReplace") + .put("body", document) + .put("_id", id) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + + /** + * Creates or Replace a document in a given collection and index. + * + * @param index + * @param collection + * @param id + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> createOrReplace( + final String index, + final String collection, + final String id, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + return this.createOrReplace(index, collection, id, document, null); + } /** * Creates multiple documents in a given collection and index. @@ -545,6 +545,64 @@ public CompletableFuture exists( (response) -> (Boolean) response.result); } + /** + * Updates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mUpdate( + final String index, + final String collection, + final ArrayList> documents, + final UpdateOptions options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + Integer retryOnConflict = null; + Boolean waitForRefresh = null; + if (options != null) { + retryOnConflict = options.getRetryOnConflict(); + waitForRefresh = options.getWaitForRefresh(); + } + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mUpdate") + .put("body", new KuzzleMap().put("documents", documents)) + .put("retryOnConflict", retryOnConflict) + .put("waitForRefresh", waitForRefresh); + + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Updates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mUpdate( + final String index, + final String collection, + final ArrayList> documents) throws NotConnectedException, InternalException { + + return this.mUpdate(index, collection, documents, null); + } + /** * Creates or replaces multiple documents in a given collection and index. * diff --git a/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java b/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java index a66060af..7e11f4da 100644 --- a/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java +++ b/src/main/java/io/kuzzle/sdk/Options/CreateOptions.java @@ -5,6 +5,7 @@ public class CreateOptions { private String id; + private Integer retryOnConflict; private Boolean waitForRefresh; /** * Constructor @@ -19,6 +20,11 @@ public CreateOptions() {} public CreateOptions(CreateOptions options) { this.id = options.getId(); this.waitForRefresh = options.getWaitForRefresh(); + this.retryOnConflict = options.getRetryOnConflict(); + } + + public Integer getRetryOnConflict() { + return retryOnConflict; } public Boolean getWaitForRefresh() { @@ -37,11 +43,16 @@ public void setId(String id) { this.id = id; } + public void setRetryOnConflict(Integer retryOnConflict) { + this.retryOnConflict = retryOnConflict; + } + public ConcurrentHashMap toHashMap() { ConcurrentHashMap options = new ConcurrentHashMap<>(); options.put("_id", this.id); options.put("waitForRefresh", this.waitForRefresh); + options.put("retryOnConflict", this.retryOnConflict); return options; } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index ceb110e9..f3400b7d 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -26,124 +26,123 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); - @Test - public void getDocumentTest() throws NotConnectedException, InternalException { + @Test + public void createDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + CreateOptions options = new CreateOptions(); + options.setId("some-id"); + options.setWaitForRefresh(true); - kuzzleMock.getDocumentController().get(index, collection, "some-id"); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + kuzzleMock.getDocumentController().create(index, collection, document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - } + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } - @Test(expected = NotConnectedException.class) - public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + @Test + public void createDocumentTestB() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - kuzzleMock.getDocumentController().get(index, collection, "some-id"); - } + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); - @Test - public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException { + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + kuzzleMock.getDocumentController().create(index, collection, document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); + } - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + @Test(expected = NotConnectedException.class) + public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { - kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document, true); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - @Test - public void createOrReplaceDocumentTestB() throws NotConnectedException, InternalException { + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); + document.put("nickname", "El angel de la muerte que hace el JAVA"); - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + kuzzleMock.getDocumentController().create(index, collection, document); + } - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); + @Test + public void getDocumentTest() throws NotConnectedException, InternalException { - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getString("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - assertEquals(((ConcurrentHashMap)(((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); - } + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - @Test(expected = NotConnectedException.class) - public void createOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + } - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + @Test(expected = NotConnectedException.class) + public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - document.put("nickname", "El angel de la muerte que hace el JAVA"); + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); - } + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + } - @Test - public void createDocumentTestA() throws NotConnectedException, InternalException { + @Test + public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; - + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); document.put("nickname", "El angel de la muerte que hace el JAVA"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - CreateOptions options = new CreateOptions(); - options.setId("some-id"); - options.setWaitForRefresh(true); - - kuzzleMock.getDocumentController().create(index, collection, document, options); + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); @@ -152,33 +151,30 @@ public void createDocumentTestA() throws NotConnectedException, InternalExceptio } @Test - public void createDocumentTestB() throws NotConnectedException, InternalException { + public void createOrReplaceDocumentTestB() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; - + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); document.put("nickname", "El angel de la muerte que hace el JAVA"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().create(index, collection, document); + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getString("waitForRefresh"), null); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @Test(expected = NotConnectedException.class) - public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { - + public void createOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); @@ -190,80 +186,80 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException, document.put("name", "Yoann"); document.put("nickname", "El angel de la muerte que hace el JAVA"); - kuzzleMock.getDocumentController().create(index, collection, document); + kuzzleMock.getDocumentController().createOrReplace(index, collection, "some-id", document); } - @Test - public void udpateDocumentTestA() throws NotConnectedException, InternalException { + @Test + public void udpateDocumentTestA() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); - UpdateOptions options = new UpdateOptions(); - options.setWaitForRefresh(false); - options.setSource(true); - options.setRetryOnConflict(1); + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); - assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - } + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + } - @Test - public void udpateDocumentTestB() throws NotConnectedException, InternalException { + @Test + public void udpateDocumentTestB() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - ConcurrentHashMap document = new ConcurrentHashMap<>(); + ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + document.put("name", "Yoann"); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().update(index, collection, "some-id", document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + kuzzleMock.getDocumentController().update(index, collection, "some-id", document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), null); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), null); - assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); - } + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), null); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); + } - @Test(expected = NotConnectedException.class) - public void updateShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + @Test(expected = NotConnectedException.class) + public void updateShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - String id = "some-id"; + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + String id = "some-id"; - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("name", "Yoann"); + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("name", "Yoann"); - kuzzleMock.getDocumentController().update(index, collection, id, document); - } + kuzzleMock.getDocumentController().update(index, collection, id, document); + } @Test public void mCreateDocumentTestA() throws NotConnectedException, InternalException { @@ -298,8 +294,8 @@ public void mCreateDocumentTestA() throws NotConnectedException, InternalExcepti assertEquals((arg.getValue()).getString("action"), "mCreate"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test @@ -334,8 +330,8 @@ public void mCreateDocumentTestB() throws NotConnectedException, InternalExcepti assertEquals((arg.getValue()).getString("action"), "mCreate"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test(expected = NotConnectedException.class) @@ -615,8 +611,8 @@ public void mReplaceDocumentTestA() throws NotConnectedException, InternalExcept assertEquals((arg.getValue()).getString("action"), "mReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test @@ -651,8 +647,8 @@ public void mReplaceDocumentTestB() throws NotConnectedException, InternalExcept assertEquals((arg.getValue()).getString("action"), "mReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test(expected = NotConnectedException.class) @@ -713,7 +709,115 @@ public void existsDocumentShouldThrowWhenNotConnected() throws NotConnectedExcep kuzzleMock.getDocumentController().exists(index, collection, "some-id"); } - + + @Test + public void mUpdateDocumentTestA() throws NotConnectedException, InternalException { + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mUpdate(index, collection, documents); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mUpdate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getNumber("retryOnConflict"), null); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test + public void mUpdateDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + UpdateOptions options = new UpdateOptions(); + options.setRetryOnConflict(0); + options.setWaitForRefresh(false); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mUpdate(index, collection, documents, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mUpdate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getNumber("retryOnConflict"), 0); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mUpdateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + kuzzleMock.getDocumentController().mUpdate(index, collection, documents); + } + @Test public void mCreateOrReplaceDocumentTestA() throws NotConnectedException, InternalException { @@ -747,8 +851,8 @@ public void mCreateOrReplaceDocumentTestA() throws NotConnectedException, Intern assertEquals((arg.getValue()).getString("action"), "mCreateOrReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test @@ -783,8 +887,8 @@ public void mCreateOrReplaceDocumentTestB() throws NotConnectedException, Intern assertEquals((arg.getValue()).getString("action"), "mCreateOrReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); - assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @Test(expected = NotConnectedException.class) From 7701c57daafd64e58d2cde862efcdc063e541b6d Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 25 Mar 2020 14:16:47 +0100 Subject: [PATCH 096/134] doc wip [ci skip] --- doc/3/core-classes/SearchResults/index.md | 6 +++ .../SearchResults/introduction/index.md | 27 +++++++++++++ .../core-classes/SearchResults/next/index.md | 40 +++++++++++++++++++ .../SearchResults/next/snippets/next-1.java | 0 .../SearchResults/next/snippets/next-2.java | 0 5 files changed, 73 insertions(+) create mode 100644 doc/3/core-classes/SearchResults/next/snippets/next-1.java create mode 100644 doc/3/core-classes/SearchResults/next/snippets/next-2.java diff --git a/doc/3/core-classes/SearchResults/index.md b/doc/3/core-classes/SearchResults/index.md index e69de29b..924a90f8 100644 --- a/doc/3/core-classes/SearchResults/index.md +++ b/doc/3/core-classes/SearchResults/index.md @@ -0,0 +1,6 @@ +--- +code: true +type: branch +title: SearchResult +description: SearchResult documentation +--- \ No newline at end of file diff --git a/doc/3/core-classes/SearchResults/introduction/index.md b/doc/3/core-classes/SearchResults/introduction/index.md index e69de29b..57a018ea 100644 --- a/doc/3/core-classes/SearchResults/introduction/index.md +++ b/doc/3/core-classes/SearchResults/introduction/index.md @@ -0,0 +1,27 @@ +--- +code: true +type: page +title: constructor +description: SearchResult:constructor +order: 1 +--- + +# Constructor + +This object can only be instantiated internally by this SDK, and is an easy-to-use representation of a paginated result from a [search](/sdk/java/2/core-classes/collection/search) or a [scroll](/sdk/java/2/core-classes/collection/scroll) request. + +--- + +## Properties + +| Property name | Type | Description | get/set | +| -------------- | ---------- | --------------------------------------------------------- | ------- | +| `aggregations` | object | The result of an aggregation produced by a search request | get | +| `collection` | Collection | The collection associated to this document | get | +| `documents` | Document[] | An array of instantiated Document objects | get | +| `fetched` | number | The number of fetched documents so far | get/set | +| `options` | object | The arguments of the search/scroll request | get | +| `filters` | object | The filters of the search request | get | +| `total` | integer | The total number of results that can be fetched | get | + +--- \ No newline at end of file diff --git a/doc/3/core-classes/SearchResults/next/index.md b/doc/3/core-classes/SearchResults/next/index.md index e69de29b..914cf7e4 100644 --- a/doc/3/core-classes/SearchResults/next/index.md +++ b/doc/3/core-classes/SearchResults/next/index.md @@ -0,0 +1,40 @@ +--- +code: true +type: page +title: next +description: SearchResult:next +--- + +# next + +Fetches the next SearchResult, by triggering a new search/scroll request depending on the options and filters of the SearchResult. + +If the previous request was a search or a scroll action which provided a `scroll` argument, +`next` will use the `scrollId` retrieved from the current result to make a new scroll request. + +If the previous request was a search action which provided `size` argument and `sort` filtering, +`next` will use Elasticsearch's [`search_after`](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-request-body.html#request-body-search-search-after) mechanism, which can efficiently search through a large volume of documents, bypassing internal hard limits\[1\], +but at the cost of reflecting the latest changes of the index, as opposed to using scroll. + +If the previous request was a search action which provided `from` and `size` arguments, +`next` will add `size` to `from` and make a new search request. + +--- + +## How to process every document of a collection + +The safest way to process all documents in a collection is to fetch them as a batch in order to avoid memory exhaustion and possibly hitting some hard limits\[1\] on the database layer. + +:::warning +Make sure your first search request includes the `size` and `scroll` parameters +::: + +:::info +\[1\] Elasticsearch limits the number of documents inside a single page to [10,000 by default](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/index-modules.html#dynamic-index-settings). +::: + +## Usage + +<<< ./snippets/next-1.java + +<<< ./snippets/next-2.java \ No newline at end of file diff --git a/doc/3/core-classes/SearchResults/next/snippets/next-1.java b/doc/3/core-classes/SearchResults/next/snippets/next-1.java new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/core-classes/SearchResults/next/snippets/next-2.java b/doc/3/core-classes/SearchResults/next/snippets/next-2.java new file mode 100644 index 00000000..e69de29b From 0b12d7726a2e16bc8c6665f6a13ac9768b5a24b1 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 25 Mar 2020 14:35:11 +0100 Subject: [PATCH 097/134] Add document:validate (#74) This PR implements the validate method with its unit tests. --- doc/3/controllers/document/validate/index.md | 38 ++++++++++++++++++ .../document/validate/snippets/validate.java | 7 ++++ .../validate/snippets/validate.test.yml | 10 +++++ .../API/Controllers/DocumentController.java | 29 ++++++++++++++ .../DocumentTest/DocumentTest.java | 39 +++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 doc/3/controllers/document/validate/index.md create mode 100644 doc/3/controllers/document/validate/snippets/validate.java create mode 100644 doc/3/controllers/document/validate/snippets/validate.test.yml diff --git a/doc/3/controllers/document/validate/index.md b/doc/3/controllers/document/validate/index.md new file mode 100644 index 00000000..3ad5249d --- /dev/null +++ b/doc/3/controllers/document/validate/index.md @@ -0,0 +1,38 @@ +--- +code: true +type: page +title: validate +description: Validate a document +--- + +# validate + +Validates data against existing validation rules. + +Note that if no validation specifications are set for the ``/``, the document will always be valid. + +This request does **not** store or publish the document. + +
+ +```java +public CompletableFuture validate( + final String index, + final String collection, + final ConcurrentHashMap document) +throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +| ------------ | -------------------------------------------- | -------------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `document` |
ConcurrentHashMap
| Document to validate | + +## Returns + +Returns a boolean value set to true if the document is valid and false otherwise. + +## Usage + +<<< ./snippets/validate.java \ No newline at end of file diff --git a/doc/3/controllers/document/validate/snippets/validate.java b/doc/3/controllers/document/validate/snippets/validate.java new file mode 100644 index 00000000..aaad866e --- /dev/null +++ b/doc/3/controllers/document/validate/snippets/validate.java @@ -0,0 +1,7 @@ + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("key", "value"); + + Boolean result = kuzzle + .getDocumentController() + .validate("nyc-open-data", "yellow-taxi", document) + .get(); diff --git a/doc/3/controllers/document/validate/snippets/validate.test.yml b/doc/3/controllers/document/validate/snippets/validate.test.yml new file mode 100644 index 00000000..63717fd0 --- /dev/null +++ b/doc/3/controllers/document/validate/snippets/validate.test.yml @@ -0,0 +1,10 @@ +name: document#validate +description: Validates a document +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result +expected: true \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index a11de943..07a43590 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -653,6 +653,35 @@ public CompletableFuture>> mCreateOr return this.mCreateOrReplace(index, collection, documents, null); } + /** + * Validates data against existing validation rules. + * + * @param index + * @param collection + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture validate( + final String index, + final String collection, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "validate") + .put("body", new KuzzleMap(document)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (Boolean)((ConcurrentHashMap)response.result).get("valid")); + } + /** * Counts documents in a collection. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index f3400b7d..f1b79737 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -919,6 +919,45 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); } + @Test + public void validateDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + + document.put("Tirion", "Fordring"); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().validate(index, collection, document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "validate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("Tirion").toString(), "Fordring"); + + } + + @Test(expected = NotConnectedException.class) + public void validateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document = new ConcurrentHashMap<>(); + + document.put("Tirion", "Fordring"); + + kuzzleMock.getDocumentController().validate(index, collection, document); + } + @Test public void countDocumentTestA() throws NotConnectedException, InternalException { From e4c9722fb5c785ad20182064836a889ce7ba97f3 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 25 Mar 2020 16:10:04 +0100 Subject: [PATCH 098/134] Add Collection controller and collection:exists (#78) ## What does this PR do ? This PR implements the `collection:exists` method with its unit tests. --- doc/3/controllers/collection/exists/index.md | 39 ++++++++++++++ .../collection/exists/snippets/exists.java | 4 ++ .../exists/snippets/exists.test.yml | 10 ++++ doc/3/controllers/collection/index.md | 8 +++ .../API/Controllers/CollectionController.java | 41 +++++++++++++++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 8 +++ .../test/API/Controllers/CollectionTest.java | 52 +++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 doc/3/controllers/collection/exists/index.md create mode 100644 doc/3/controllers/collection/exists/snippets/exists.java create mode 100644 doc/3/controllers/collection/exists/snippets/exists.test.yml create mode 100644 doc/3/controllers/collection/index.md create mode 100644 src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java create mode 100644 src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java diff --git a/doc/3/controllers/collection/exists/index.md b/doc/3/controllers/collection/exists/index.md new file mode 100644 index 00000000..7e988d86 --- /dev/null +++ b/doc/3/controllers/collection/exists/index.md @@ -0,0 +1,39 @@ +--- +code: true +type: page +title: exists +description: Checks if a collection exists +--- + +# exists + +Checks if a collection exists. + +--- + +## Arguments + +```java +public CompletableFuture exists( + final String index, + final String collection) +throws NotConnectedException, InternalException + +``` + +--- + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | + +--- + +## Return + +Returns a boolean. + +## Usage + +<<< ./snippets/exists.java diff --git a/doc/3/controllers/collection/exists/snippets/exists.java b/doc/3/controllers/collection/exists/snippets/exists.java new file mode 100644 index 00000000..31359784 --- /dev/null +++ b/doc/3/controllers/collection/exists/snippets/exists.java @@ -0,0 +1,4 @@ +Boolean result = kuzzle + .getCollectionController() + .exists("nyc-open-data", "yellow-taxi") + .get(); diff --git a/doc/3/controllers/collection/exists/snippets/exists.test.yml b/doc/3/controllers/collection/exists/snippets/exists.test.yml new file mode 100644 index 00000000..f4f8e8db --- /dev/null +++ b/doc/3/controllers/collection/exists/snippets/exists.test.yml @@ -0,0 +1,10 @@ +name: collection#exists +description: Check if collection exists +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result +expected: "true" \ No newline at end of file diff --git a/doc/3/controllers/collection/index.md b/doc/3/controllers/collection/index.md new file mode 100644 index 00000000..bf3a499d --- /dev/null +++ b/doc/3/controllers/collection/index.md @@ -0,0 +1,8 @@ +--- +code: true +type: branch +title: Collection +description: Collection Controller +--- + +# Collection Controller \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java new file mode 100644 index 00000000..23dada9f --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -0,0 +1,41 @@ +package io.kuzzle.sdk.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; + +import java.util.concurrent.CompletableFuture; + +public class CollectionController extends BaseController { + + public CollectionController(final Kuzzle kuzzle) { + super(kuzzle); + } + + /** + * Tells if a collection exists in a given index. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture exists( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "exists"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (Boolean) response.result); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index cd4f6815..012745b8 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -1,6 +1,7 @@ package io.kuzzle.sdk; import io.kuzzle.sdk.API.Controllers.AuthController; +import io.kuzzle.sdk.API.Controllers.CollectionController; import io.kuzzle.sdk.API.Controllers.DocumentController; import io.kuzzle.sdk.API.Controllers.IndexController; import io.kuzzle.sdk.API.Controllers.RealtimeController; @@ -80,6 +81,13 @@ public AuthController getAuthController() { return new AuthController(this); } + /** + * @return The CollectionController + */ + public CollectionController getCollectionController() { + return new CollectionController(this); + } + /** * @return The DocumentController */ diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java new file mode 100644 index 00000000..0f82e7f0 --- /dev/null +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -0,0 +1,52 @@ +package io.kuzzle.test.API.Controllers; + +import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.ProtocolState; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.spy; + +public class CollectionTest { + + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + @Test + public void existsCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().exists(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "exists"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void existsCollectionShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().exists(index, collection); + } +} From 500be5f8b3bd2011aec2c8e3dd636a44bc30aa7d Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:05:04 +0200 Subject: [PATCH 099/134] Add collection:getMapping (#81) ## What does this PR do ? This PR implements the `collection:create` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data`, a collection `yellow-taxi`. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class getMappingCollection { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); ConcurrentHashMap result = kuzzle.getCollectionController().getMapping("nyc-open-data", "yellow-taxi").get(); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` --- .../collection/get-mapping/index.md | 33 +++++++++++++++++++ .../get-mapping/snippets/get-mapping.java | 25 ++++++++++++++ .../get-mapping/snippets/get-mapping.test.yml | 7 ++++ .../API/Controllers/CollectionController.java | 27 +++++++++++++++ .../test/API/Controllers/CollectionTest.java | 31 +++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 doc/3/controllers/collection/get-mapping/index.md create mode 100644 doc/3/controllers/collection/get-mapping/snippets/get-mapping.java create mode 100644 doc/3/controllers/collection/get-mapping/snippets/get-mapping.test.yml diff --git a/doc/3/controllers/collection/get-mapping/index.md b/doc/3/controllers/collection/get-mapping/index.md new file mode 100644 index 00000000..e38a7371 --- /dev/null +++ b/doc/3/controllers/collection/get-mapping/index.md @@ -0,0 +1,33 @@ +--- +code: true +type: page +title: getMapping +description: Return collection mapping +--- + +# getMapping + +Returns the collection mapping. + +
+ +```java +public CompletableFuture> getMapping( + final String index, + final String collection) throws NotConnectedException, InternalException +``` + +
+ +| Arguments | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | + +## Returns + +Returns a `ConcurrentHashMap` representing the collection mapping. + +## Usage + +<<< ./snippets/get-mapping.js \ No newline at end of file diff --git a/doc/3/controllers/collection/get-mapping/snippets/get-mapping.java b/doc/3/controllers/collection/get-mapping/snippets/get-mapping.java new file mode 100644 index 00000000..bef31262 --- /dev/null +++ b/doc/3/controllers/collection/get-mapping/snippets/get-mapping.java @@ -0,0 +1,25 @@ +ConcurrentHashMap result = kuzzle + .getCollectionController() + .getMapping("nyc-open-data", "yellow-taxi") + .get(); + +/* +{ + _meta={ + schema={}, + allowForm=false + }, + dynamic=true, + properties={ + key={ + type=text, + fields={ + keyword={ + ignore_above=256, + type=keyword + } + } + } + } + } +*/ \ No newline at end of file diff --git a/doc/3/controllers/collection/get-mapping/snippets/get-mapping.test.yml b/doc/3/controllers/collection/get-mapping/snippets/get-mapping.test.yml new file mode 100644 index 00000000..e8f34817 --- /dev/null +++ b/doc/3/controllers/collection/get-mapping/snippets/get-mapping.test.yml @@ -0,0 +1,7 @@ +name: collection#getMapping +description: Return collection mapping +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result +expected: "true" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index 23dada9f..cdf96dbe 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -6,6 +6,7 @@ import io.kuzzle.sdk.Kuzzle; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; public class CollectionController extends BaseController { @@ -38,4 +39,30 @@ public CompletableFuture exists( .thenApplyAsync( (response) -> (Boolean) response.result); } + + /** + * Get collection mapping + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> getMapping( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "getMapping"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 0f82e7f0..99523b49 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -49,4 +49,35 @@ public void existsCollectionShouldThrowWhenNotConnected() throws NotConnectedExc kuzzleMock.getCollectionController().exists(index, collection); } + + @Test + public void getMappingCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().getMapping(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "getMapping"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void getMappingShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().getMapping(index, collection); + } } From e403d4d13144a3f2bdaf3b85b5f4cc7175120030 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 1 Apr 2020 09:43:19 +0200 Subject: [PATCH 100/134] Add collection:create (#79) This PR implements the collection:create method with its unit tests. --- doc/3/controllers/collection/create/index.md | 64 +++++++++++++++++ .../collection/create/snippets/create.java | 10 +++ .../create/snippets/create.test.yml | 9 +++ .../m-update/snippets/m-update.test.yml | 4 +- .../API/Controllers/CollectionController.java | 45 ++++++++++++ .../test/API/Controllers/CollectionTest.java | 68 +++++++++++++++++++ 6 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 doc/3/controllers/collection/create/index.md create mode 100644 doc/3/controllers/collection/create/snippets/create.java create mode 100644 doc/3/controllers/collection/create/snippets/create.test.yml diff --git a/doc/3/controllers/collection/create/index.md b/doc/3/controllers/collection/create/index.md new file mode 100644 index 00000000..856848fb --- /dev/null +++ b/doc/3/controllers/collection/create/index.md @@ -0,0 +1,64 @@ +--- +code: true +type: page +title: create +description: Creates a new collection +--- + +# create + +Creates a new [collection](/core/2/guides/essentials/store-access-data) in Kuzzle via the persistence engine, in the provided index. + +You can also provide an optional data mapping that allows you to exploit the full capabilities of our +persistent data storage layer, [ElasticSearch](https://www.elastic.co/elastic-stack) (check here the [mapping capabilities of ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping.html)). + +This method will only update the mapping if the collection already exists. + +
+ +--- + +## Arguments + +```java +public CompletableFuture create( + final String index, + final String collection, + final ConcurrentHashMap mapping) +throws NotConnectedException, InternalException + +public CompletableFuture create( + final String index, + final String collection) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `mapping` |
ConcurrentHashMap
| Describes the data mapping to associate to the new collection, using Elasticsearch [mapping format](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping.html) | + +--- + +### mapping + +A `ConcurrentHashMap` representing the data mapping of the collection. + +The mapping must have a root field `properties` that contain the mapping definition: + +```java + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap field = new ConcurrentHashMap<>(); + + field.put("type", "keyword"); + properties.put("field", field); + mapping.put("properties", properties); +``` + +More information about database mappings [here](/core/2/guides/essentials/database-mappings). + +## Usage + +<<< ./snippets/create.java diff --git a/doc/3/controllers/collection/create/snippets/create.java b/doc/3/controllers/collection/create/snippets/create.java new file mode 100644 index 00000000..2e59f164 --- /dev/null +++ b/doc/3/controllers/collection/create/snippets/create.java @@ -0,0 +1,10 @@ + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + license.put("type", "keyword"); + properties.put("license", license); + mapping.put("properties", properties); + + kuzzle.getCollectionController().create("nyc-open-data", "yellow-taxi", mapping) + .get(); \ No newline at end of file diff --git a/doc/3/controllers/collection/create/snippets/create.test.yml b/doc/3/controllers/collection/create/snippets/create.test.yml new file mode 100644 index 00000000..ad25ec5b --- /dev/null +++ b/doc/3/controllers/collection/create/snippets/create.test.yml @@ -0,0 +1,9 @@ +name: collection#create +description: Creates a new collection +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/document/m-update/snippets/m-update.test.yml b/doc/3/controllers/document/m-update/snippets/m-update.test.yml index 29ccba1f..b14ef60a 100644 --- a/doc/3/controllers/document/m-update/snippets/m-update.test.yml +++ b/doc/3/controllers/document/m-update/snippets/m-update.test.yml @@ -10,5 +10,5 @@ hooks: after: template: print-result-array expected: - - "id=some-id, status=200" - - "id=some-id2, status=200" \ No newline at end of file + - "id=some-id, _version=2, status=200" + - "id=some-id2, _version=2, status=200" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index cdf96dbe..78c410a3 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -40,6 +40,51 @@ public CompletableFuture exists( (response) -> (Boolean) response.result); } + /** + * Creates a collection in a given index. + * + * @param index + * @param collection + * @param mappings + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture create( + final String index, + final String collection, + final ConcurrentHashMap mappings) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "create") + .put("body", mappings != null ? new KuzzleMap(mappings) : null); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> null); + } + + /** + * Creates a collection in a given index. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture create( + final String index, + final String collection) throws NotConnectedException, InternalException { + + return this.create(index, collection, null); + } + /** * Get collection mapping * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 99523b49..dca7b1c6 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -12,6 +12,8 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import java.util.concurrent.ConcurrentHashMap; + import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; @@ -50,6 +52,72 @@ public void existsCollectionShouldThrowWhenNotConnected() throws NotConnectedExc kuzzleMock.getCollectionController().exists(index, collection); } + @Test + public void createCollectionTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().create(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "create"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + } + + @Test + public void createCollectionTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + license.put("type", "keyword"); + properties.put("license", license); + mapping.put("properties", properties); + + kuzzleMock.getCollectionController().create(index, collection, mapping); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "create"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(( + (ConcurrentHashMap) ( + (ConcurrentHashMap) ( + ((ConcurrentHashMap) + ((arg.getValue()) + .get("body"))) + .get("properties"))) + .get("license")) + .get("type").toString(), "keyword"); + } + + @Test(expected = NotConnectedException.class) + public void createCollectionThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().create(index, collection); + } + @Test public void getMappingCollectionTest() throws NotConnectedException, InternalException { From cbec142e10ef3fb545e237b861b45bd5291d95fb Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 2 Apr 2020 13:13:49 +0200 Subject: [PATCH 101/134] Add collection:truncate (#80) ## What does this PR do ? This PR implements the `collection:truncate` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data`, a `yellow-taxi` collection with several documents in it. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class truncateCollection { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); kuzzle.getCollectionController().truncate("nyc-open-data", "yellow-taxi").get(); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` --- .../controllers/collection/truncate/index.md | 29 ++++++++++++++++++ .../truncate/snippets/truncate.java | 1 + .../truncate/snippets/truncate.test.yml | 7 +++++ .../API/Controllers/CollectionController.java | 26 ++++++++++++++++ .../test/API/Controllers/CollectionTest.java | 30 +++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 doc/3/controllers/collection/truncate/index.md create mode 100644 doc/3/controllers/collection/truncate/snippets/truncate.java create mode 100644 doc/3/controllers/collection/truncate/snippets/truncate.test.yml diff --git a/doc/3/controllers/collection/truncate/index.md b/doc/3/controllers/collection/truncate/index.md new file mode 100644 index 00000000..a8819665 --- /dev/null +++ b/doc/3/controllers/collection/truncate/index.md @@ -0,0 +1,29 @@ +--- +code: true +type: page +title: truncate +description: Remove all documents from a collection +--- + +# truncate + +Removes all documents from a collection, while keeping the associated mappings. + +
+ +```java +public CompletableFuture truncate( + final String index, + final String collection) throws NotConnectedException, InternalException +``` + +
+ +| Arguments | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | + +## Usage + +<<< ./snippets/truncate.js diff --git a/doc/3/controllers/collection/truncate/snippets/truncate.java b/doc/3/controllers/collection/truncate/snippets/truncate.java new file mode 100644 index 00000000..4a458b15 --- /dev/null +++ b/doc/3/controllers/collection/truncate/snippets/truncate.java @@ -0,0 +1 @@ + kuzzle.getCollectionController().truncate("nyc-open-data", "yellow-taxi").get(); \ No newline at end of file diff --git a/doc/3/controllers/collection/truncate/snippets/truncate.test.yml b/doc/3/controllers/collection/truncate/snippets/truncate.test.yml new file mode 100644 index 00000000..931b0041 --- /dev/null +++ b/doc/3/controllers/collection/truncate/snippets/truncate.test.yml @@ -0,0 +1,7 @@ +name: collection#truncate +description: Remove all documents from collection +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index 78c410a3..c0c84472 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -40,6 +40,32 @@ public CompletableFuture exists( (response) -> (Boolean) response.result); } + /** + * Removes all documents from collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture truncate( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "truncate"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (null)); + } + /** * Creates a collection in a given index. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index dca7b1c6..f02222c8 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -52,6 +52,36 @@ public void existsCollectionShouldThrowWhenNotConnected() throws NotConnectedExc kuzzleMock.getCollectionController().exists(index, collection); } + @Test + public void truncateCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().truncate(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "truncate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void truncateCollectionShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().truncate(index, collection); + } + @Test public void createCollectionTestA() throws NotConnectedException, InternalException { From b411fdb6c60cc974b42b1bacff3ec0b189f6571a Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 3 Apr 2020 15:06:48 +0200 Subject: [PATCH 102/134] Add document:deleteByQuery (#75) ## What does this PR do ? This PR implements the `deleteByQuery` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data` and a `yellow-taxi` collection in the admin console. Create 5 documents with 3 containing field `{"key":"value"}`. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class deleteByQueryDocument { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); ConcurrentHashMap match = new ConcurrentHashMap<>(); match.put("key", "value"); searchQuery.put("match", match); ArrayList result = kuzzle.getDocumentController().deleteByQuery("nyc-open-data", "yellow-taxi", searchQuery).get(); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` You should have an ArrayList as result containing the deleted documents ids. --- .../templates/print-result-arraylist.tpl.java | 30 ++++ .../document/delete-by-query/index.md | 46 ++++++ .../snippets/delete-by-query.java | 10 ++ .../snippets/delete-by-query.test.yml | 22 +++ .../API/Controllers/DocumentController.java | 51 ++++++ .../DocumentTest/DocumentTest.java | 150 ++++++++++++++---- 6 files changed, 277 insertions(+), 32 deletions(-) create mode 100644 .ci/doc/templates/print-result-arraylist.tpl.java create mode 100644 doc/3/controllers/document/delete-by-query/index.md create mode 100644 doc/3/controllers/document/delete-by-query/snippets/delete-by-query.java create mode 100644 doc/3/controllers/document/delete-by-query/snippets/delete-by-query.test.yml diff --git a/.ci/doc/templates/print-result-arraylist.tpl.java b/.ci/doc/templates/print-result-arraylist.tpl.java new file mode 100644 index 00000000..ca5a96dc --- /dev/null +++ b/.ci/doc/templates/print-result-arraylist.tpl.java @@ -0,0 +1,30 @@ +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Protocol.WebSocket; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.SubscribeOptions; +import io.kuzzle.sdk.CoreClasses.Responses.Response; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.ArrayList; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] argv) { + try { + kuzzle = new Kuzzle(new WebSocket("kuzzle")); + kuzzle.connect(); + [snippet-code] + for (Object o : result) { + System.out.println(o); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (kuzzle != null) { + kuzzle.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/doc/3/controllers/document/delete-by-query/index.md b/doc/3/controllers/document/delete-by-query/index.md new file mode 100644 index 00000000..c59a5abc --- /dev/null +++ b/doc/3/controllers/document/delete-by-query/index.md @@ -0,0 +1,46 @@ +--- +code: true +type: page +title: deleteByQuery +description: Delete documents matching query +--- + +# deleteByQuery + +Deletes documents matching the provided search query. + +Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax. + +An empty or null query will match all documents in the collection. + +
+ +```java + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException + + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final Boolean waitForRefresh) throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +| ------------------ | -------------------------------------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `searchQuery` |
ConcurrentHashMap
| Query to match | +| `waitForRefresh` |
Boolean
(optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| + +--- + +## Returns + +Returns an `ArrayList` containing the deleted document ids. + +## Usage + +<<< ./snippets/delete-by-query.js \ No newline at end of file diff --git a/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.java b/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.java new file mode 100644 index 00000000..46b10a9a --- /dev/null +++ b/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.java @@ -0,0 +1,10 @@ + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("capacity", 4); + query.put("match", match); + searchQuery.put("query", query); + ArrayList result = kuzzle + .getDocumentController() + .deleteByQuery("nyc-open-data", "yellow-taxi", searchQuery) + .get(); diff --git a/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.test.yml b/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.test.yml new file mode 100644 index 00000000..5d3fd03d --- /dev/null +++ b/doc/3/controllers/document/delete-by-query/snippets/delete-by-query.test.yml @@ -0,0 +1,22 @@ +name: document#deleteByQuery +description: Delete documents matching query +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create + done + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + curl -XPOST kuzzle:7512/nyc-open-data/_refresh + after: +template: print-result-arraylist +expected: + - "document_1" + - "document_2" + - "document_3" + - "document_4" + - "document_5" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 07a43590..9e404ad6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -653,6 +653,57 @@ public CompletableFuture>> mCreateOr return this.mCreateOrReplace(index, collection, documents, null); } + /** + * Deletes documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "deleteByQuery") + .put("body", new KuzzleMap(searchQuery)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ArrayList)((ConcurrentHashMap) response.result).get("ids")); + } + + /** + * Deletes documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + return this.deleteByQuery(index, collection, searchQuery, null); + } + /** * Validates data against existing validation rules. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index f1b79737..c1bf6b00 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -26,6 +26,37 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + @Test + public void getDocumentTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + } + + @Test(expected = NotConnectedException.class) + public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().get(index, collection, "some-id"); + } + + @Test public void createDocumentTestA() throws NotConnectedException, InternalException { @@ -82,7 +113,6 @@ public void createDocumentTestB() throws NotConnectedException, InternalExceptio @Test(expected = NotConnectedException.class) public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); @@ -97,36 +127,6 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException, kuzzleMock.getDocumentController().create(index, collection, document); } - @Test - public void getDocumentTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().get(index, collection, "some-id"); - Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); - - assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); - assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get"); - assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - } - - @Test(expected = NotConnectedException.class) - public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - kuzzleMock.getDocumentController().get(index, collection, "some-id"); - } - @Test public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException { @@ -258,7 +258,24 @@ public void updateShouldThrowWhenNotConnected() throws NotConnectedException, In ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); - kuzzleMock.getDocumentController().update(index, collection, id, document); + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); } @Test @@ -919,6 +936,75 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); } + @Test + public void deleteByQueryDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + } + + @Test + public void deleteByQueryDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + } + + @Test(expected = NotConnectedException.class) + public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); + } + @Test public void validateDocumentTest() throws NotConnectedException, InternalException { From a9aaa86891eaaab841927bd19baf48d8e3239f1b Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 8 Apr 2020 09:40:49 +0200 Subject: [PATCH 103/134] Add document:updateByQuery (#76) This PR implements the updateByQuery method with its unit tests. --- .../document/update-by-query/index.md | 76 ++++++++++ .../snippets/update-by-query.java | 30 ++++ .../snippets/update-by-query.test.yml | 19 +++ .../API/Controllers/DocumentController.java | 132 +++++++++++++---- .../DocumentTest/DocumentTest.java | 137 ++++++++++++++---- 5 files changed, 336 insertions(+), 58 deletions(-) create mode 100644 doc/3/controllers/document/update-by-query/index.md create mode 100644 doc/3/controllers/document/update-by-query/snippets/update-by-query.java create mode 100644 doc/3/controllers/document/update-by-query/snippets/update-by-query.test.yml diff --git a/doc/3/controllers/document/update-by-query/index.md b/doc/3/controllers/document/update-by-query/index.md new file mode 100644 index 00000000..09f0d8b0 --- /dev/null +++ b/doc/3/controllers/document/update-by-query/index.md @@ -0,0 +1,76 @@ +--- +code: true +type: page +title: updateByQuery +description: Updates documents matching query +--- + +# updateByQuery + +Updates documents matching the provided search query. + +Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax. + +An empty or null query will match all documents in the collection. + +
+ +```java + public CompletableFuture>> updateByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final ConcurrentHashMap changes) throws NotConnectedException, InternalException + + public CompletableFuture>> updateByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final ConcurrentHashMap changes, + final UpdateOptions options) throws NotConnectedException, InternalException +``` + +| Argument | Type | Description | +| ------------------ | -------------------------------------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `searchQuery` |
ConcurrentHashMap
| Query to match | +| `changes` |
ConcurrentHashMap
| Partial changes to apply to the documents | +| `options` |
UpdateOptions

(`null`) | Optional parameters | + +--- + +### options + +A [UpdateOptions](/sdk/java/3/core-classes/update-options) object. + +The following options can be set: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing| +| `source` |
Boolean
| If true, returns the updated document inside the response | + +## Returns + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each updated document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Updated document (if `source` option set to true) | +| `_id` |
String
| ID of the udated document | +| `_version` |
Integer
| Version of the document in the persistent data storage | +| `status` |
Integer
| HTTP status code | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/update-by-query.js \ No newline at end of file diff --git a/doc/3/controllers/document/update-by-query/snippets/update-by-query.java b/doc/3/controllers/document/update-by-query/snippets/update-by-query.java new file mode 100644 index 00000000..e8939278 --- /dev/null +++ b/doc/3/controllers/document/update-by-query/snippets/update-by-query.java @@ -0,0 +1,30 @@ + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("capacity", 4); + searchQuery.put("match", match); + + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("capacity", 42); + + ConcurrentHashMap> result = kuzzle + .getDocumentController() + .updateByQuery("nyc-open-data", "yellow-taxi", searchQuery, changes) + .get(); + + /* + { + successes=[ + { + _id=, + _source= // if source set to true + status=200 + }, + { + _id=, + _source= // if source set to true + status=200 + } + ], + errors=[] + } + */ \ No newline at end of file diff --git a/doc/3/controllers/document/update-by-query/snippets/update-by-query.test.yml b/doc/3/controllers/document/update-by-query/snippets/update-by-query.test.yml new file mode 100644 index 00000000..5473fced --- /dev/null +++ b/doc/3/controllers/document/update-by-query/snippets/update-by-query.test.yml @@ -0,0 +1,19 @@ +name: document#updateByQuery +description: Update documents matching query +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + for i in 1 2 ; do + curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create + done + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + curl -XPOST kuzzle:7512/nyc-open-data/_refresh + after: +template: print-result-array +expected: + - "id=document_1, _version=2, status=200" + - "id=document_2, _version=2, status=200" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 9e404ad6..8720c6d6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -8,6 +8,7 @@ import io.kuzzle.sdk.Options.UpdateOptions; import io.kuzzle.sdk.Options.CreateOptions; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -683,7 +684,7 @@ public CompletableFuture> deleteByQuery( return kuzzle .query(query) .thenApplyAsync( - (response) -> (ArrayList)((ConcurrentHashMap) response.result).get("ids")); + (response) -> (ArrayList) ((ConcurrentHashMap) response.result).get("ids")); } /** @@ -704,41 +705,41 @@ public CompletableFuture> deleteByQuery( return this.deleteByQuery(index, collection, searchQuery, null); } - /** - * Validates data against existing validation rules. - * - * @param index - * @param collection - * @param document - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture validate( - final String index, - final String collection, - final ConcurrentHashMap document) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - query - .put("index", index) - .put("collection", collection) - .put("controller", "document") - .put("action", "validate") - .put("body", new KuzzleMap(document)); - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> (Boolean)((ConcurrentHashMap)response.result).get("valid")); - } + /** + * Validates data against existing validation rules. + * + * @param index + * @param collection + * @param document + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture validate( + final String index, + final String collection, + final ConcurrentHashMap document) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "validate") + .put("body", new KuzzleMap(document)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (Boolean) ((ConcurrentHashMap) response.result).get("valid")); + } /** * Counts documents in a collection. * * @param index * @param collection - * @paran searchQuery + * @param searchQuery * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -759,7 +760,7 @@ public CompletableFuture count( return kuzzle .query(query) .thenApplyAsync( - (response) -> ((LazilyParsedNumber) ((ConcurrentHashMap)response.result).get("count")).intValue()); + (response) -> ((LazilyParsedNumber) ((ConcurrentHashMap) response.result).get("count")).intValue()); } /** @@ -779,4 +780,73 @@ public CompletableFuture count( return this.count(index, collection, searchQuery); } + + /** + * Updates documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @param changes + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> updateByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final ConcurrentHashMap changes, + final UpdateOptions options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + Integer retryOnConflict = null; + Boolean waitForRefresh = null; + Boolean source = null; + + if (options != null) { + retryOnConflict = options.getRetryOnConflict(); + source = options.getSource(); + waitForRefresh = options.getWaitForRefresh(); + } + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "updateByQuery") + .put("body", new KuzzleMap() + .put("query", searchQuery) + .put("changes", changes)) + .put("source", source) + .put("retryOnConflict", retryOnConflict) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Updates documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @param changes + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> updateByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final ConcurrentHashMap changes) throws NotConnectedException, InternalException { + + return this.updateByQuery(index, collection, searchQuery, changes, null); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index c1bf6b00..e5434272 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -1005,44 +1005,44 @@ public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnect kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); } - @Test - public void validateDocumentTest() throws NotConnectedException, InternalException { + @Test + public void validateDocumentTest() throws NotConnectedException, InternalException { - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - ConcurrentHashMap document = new ConcurrentHashMap<>(); + ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("Tirion", "Fordring"); + document.put("Tirion", "Fordring"); - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().validate(index, collection, document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + kuzzleMock.getDocumentController().validate(index, collection, document); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "validate"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("Tirion").toString(), "Fordring"); + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "validate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("Tirion").toString(), "Fordring"); - } + } - @Test(expected = NotConnectedException.class) - public void validateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + @Test(expected = NotConnectedException.class) + public void validateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; - ConcurrentHashMap document = new ConcurrentHashMap<>(); + ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("Tirion", "Fordring"); + document.put("Tirion", "Fordring"); - kuzzleMock.getDocumentController().validate(index, collection, document); - } + kuzzleMock.getDocumentController().validate(index, collection, document); + } @Test public void countDocumentTestA() throws NotConnectedException, InternalException { @@ -1083,7 +1083,7 @@ public void countDocumentTestB() throws NotConnectedException, InternalException assertEquals((arg.getValue()).getString("action"), "count"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); - assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); } @@ -1098,4 +1098,87 @@ public void countDocumentShouldThrowWhenNotConnected() throws NotConnectedExcept kuzzleMock.getDocumentController().count(index, collection); } + + @Test + public void updateByQueryDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "updateByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + assertEquals((((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("changes")).get("Hello")), "Mister Anderson"); + + } + + @Test + public void updateByQueryDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "updateByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getBoolean("source"), true); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + assertEquals((((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("changes")).get("Hello")), "Mister Anderson"); + } + + @Test(expected = NotConnectedException.class) + public void updateByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes); + } } From f19a0fa651620e7fec90ee43894b9a8bdff148bd Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:23:27 +0200 Subject: [PATCH 104/134] Add collection:getSpecifications (#87) --- .../collection/get-specifications/index.md | 33 +++++++++++++++++++ .../snippets/get-specifications.java | 21 ++++++++++++ .../snippets/get-specifications.test.yml | 11 +++++++ .../API/Controllers/CollectionController.java | 27 +++++++++++++++ .../test/API/Controllers/CollectionTest.java | 31 +++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 doc/3/controllers/collection/get-specifications/index.md create mode 100644 doc/3/controllers/collection/get-specifications/snippets/get-specifications.java create mode 100644 doc/3/controllers/collection/get-specifications/snippets/get-specifications.test.yml diff --git a/doc/3/controllers/collection/get-specifications/index.md b/doc/3/controllers/collection/get-specifications/index.md new file mode 100644 index 00000000..3874bcef --- /dev/null +++ b/doc/3/controllers/collection/get-specifications/index.md @@ -0,0 +1,33 @@ +--- +code: true +type: page +title: getSpecifications +description: Returns the validation specifications +--- + +# getSpecifications + +Returns the validation specifications associated to the given index and collection. + +
+ +```java + public CompletableFuture> getSpecifications( + final String index, + final String collection) +``` + +
+ +| Arguments | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | + +## Returns + +Returns a `ConcurrentHashMap` representing the collection specifications. + +## Usage + +<<< ./snippets/get-specifications.java \ No newline at end of file diff --git a/doc/3/controllers/collection/get-specifications/snippets/get-specifications.java b/doc/3/controllers/collection/get-specifications/snippets/get-specifications.java new file mode 100644 index 00000000..96aa0edb --- /dev/null +++ b/doc/3/controllers/collection/get-specifications/snippets/get-specifications.java @@ -0,0 +1,21 @@ + ConcurrentHashMap result = kuzzle + .getCollectionController() + .getSpecifications("nyc-open-data", "yellow-taxi") + .get(); + +/* + { + collection="yellow-taxi", + index="nyc-open-data", + validation={ + fields={ + age={ + defaultValue=42, + mandatory=true, + type="integer" + } + }, + strict=true + } + } +*/ \ No newline at end of file diff --git a/doc/3/controllers/collection/get-specifications/snippets/get-specifications.test.yml b/doc/3/controllers/collection/get-specifications/snippets/get-specifications.test.yml new file mode 100644 index 00000000..5f7533bf --- /dev/null +++ b/doc/3/controllers/collection/get-specifications/snippets/get-specifications.test.yml @@ -0,0 +1,11 @@ +name: collection#getSpecifications +description: Returns the validation specifications +hooks: + before: | + curl -X DELETE kuzzle:7512/nyc-open-data + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -X PUT -H "Content-Type: application/json" -d '{ "strict": false, "fields": {"license": {"type": "string"} } }' kuzzle:7512/nyc-open-data/yellow-taxi/_specifications + after: +template: print-result +expected: 'fields' \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index c0c84472..224c9d4d 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -136,4 +136,31 @@ public CompletableFuture> getMapping( .thenApplyAsync( (response) -> (ConcurrentHashMap) response.result); } + + /** + * Gets the validation specifications associated to the given index and collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> getSpecifications( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "getSpecifications"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index f02222c8..30c3a876 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -178,4 +178,35 @@ public void getMappingShouldThrowWhenNotConnected() throws NotConnectedException kuzzleMock.getCollectionController().getMapping(index, collection); } + + @Test + public void getSpecificationsCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().getSpecifications(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "getSpecifications"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void getSpecificationsCollectionThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().getSpecifications(index, collection); + } } From 8377f92cec9a17813fb51e44f74f6529f68b22fd Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 11:30:36 +0200 Subject: [PATCH 105/134] snippets tests --- doc/3/controllers/document/search/snippets/search.java | 5 +++-- doc/3/core-classes/search-result/next/snippets/fromsize.java | 4 ++-- doc/3/core-classes/search-result/next/snippets/scroll.java | 3 ++- src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java | 5 +++++ src/main/java/io/kuzzle/sdk/Kuzzle.java | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/3/controllers/document/search/snippets/search.java b/doc/3/controllers/document/search/snippets/search.java index 0633c8c8..5e7c5162 100644 --- a/doc/3/controllers/document/search/snippets/search.java +++ b/doc/3/controllers/document/search/snippets/search.java @@ -25,6 +25,8 @@ .getDocumentController() .search("nyc-open-data", "yellow-taxi", searchQuery).get(); + System.out.println("Successfully retrieved " + results.total + " documents"); + /* { "aggregations"=undefined, @@ -48,5 +50,4 @@ "total"=5, "fetched"=5, "scroll_id"=undefined - */ - System.out.println("Successfully retrieved " + results.total + " documents"); \ No newline at end of file + */ \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.java b/doc/3/core-classes/search-result/next/snippets/fromsize.java index 1cca14c0..64f399e4 100644 --- a/doc/3/core-classes/search-result/next/snippets/fromsize.java +++ b/doc/3/core-classes/search-result/next/snippets/fromsize.java @@ -1,11 +1,11 @@ ArrayList> documents = new ArrayList<>(); - ConcurrentHashMap document = new ConcurrentHashMap<>(); ConcurrentHashMap body = new ConcurrentHashMap<>(); body.put("category", "suv"); - for (int i = 0; i < 100; i++) { + ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("_id", "suv_no" + i); + document.put("body", body); documents.add(document); } diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.java b/doc/3/core-classes/search-result/next/snippets/scroll.java index 361718de..b5af570a 100644 --- a/doc/3/core-classes/search-result/next/snippets/scroll.java +++ b/doc/3/core-classes/search-result/next/snippets/scroll.java @@ -1,11 +1,12 @@ ArrayList> documents = new ArrayList<>(); - ConcurrentHashMap document = new ConcurrentHashMap<>(); ConcurrentHashMap body = new ConcurrentHashMap<>(); body.put("category", "suv"); for (int i = 0; i < 100; i++) { + ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("_id", "suv_no" + i); + document.put("body", body); documents.add(document); } diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index 26fdad31..8a52f2f9 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -35,6 +35,8 @@ public SearchResult( ConcurrentHashMap _response = response.toMap(); + System.out.println(response.result); + System.out.println(_response); this.kuzzle = kuzzle; this.options = options; this.request = request; @@ -118,6 +120,8 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec return null; } + System.out.println(this.hits); + System.out.println(this.fetched); this.options.setFrom(this.fetched); nextRequest = this.request; } @@ -126,6 +130,7 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec return null; } + System.out.println(nextRequest); Response response = this.kuzzle.query(nextRequest).get(); return new SearchResult(this.kuzzle, nextRequest, this.options, response, this.fetched); diff --git a/src/main/java/io/kuzzle/sdk/Kuzzle.java b/src/main/java/io/kuzzle/sdk/Kuzzle.java index 012745b8..84f5a825 100644 --- a/src/main/java/io/kuzzle/sdk/Kuzzle.java +++ b/src/main/java/io/kuzzle/sdk/Kuzzle.java @@ -242,7 +242,7 @@ public CompletableFuture query( } final KuzzleMap queryMap = KuzzleMap.from(query); - if (queryMap.contains("waitForRefresh")) { + if (queryMap.containsKey("waitForRefresh")) { if (queryMap.optBoolean("waitForRefresh", false).booleanValue()) { queryMap.put("refresh", "wait_for"); } From 16ab5fe92f8d2e577e62d2621d839043e07daca9 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 11:35:15 +0200 Subject: [PATCH 106/134] [ci skip] conflict --- .../API/Controllers/DocumentController.java | 159 +++++++-- .../DocumentTest/DocumentTest.java | 312 ++++++++++++++---- 2 files changed, 381 insertions(+), 90 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 4577d8c2..bd055a77 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -657,6 +657,57 @@ public CompletableFuture>> mCreateOr return this.mCreateOrReplace(index, collection, documents, null); } + /** + * Deletes documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "deleteByQuery") + .put("body", new KuzzleMap(searchQuery)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ArrayList) ((ConcurrentHashMap) response.result).get("ids")); + } + + /** + * Deletes documents matching the provided search query. + * + * @param index + * @param collection + * @param searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> deleteByQuery( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + return this.deleteByQuery(index, collection, searchQuery, null); + } + /** * Validates data against existing validation rules. * @@ -691,6 +742,7 @@ public CompletableFuture validate( * * @param index * @param collection + * @param searchQuery * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException @@ -733,60 +785,129 @@ public CompletableFuture count( } /** - * Searches documents. + * Updates documents matching the provided search query. * * @param index * @param collection * @param searchQuery + * @param changes * @param options * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture search( + public CompletableFuture>> updateByQuery( final String index, final String collection, final ConcurrentHashMap searchQuery, - final SearchOptions options) throws NotConnectedException, InternalException { + final ConcurrentHashMap changes, + final UpdateOptions options) throws NotConnectedException, InternalException { final KuzzleMap query = new KuzzleMap(); + + Integer retryOnConflict = null; + Boolean waitForRefresh = null; + Boolean source = null; + + if (options != null) { + retryOnConflict = options.getRetryOnConflict(); + source = options.getSource(); + waitForRefresh = options.getWaitForRefresh(); + } + query .put("index", index) .put("collection", collection) .put("controller", "document") - .put("action", "search") - .put("body", new KuzzleMap(searchQuery)); - - if (options != null) { - query - .put("from", options.getFrom()) - .put("size", options.getSize()); - if (options.getScroll() != null) { - query.put("scroll", options.getScroll()); - } - } + .put("action", "updateByQuery") + .put("body", new KuzzleMap() + .put("query", searchQuery) + .put("changes", changes)) + .put("source", source) + .put("retryOnConflict", retryOnConflict) + .put("waitForRefresh", waitForRefresh); return kuzzle .query(query) .thenApplyAsync( - (response) -> new SearchResult(kuzzle, query, options, response)); + (response) -> (ConcurrentHashMap>) response.result); } /** - * Searches documents. + * Updates documents matching the provided search query. * * @param index * @param collection * @param searchQuery + * @param changes * @return a CompletableFuture * @throws NotConnectedException * @throws InternalException */ - public CompletableFuture search( + public CompletableFuture>> updateByQuery( final String index, final String collection, - final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + final ConcurrentHashMap searchQuery, + final ConcurrentHashMap changes) throws NotConnectedException, InternalException { - return this.search(index, collection, searchQuery, new SearchOptions()); + return this.updateByQuery(index, collection, searchQuery, changes, null); } + +// /** +// * Searches documents. +// * +// * @param index +// * @param collection +// * @param searchQuery +// * @param options +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture search( +// final String index, +// final String collection, +// final ConcurrentHashMap searchQuery, +// final SearchOptions options) throws NotConnectedException, InternalException { +// +// final KuzzleMap query = new KuzzleMap(); +// query +// .put("index", index) +// .put("collection", collection) +// .put("controller", "document") +// .put("action", "search") +// .put("body", new KuzzleMap(searchQuery)); +// +// if (options != null) { +// query +// .put("from", options.getFrom()) +// .put("size", options.getSize()); +// if (options.getScroll() != null) { +// query.put("scroll", options.getScroll()); +// } +// } +// +// return kuzzle +// .query(query) +// .thenApplyAsync( +// (response) -> new SearchResult(kuzzle, query, options, response)); +// } +// +// /** +// * Searches documents. +// * +// * @param index +// * @param collection +// * @param searchQuery +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture search( +// final String index, +// final String collection, +// final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { +// +// return this.search(index, collection, searchQuery, new SearchOptions()); +// } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index b03dc019..675a9f2e 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -35,7 +35,7 @@ public class DocumentTest { private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); @Test - public void getDocumentTest() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + public void getDocumentTest() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; @@ -64,6 +64,7 @@ public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedExceptio kuzzleMock.getDocumentController().get(index, collection, "some-id"); } + @Test public void createDocumentTestA() throws NotConnectedException, InternalException { @@ -77,12 +78,18 @@ public void createDocumentTestA() throws NotConnectedException, InternalExceptio ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().create(index, collection, document); + CreateOptions options = new CreateOptions(); + options.setId("some-id"); + options.setWaitForRefresh(true); + + kuzzleMock.getDocumentController().create(index, collection, document, options); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @@ -100,30 +107,24 @@ public void createDocumentTestB() throws NotConnectedException, InternalExceptio ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CreateOptions options = new CreateOptions(); - options.setId("some-id"); - options.setWaitForRefresh(true); - - kuzzleMock.getDocumentController().create(index, collection, document, options); + kuzzleMock.getDocumentController().create(index, collection, document); Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), null); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), null); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @Test(expected = NotConnectedException.class) public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; String collection = "yellow-taxi"; @@ -265,7 +266,24 @@ public void updateShouldThrowWhenNotConnected() throws NotConnectedException, In ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("name", "Yoann"); - kuzzleMock.getDocumentController().update(index, collection, id, document); + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options); + Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture()); + + assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document"); + assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update"); + assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); + assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); + assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); } @Test @@ -926,6 +944,75 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); } + @Test + public void deleteByQueryDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + } + + @Test + public void deleteByQueryDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + } + + @Test(expected = NotConnectedException.class) + public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); + } + @Test public void validateDocumentTest() throws NotConnectedException, InternalException { @@ -1021,7 +1108,7 @@ public void countDocumentShouldThrowWhenNotConnected() throws NotConnectedExcept } @Test - public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + public void updateByQueryDocumentTestA() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; @@ -1029,93 +1116,62 @@ public void searchDocumentTestA() throws NotConnectedException, InternalExceptio ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); ConcurrentHashMap match = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); + searchQuery.put("match", match); ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap) r.result).put("scrollId", ""); - ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getDocumentController().search(index, collection, searchQuery); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); + + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "search"); + assertEquals((arg.getValue()).getString("action"), "updateByQuery"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + assertEquals((((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("changes")).get("Hello")), "Mister Anderson"); } @Test - public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + public void updateByQueryDocumentTestB() throws NotConnectedException, InternalException { Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; - SearchOptions options = new SearchOptions(); - options.setSize(10); - options.setFrom(0); - options.setScroll("30s"); ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); ConcurrentHashMap match = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); + searchQuery.put("match", match); ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap) r.result).put("scrollId", ""); - ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); + + UpdateOptions options = new UpdateOptions(); + options.setWaitForRefresh(false); + options.setSource(true); + options.setRetryOnConflict(1); + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes, options); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "search"); + assertEquals((arg.getValue()).getString("action"), "updateByQuery"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getNumber("from"), 0); - assertEquals((arg.getValue()).getNumber("size"), 10); - assertEquals((arg.getValue()).getString("scroll"), "30s"); - + assertEquals((arg.getValue()).getNumber("retryOnConflict"), 1); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getBoolean("source"), true); assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - + assertEquals((((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("changes")).get("Hello")), "Mister Anderson"); } @Test(expected = NotConnectedException.class) - public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + public void updateByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); @@ -1128,6 +1184,120 @@ public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedExcep match.put("Hello", "Clarisse"); searchQuery.put("match", match); - kuzzleMock.getDocumentController().search(index, collection, searchQuery); + ConcurrentHashMap changes = new ConcurrentHashMap<>(); + changes.put("Hello", "Mister Anderson"); + + kuzzleMock.getDocumentController().updateByQuery(index, collection, searchQuery, changes); } + +// @Test +// public void searchDocumentTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// ConcurrentHashMap query = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// query.put("match", match); +// searchQuery.put("query", query); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap) r.result).put("scrollId", ""); +// ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test +// public void searchDocumentTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// SearchOptions options = new SearchOptions(); +// options.setSize(10); +// options.setFrom(0); +// options.setScroll("30s"); +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// ConcurrentHashMap query = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// query.put("match", match); +// searchQuery.put("query", query); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap) r.result).put("scrollId", ""); +// ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getDocumentController().search(index, collection, searchQuery, options); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "document"); +// assertEquals((arg.getValue()).getString("action"), "search"); +// assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); +// assertEquals((arg.getValue()).getNumber("from"), 0); +// assertEquals((arg.getValue()).getNumber("size"), 10); +// assertEquals((arg.getValue()).getString("scroll"), "30s"); +// +// assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test(expected = NotConnectedException.class) +// public void searchDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// String index = "nyc-open-data"; +// String collection = "yellow-taxi"; +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// kuzzleMock.getDocumentController().search(index, collection, searchQuery); +// } } From 27563c1f8d61169fa371f310e32e1ac7e19b372c Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 11:41:15 +0200 Subject: [PATCH 107/134] tests conflict --- .../DocumentTest/DocumentTest.java | 104 ------------------ 1 file changed, 104 deletions(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 9b87592a..7748d156 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -946,8 +946,6 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn @Test public void deleteByQueryDocumentTestA() throws NotConnectedException, InternalException { -<<<<<<< HEAD -======= Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; @@ -1017,112 +1015,11 @@ public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnect @Test public void validateDocumentTest() throws NotConnectedException, InternalException { ->>>>>>> 3-dev Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); String index = "nyc-open-data"; String collection = "yellow-taxi"; -<<<<<<< HEAD - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); - assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - } - - @Test - public void deleteByQueryDocumentTestB() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, false); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); - assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - } - - @Test(expected = NotConnectedException.class) - public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - searchQuery.put("match", match); - - kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery); - } - - @Test - public void validateDocumentTest() throws NotConnectedException, InternalException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - - document.put("Tirion", "Fordring"); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - - kuzzleMock.getDocumentController().validate(index, collection, document); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "document"); - assertEquals((arg.getValue()).getString("action"), "validate"); - assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("Tirion").toString(), "Fordring"); - - } - - @Test(expected = NotConnectedException.class) - public void validateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - String index = "nyc-open-data"; - String collection = "yellow-taxi"; - - ConcurrentHashMap document = new ConcurrentHashMap<>(); - - document.put("Tirion", "Fordring"); - -======= ConcurrentHashMap document = new ConcurrentHashMap<>(); document.put("Tirion", "Fordring"); @@ -1152,7 +1049,6 @@ public void validateDocumentShouldThrowWhenNotConnected() throws NotConnectedExc document.put("Tirion", "Fordring"); ->>>>>>> 3-dev kuzzleMock.getDocumentController().validate(index, collection, document); } From a292e3061eef694925622b8208e1fbd068cf49e7 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 11:52:42 +0200 Subject: [PATCH 108/134] fix tests --- .../DocumentTest/DocumentTest.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 7748d156..33b1ff61 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -89,7 +89,7 @@ public void createDocumentTestA() throws NotConnectedException, InternalExceptio assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "create"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((KuzzleMap) arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @@ -153,7 +153,7 @@ public void createOrReplaceDocumentTestA() throws NotConnectedException, Interna assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "createOrReplace"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((KuzzleMap) arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @@ -208,7 +208,7 @@ public void udpateDocumentTestA() throws NotConnectedException, InternalExceptio document.put("name", "Yoann"); UpdateOptions options = new UpdateOptions(); - options.setWaitForRefresh(false); + options.setWaitForRefresh(true); options.setSource(true); options.setRetryOnConflict(1); @@ -222,7 +222,7 @@ public void udpateDocumentTestA() throws NotConnectedException, InternalExceptio assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((KuzzleMap) arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); } @@ -348,13 +348,13 @@ public void mCreateDocumentTestB() throws NotConnectedException, InternalExcepti ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().mCreate(index, collection, documents, false); + kuzzleMock.getDocumentController().mCreate(index, collection, documents, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "mCreate"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @@ -422,13 +422,13 @@ public void mDeleteDocumentTestB() throws NotConnectedException, InternalExcepti ids.add("some-id2"); ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().mDelete(index, collection, ids, false); + kuzzleMock.getDocumentController().mDelete(index, collection, ids, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "mDelete"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(0), "some-id1"); assertEquals(((ArrayList) (((KuzzleMap) (arg.getValue()).get("body"))).get("ids")).get(1), "some-id2"); } @@ -469,7 +469,7 @@ public void replaceDocumentTestA() throws NotConnectedException, InternalExcepti assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "replace"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((KuzzleMap) arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann"); assertEquals(((ConcurrentHashMap) (((KuzzleMap) arg.getValue()).get("body"))).get("nickname").toString(), "El angel de la muerte que hace el JAVA"); } @@ -531,7 +531,7 @@ public void deleteDocumentTestA() throws NotConnectedException, InternalExceptio assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "delete"); assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data"); assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id"); - assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), true); + assertEquals(((KuzzleMap) arg.getValue()).getString("refresh"), "wait_for"); } @Test @@ -665,13 +665,13 @@ public void mReplaceDocumentTestB() throws NotConnectedException, InternalExcept ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().mReplace(index, collection, documents, false); + kuzzleMock.getDocumentController().mReplace(index, collection, documents, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "mReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @@ -798,7 +798,7 @@ public void mUpdateDocumentTestB() throws NotConnectedException, InternalExcepti UpdateOptions options = new UpdateOptions(); options.setRetryOnConflict(0); - options.setWaitForRefresh(false); + options.setWaitForRefresh(true); ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); @@ -809,7 +809,7 @@ public void mUpdateDocumentTestB() throws NotConnectedException, InternalExcepti assertEquals((arg.getValue()).getString("action"), "mUpdate"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getNumber("retryOnConflict"), 0); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @@ -905,13 +905,13 @@ public void mCreateOrReplaceDocumentTestB() throws NotConnectedException, Intern ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents, false); + kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "mCreateOrReplace"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); assertEquals(((ArrayList>) (((KuzzleMap) (arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); } @@ -986,13 +986,13 @@ public void deleteByQueryDocumentTestB() throws NotConnectedException, InternalE ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, false); + kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, true); Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); assertEquals((arg.getValue()).getString("controller"), "document"); assertEquals((arg.getValue()).getString("action"), "deleteByQuery"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); } @@ -1151,7 +1151,7 @@ public void updateByQueryDocumentTestB() throws NotConnectedException, InternalE ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); UpdateOptions options = new UpdateOptions(); - options.setWaitForRefresh(false); + options.setWaitForRefresh(true); options.setSource(true); options.setRetryOnConflict(1); ConcurrentHashMap changes = new ConcurrentHashMap<>(); @@ -1164,7 +1164,7 @@ public void updateByQueryDocumentTestB() throws NotConnectedException, InternalE assertEquals((arg.getValue()).getString("action"), "updateByQuery"); assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); assertEquals((arg.getValue()).getNumber("retryOnConflict"), 1); - assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals((arg.getValue()).getString("refresh"), "wait_for"); assertEquals((arg.getValue()).getBoolean("source"), true); assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); assertEquals((((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("changes")).get("Hello")), "Mister Anderson"); From d5ab56d42c5f19181eca2efca191d49e07bbf7b7 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 12:57:36 +0200 Subject: [PATCH 109/134] search options doc --- .../collection/search-specifications/index.md | 0 doc/3/core-classes/search-options/index.md | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 doc/3/controllers/collection/search-specifications/index.md create mode 100644 doc/3/core-classes/search-options/index.md diff --git a/doc/3/controllers/collection/search-specifications/index.md b/doc/3/controllers/collection/search-specifications/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/3/core-classes/search-options/index.md b/doc/3/core-classes/search-options/index.md new file mode 100644 index 00000000..b54af13c --- /dev/null +++ b/doc/3/core-classes/search-options/index.md @@ -0,0 +1,31 @@ +--- +code: true +type: page +title: SearchOptions +description: SearchOptions class documentation +order: 110 +--- + +# SearchOptions + +This class represents the options usable with the search related methods. + +It can be used with the following methods: + - [document:search](/sdk/java/3/controllers/document/search) + - [collection:searchSpecifications](/sdk/java/3/controllers/collection/search-specifications) + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.Options.SearchOptions; +``` + +## Properties + +| Property | Type | Description | +| -------- | --------------------- | ------------------------------------- | +| `from` |
Integer
| Offset of the first document to fetch | +| `scroll` |
String
| When set, gets a forward-only cursor having its ttl set to the given value (ie `30s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | +| `size` |
Integer
| Maximum number of documents to retrieve per page | \ No newline at end of file From 06624bd86704b21b03e258cba23e9f892dcc65a0 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 13:01:40 +0200 Subject: [PATCH 110/134] deadlink --- doc/3/controllers/collection/search-specifications/index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/3/controllers/collection/search-specifications/index.md b/doc/3/controllers/collection/search-specifications/index.md index e69de29b..e10ebb82 100644 --- a/doc/3/controllers/collection/search-specifications/index.md +++ b/doc/3/controllers/collection/search-specifications/index.md @@ -0,0 +1,6 @@ +--- +code: true +type: page +title: SearchSpecifications +description: Searches collection specifications. +--- From 4822a8abac52590fb7a68c097bc4040dd15f83e7 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 8 Apr 2020 14:18:31 +0200 Subject: [PATCH 111/134] unit test --- .../kuzzle/sdk/CoreClasses/SearchResult.java | 8 --- .../TaskTest/SearchResultTest.java | 67 ++++++++++++++----- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index 8a52f2f9..84218219 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -35,8 +35,6 @@ public SearchResult( ConcurrentHashMap _response = response.toMap(); - System.out.println(response.result); - System.out.println(_response); this.kuzzle = kuzzle; this.options = options; this.request = request; @@ -108,20 +106,16 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec if (this.fetched >= this.total) return null; ConcurrentHashMap nextRequest = new ConcurrentHashMap<>(); - if (this.scrollId != null) { nextRequest = this.getScrollRequest(); } else if (this.options.getSize() != null && ((ConcurrentHashMap) this.request.get("body")).get("sort") != null) { nextRequest = this.getSearchAfterRequest(); } else if (this.options.getSize() != null) { - if (this.options.getFrom() != null && this.options.getFrom() > this.total) { return null; } - System.out.println(this.hits); - System.out.println(this.fetched); this.options.setFrom(this.fetched); nextRequest = this.request; } @@ -130,9 +124,7 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec return null; } - System.out.println(nextRequest); Response response = this.kuzzle.query(nextRequest).get(); - return new SearchResult(this.kuzzle, nextRequest, this.options, response, this.fetched); } } diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java index 89aee4c2..74913f18 100644 --- a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java @@ -3,57 +3,90 @@ import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.CoreClasses.SearchResult; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; import io.kuzzle.sdk.Options.SearchOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.WebSocket; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; + +import static org.mockito.Mockito.spy; public class SearchResultTest { - private Kuzzle kuzzle = Mockito.mock(Kuzzle.class); - private SearchOptions options = Mockito.mock(SearchOptions.class); + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + private Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + private SearchOptions options = new SearchOptions(); + private ConcurrentHashMap request = new ConcurrentHashMap<>(); + private ConcurrentHashMap result = new ConcurrentHashMap<>(); + private ConcurrentHashMap aggregations = new ConcurrentHashMap<>(); + private ArrayList> hits = new ArrayList<>(); + private Response response = new Response(); @Test public void constructorTestA() { - ConcurrentHashMap request = new ConcurrentHashMap<>(); - ConcurrentHashMap result = new ConcurrentHashMap<>(); - ConcurrentHashMap aggregations = new ConcurrentHashMap<>(); - ArrayList> hits = new ArrayList<>(); - result.put("aggregations", aggregations); result.put("hits", hits); result.put("scrollId", ""); result.put("total", new LazilyParsedNumber("1")); - Response response = new Response(); response.result = result; - SearchResult searchResult = new SearchResult(kuzzle, request, options, response); + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response); Assert.assertNotNull(searchResult); - } @Test public void constructorTestB() { - ConcurrentHashMap request = new ConcurrentHashMap<>(); - ConcurrentHashMap result = new ConcurrentHashMap<>(); - ConcurrentHashMap aggregations = new ConcurrentHashMap<>(); - ArrayList> hits = new ArrayList<>(); - result.put("aggregations", aggregations); result.put("hits", hits); result.put("scrollId", ""); result.put("total", new LazilyParsedNumber("1")); - Response response = new Response(); response.result = result; - SearchResult searchResult = new SearchResult(kuzzle, request, options, response, 10); + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); Assert.assertNotNull(searchResult); + } + + @Test + public void nextTestA() throws InternalException, ExecutionException, NotConnectedException, InterruptedException { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollId", "30s"); + result.put("scrollAction", "scroll"); + result.put("total", new LazilyParsedNumber("10")); + request.put("controller", "document"); + response.result = result; + + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); + searchResult = searchResult.next(); + Assert.assertNull(searchResult); + } + + @Test + public void nextTestB() throws InternalException, ExecutionException, NotConnectedException, InterruptedException { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollAction", "scroll"); + result.put("total", new LazilyParsedNumber("20")); + request.put("controller", "document"); + options.setSize(10); + options.setFrom(30); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + request.put("body", body); + response.result = result; + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); + searchResult = searchResult.next(); + Assert.assertNull(searchResult); } } From 0d62666a37669ad1473fc5734c9618c9ed93ae5b Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:35:09 +0200 Subject: [PATCH 112/134] Add collection:deleteSpecifications (#88) This PR implements the collection:deleteSpecifications method with its unit tests. --- .../collection/delete-specifications/index.md | 33 +++++++++++++++++++ .../snippets/delete-specifications.java | 4 +++ .../snippets/delete-specifications.test.yml | 7 ++++ .../API/Controllers/CollectionController.java | 27 +++++++++++++++ .../test/API/Controllers/CollectionTest.java | 31 +++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 doc/3/controllers/collection/delete-specifications/index.md create mode 100644 doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.java create mode 100644 doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.test.yml diff --git a/doc/3/controllers/collection/delete-specifications/index.md b/doc/3/controllers/collection/delete-specifications/index.md new file mode 100644 index 00000000..e07a9d8f --- /dev/null +++ b/doc/3/controllers/collection/delete-specifications/index.md @@ -0,0 +1,33 @@ +--- +code: true +type: page +title: deleteSpecifications +description: Delete validation specifications for a collection +--- + +# deleteSpecifications + +Deletes validation specifications for a collection. + +
+ +```java + public CompletableFuture deleteSpecifications( + final String index, + final String collection) +``` + +
+ +| Arguments | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | + +## Returns + +Returns a `CompletableFuture`. + +## Usage + +<<< ./snippets/delete-specifications.java \ No newline at end of file diff --git a/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.java b/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.java new file mode 100644 index 00000000..bff98d89 --- /dev/null +++ b/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.java @@ -0,0 +1,4 @@ + kuzzle + .getCollectionController() + .deleteSpecifications("nyc-open-data", "yellow-taxi") + .get(); \ No newline at end of file diff --git a/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.test.yml b/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.test.yml new file mode 100644 index 00000000..56cd44ca --- /dev/null +++ b/doc/3/controllers/collection/delete-specifications/snippets/delete-specifications.test.yml @@ -0,0 +1,7 @@ +name: collection#deleteSpecifications +description: Delete validation specifications for a collection +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index 224c9d4d..b59ca011 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -137,6 +137,33 @@ public CompletableFuture> getMapping( (response) -> (ConcurrentHashMap) response.result); } + /** + * Deletes the validation specifications associated to the given index and collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture deleteSpecifications( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "deleteSpecifications"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> null); + } + /** * Gets the validation specifications associated to the given index and collection. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 30c3a876..4594be41 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -179,6 +179,37 @@ public void getMappingShouldThrowWhenNotConnected() throws NotConnectedException kuzzleMock.getCollectionController().getMapping(index, collection); } + @Test + public void deleteSpecificationsCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().deleteSpecifications(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "deleteSpecifications"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void deleteSpecificationsCollectionThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().deleteSpecifications(index, collection); + } + @Test public void getSpecificationsCollectionTest() throws NotConnectedException, InternalException { From abf202fa45510142a6c8698e761ba37523da7d3d Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Thu, 9 Apr 2020 13:13:32 +0200 Subject: [PATCH 113/134] Add collection:updateSpecifications (#85) ## What does this PR do ? This PR implements the `collection:updateSpecifications` method with its unit tests. --- .../collection/update-specifications/index.md | 43 +++++++++++++++ .../snippets/update-specifications.java | 26 ++++++++++ .../snippets/update-specifications.test.yml | 9 ++++ .../API/Controllers/CollectionController.java | 30 +++++++++++ .../test/API/Controllers/CollectionTest.java | 52 +++++++++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 doc/3/controllers/collection/update-specifications/index.md create mode 100644 doc/3/controllers/collection/update-specifications/snippets/update-specifications.java create mode 100644 doc/3/controllers/collection/update-specifications/snippets/update-specifications.test.yml diff --git a/doc/3/controllers/collection/update-specifications/index.md b/doc/3/controllers/collection/update-specifications/index.md new file mode 100644 index 00000000..35bfa067 --- /dev/null +++ b/doc/3/controllers/collection/update-specifications/index.md @@ -0,0 +1,43 @@ +--- +code: true +type: page +title: updateSpecifications +description: Update the validation specifications +--- + +# updateSpecifications + +The updateSpecifications method allows you to create or update the validation specifications for a collection. + +When the validation specification is not formatted correctly, a detailed error message is returned to help you to debug. + +
+ +```java +public CompletableFuture> updateSpecifications( + final String index, + final String collection, + final ConcurrentHashMap specifications) +``` + +
+ +| Arguments | Type | Description | +| ---------------- | -------------------------------------------- | ------------------------ | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `specifications` |
ConcurrentHashMap
| Specifications to update | + +### specifications + +A `ConcurrentHashMap` representing the specifications. + +It must follow the [Specification Structure](/core/2/guides/essentials/data-validation). + +## Returns + +Returns a `ConcurrentHashMap` containing the specifications. + +## Usage + +<<< ./snippets/update-specifications.java \ No newline at end of file diff --git a/doc/3/controllers/collection/update-specifications/snippets/update-specifications.java b/doc/3/controllers/collection/update-specifications/snippets/update-specifications.java new file mode 100644 index 00000000..e627ca17 --- /dev/null +++ b/doc/3/controllers/collection/update-specifications/snippets/update-specifications.java @@ -0,0 +1,26 @@ + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + ConcurrentHashMap fields = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + specifications.put("strict", false); + license.put("mandatory", true); + license.put("type", "string"); + fields.put("license", license); + specifications.put("fields", fields); + + ConcurrentHashMap result = kuzzle + .getCollectionController() + .updateSpecifications("nyc-open-data", "yellow-taxi", specifications) + .get(); + +/* + { + strict=false, + fields={ + license={ + mandatory=true, + type="string" + } + } + } + */ diff --git a/doc/3/controllers/collection/update-specifications/snippets/update-specifications.test.yml b/doc/3/controllers/collection/update-specifications/snippets/update-specifications.test.yml new file mode 100644 index 00000000..288fc2e5 --- /dev/null +++ b/doc/3/controllers/collection/update-specifications/snippets/update-specifications.test.yml @@ -0,0 +1,9 @@ +name: collection#updateSpecifications +description: Update the validation specifications +hooks: + before: | + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi/ + after: curl -X DELETE kuzzle:7512/nyc-open-data/yellow-taxi/_specifications +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index b59ca011..b632b99e 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -190,4 +190,34 @@ public CompletableFuture> getSpecifications( .thenApplyAsync( (response) -> (ConcurrentHashMap) response.result); } + + /** + * Updates validation specifications for a collection. + * + * @param index + * @param collection + * @param specifications + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> updateSpecifications( + final String index, + final String collection, + final ConcurrentHashMap specifications) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "updateSpecifications") + .put("body", new KuzzleMap(specifications)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 4594be41..d3d31481 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -240,4 +240,56 @@ public void getSpecificationsCollectionThrowWhenNotConnected() throws NotConnect kuzzleMock.getCollectionController().getSpecifications(index, collection); } + + @Test + public void updateSpecificationsCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + ConcurrentHashMap fields = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + specifications.put("strict", false); + license.put("mandatory", true); + license.put("type", "string"); + fields.put("license", license); + specifications.put("fields", fields); + + kuzzleMock.getCollectionController().updateSpecifications(index, collection, specifications); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "updateSpecifications"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(( + (ConcurrentHashMap) ( + (ConcurrentHashMap) ( + ((ConcurrentHashMap) + ((arg.getValue()) + .get("body"))) + .get("fields"))) + .get("license")) + .get("type").toString(), "string"); + } + + @Test(expected = NotConnectedException.class) + public void updateSpecificationsCollectionThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + + kuzzleMock.getCollectionController().updateSpecifications(index, collection, specifications); + } } From e4aaf5c2682fde85f31f5f7c75a9bdeb0a3af22a Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:46:21 +0200 Subject: [PATCH 114/134] Update doc/3/controllers/document/search/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/search/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/search/index.md b/doc/3/controllers/document/search/index.md index 4bfea4d0..ba0252f6 100644 --- a/doc/3/controllers/document/search/index.md +++ b/doc/3/controllers/document/search/index.md @@ -12,7 +12,7 @@ Searches document. There is a limit to how many documents can be returned by a single search query. That limit is by default set at 10000 documents, and you can't get over it even with the from and size pagination options. -:::info +::: info When processing a large number of documents (i.e. more than 1000), it is advised to paginate the results using [SearchResult.next](/sdk/java/3/core-classes/search-result/next) rather than increasing the size parameter. ::: From 967fae70e99a95d80f196a19814581ab280087ea Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:46:29 +0200 Subject: [PATCH 115/134] Update doc/3/controllers/document/search/index.md Co-Authored-By: Adrien Maret --- doc/3/controllers/document/search/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/3/controllers/document/search/index.md b/doc/3/controllers/document/search/index.md index ba0252f6..0910e971 100644 --- a/doc/3/controllers/document/search/index.md +++ b/doc/3/controllers/document/search/index.md @@ -65,7 +65,7 @@ The following options can be set: | ---------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `from` |
Integer

(`0`) | Offset of the first document to fetch | | `size` |
Integer

(`10`) | Maximum number of documents to retrieve per page | -| `scroll` |
String

(`""`) | When set, gets a forward-only cursor having its ttl set to the given value (ie `30s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | +| `scroll` |
String

(`""`) | When set, gets a forward-only cursor having its ttl set to the given value (ie `1s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | ## Return From a307024f686b8065f2065df056a3bd883d2d8f91 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:46:37 +0200 Subject: [PATCH 116/134] Update doc/3/core-classes/search-options/index.md Co-Authored-By: Adrien Maret --- doc/3/core-classes/search-options/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/core-classes/search-options/index.md b/doc/3/core-classes/search-options/index.md index b54af13c..5f4967d6 100644 --- a/doc/3/core-classes/search-options/index.md +++ b/doc/3/core-classes/search-options/index.md @@ -27,5 +27,5 @@ import io.kuzzle.sdk.Options.SearchOptions; | Property | Type | Description | | -------- | --------------------- | ------------------------------------- | | `from` |
Integer
| Offset of the first document to fetch | -| `scroll` |
String
| When set, gets a forward-only cursor having its ttl set to the given value (ie `30s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | -| `size` |
Integer
| Maximum number of documents to retrieve per page | \ No newline at end of file +| `scroll` |
String
| When set, gets a forward-only cursor having its ttl set to the given value (ie `1s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | +| `size` |
Integer
| Maximum number of documents to retrieve per page | From 29b889fda7d6b7a17c729dc3f6ac38381433fc8a Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:46:46 +0200 Subject: [PATCH 117/134] Update doc/3/core-classes/search-result/introduction/index.md Co-Authored-By: Adrien Maret --- doc/3/core-classes/search-result/introduction/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/core-classes/search-result/introduction/index.md b/doc/3/core-classes/search-result/introduction/index.md index e7025370..372f732e 100644 --- a/doc/3/core-classes/search-result/introduction/index.md +++ b/doc/3/core-classes/search-result/introduction/index.md @@ -8,7 +8,7 @@ order: 1 # Constructor -This object can only be instantiated internally by this SDK, and is an easy-to-use representation of a paginated result from a [search](/sdk/java/2/core-classes/collection/search) or a [scroll](/sdk/java/2/core-classes/collection/scroll) request. +This object can only be instantiated internally by this SDK, and is an easy-to-use representation of a paginated result from a [search](/sdk/java/3/core-classes/collection/search) or a [scroll](/sdk/java/3/core-classes/collection/scroll) request. --- @@ -24,4 +24,4 @@ This object can only be instantiated internally by this SDK, and is an easy-to-u | `filters` | object | The filters of the search request | get | | `total` | Integer | The total number of results that can be fetched | get | ---- \ No newline at end of file +--- From 425491fba260b4d43c33f228b2d4f8e0e99a2faf Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:47:07 +0200 Subject: [PATCH 118/134] Update doc/3/core-classes/search-result/next/snippets/scroll.java Co-Authored-By: Adrien Maret --- doc/3/core-classes/search-result/next/snippets/scroll.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.java b/doc/3/core-classes/search-result/next/snippets/scroll.java index b5af570a..3c5e99f0 100644 --- a/doc/3/core-classes/search-result/next/snippets/scroll.java +++ b/doc/3/core-classes/search-result/next/snippets/scroll.java @@ -15,7 +15,7 @@ .mCreate("nyc-open-data", "yellow-taxi", documents, true).get(); SearchOptions options = new SearchOptions(); - options.setScroll("10s"); + options.setScroll("1s"); options.setSize(10); ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); @@ -49,4 +49,4 @@ createdAt=1570093133057 }, category="suv" } } */ - System.out.println("Successfully retrieved " + matched.size() + " documents"); \ No newline at end of file + System.out.println("Successfully retrieved " + matched.size() + " documents"); From c785020a145c2fb1ab0ed63b44de1cd171a1fe3b Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Fri, 10 Apr 2020 14:27:56 +0200 Subject: [PATCH 119/134] Add collection:validateSpecifications (#86) --- .../validate-specifications/index.md | 51 ++++++++++++++++++ .../snippets/validate-specifications.java | 24 +++++++++ .../snippets/validate-specifications.test.yml | 7 +++ .../API/Controllers/CollectionController.java | 30 +++++++++++ .../test/API/Controllers/CollectionTest.java | 52 +++++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 doc/3/controllers/collection/validate-specifications/index.md create mode 100644 doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.java create mode 100644 doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.test.yml diff --git a/doc/3/controllers/collection/validate-specifications/index.md b/doc/3/controllers/collection/validate-specifications/index.md new file mode 100644 index 00000000..c3fb13c1 --- /dev/null +++ b/doc/3/controllers/collection/validate-specifications/index.md @@ -0,0 +1,51 @@ +--- +code: true +type: page +title: validateSpecifications +description: Validate specifications format +--- + +# validateSpecifications + +The validateSpecifications method checks if a validation specification is well formatted. It does not store or modify the existing specification. + +When the validation specification is not formatted correctly, a detailed error message is returned to help you to debug. + +
+ +```java + public CompletableFuture> validateSpecifications( + final String index, + final String collection, + final ConcurrentHashMap specifications) +``` + +
+ +| Arguments | Type | Description | +| ---------------- | -------------------------------------------- | -------------------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `specifications` |
ConcurrentHashMap
| Specifications to validate | + +### specifications + +A `ConcurrentHashMap` representing the specifications. + +This object must follow the [Specification Structure](/core/2/guides/cookbooks/datavalidation). + +## Returns + +Returns a `ConcurrentHashMap` which contains information about the specifications validity. + +It contains the following properties: + +| Property | Type | Description | +| ------------- | ---------------------------- | ---------------------------- | +| `valid` |
Boolean
| Specifications validity | +| `details` |
ArrayList
| Specifications errors | +| `description` |
String
| Global description of errors | + +## Usage + +<<< ./snippets/validate-specifications.java \ No newline at end of file diff --git a/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.java b/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.java new file mode 100644 index 00000000..69e736cc --- /dev/null +++ b/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.java @@ -0,0 +1,24 @@ + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + ConcurrentHashMap fields = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + specifications.put("strict", false); + license.put("mandatory", true); + license.put("type", "symbol"); // type 'symbol' is not a recognized type + fields.put("license", license); + specifications.put("fields", fields); + + ConcurrentHashMap result = kuzzle + .getCollectionController() + .validateSpecifications("nyc-open-data", "yellow-taxi", specifications) + .get(); + +/* + { + valid=false, + details=[ + "In nyc-open-data.yellow-taxi.license: symbol is not a recognized type." + ], + description="Some errors with provided specifications." + } +*/ \ No newline at end of file diff --git a/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.test.yml b/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.test.yml new file mode 100644 index 00000000..b5f42d87 --- /dev/null +++ b/doc/3/controllers/collection/validate-specifications/snippets/validate-specifications.test.yml @@ -0,0 +1,7 @@ +name: collection#validateSpecifications +description: Validate specifications format +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result +expected: Some errors with provided specifications. \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index b632b99e..d61667c1 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -191,6 +191,36 @@ public CompletableFuture> getSpecifications( (response) -> (ConcurrentHashMap) response.result); } + /** + * Validates specifications for a collection. + * + * @param index + * @param collection + * @param specifications + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> validateSpecifications( + final String index, + final String collection, + final ConcurrentHashMap specifications) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "validateSpecifications") + .put("body", new KuzzleMap(specifications)); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } + /** * Updates validation specifications for a collection. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index d3d31481..f9977e55 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -241,6 +241,58 @@ public void getSpecificationsCollectionThrowWhenNotConnected() throws NotConnect kuzzleMock.getCollectionController().getSpecifications(index, collection); } + @Test + public void validateSpecificationsCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + ConcurrentHashMap fields = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + specifications.put("strict", false); + license.put("mandatory", true); + license.put("type", "string"); + fields.put("license", license); + specifications.put("fields", fields); + + kuzzleMock.getCollectionController().validateSpecifications(index, collection, specifications); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "validateSpecifications"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(( + (ConcurrentHashMap) ( + (ConcurrentHashMap) ( + ((ConcurrentHashMap) + ((arg.getValue()) + .get("body"))) + .get("fields"))) + .get("license")) + .get("type").toString(), "string"); + } + + @Test(expected = NotConnectedException.class) + public void validateSpecificationsCollectionThrowWhenNotConnected() throws NotConnectedException, InternalException { + + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap specifications = new ConcurrentHashMap<>(); + + kuzzleMock.getCollectionController().validateSpecifications(index, collection, specifications); + } + @Test public void updateSpecificationsCollectionTest() throws NotConnectedException, InternalException { From 23f182b2b217488d6e2af51465fd0193ea87ed62 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 15 Apr 2020 14:22:18 +0200 Subject: [PATCH 120/134] update doc --- .../search-result/introduction/index.md | 41 +++++++++++++------ .../core-classes/search-result/next/index.md | 2 +- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/doc/3/core-classes/search-result/introduction/index.md b/doc/3/core-classes/search-result/introduction/index.md index 372f732e..e5f59ad9 100644 --- a/doc/3/core-classes/search-result/introduction/index.md +++ b/doc/3/core-classes/search-result/introduction/index.md @@ -6,22 +6,37 @@ description: SearchResult:constructor order: 1 --- -# Constructor +# SearchResults -This object can only be instantiated internally by this SDK, and is an easy-to-use representation of a paginated result from a [search](/sdk/java/3/core-classes/collection/search) or a [scroll](/sdk/java/3/core-classes/collection/scroll) request. +This class represents a paginated search result. ---- +It can be returned by the following methods: + - [document:search](/sdk/java/3/controllers/document/search) + - [collection:searchSpecifications](/sdk/java/3/controllers/collection/search-specifications) + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.CoreClasses.SearchResult; +``` ## Properties -| Property name | Type | Description | get/set | -| -------------- | ---------- | --------------------------------------------------------- | ------- | -| `aggregations` | ConcurrentHashMap | The result of an aggregation produced by a search request | get | -| `collection` | Collection | The collection associated to this document | get | -| `documents` | ArrayList> | An array of instantiated Document objects | get | -| `fetched` | Integer | The number of fetched documents so far | get/set | -| `options` | SearchOptions | The arguments of the search/scroll request | get | -| `filters` | object | The filters of the search request | get | -| `total` | Integer | The total number of results that can be fetched | get | +| Property | Type | Description | +| -------------- | ------------------------------------------------------- | ------------------ | +| `aggregations` |
ConcurrentHashMap
| Search aggregations (can be undefined) | +| `hits` |
ArrayList>
| Page results | +| `total` |
Integer
| Total number of items that _can_ be retrieved | +| `fetched` |
Integer
| Number of retrieved items so far | ---- +### hits + +Each element of the `hits` ArrayList is a `ConcurrentHashMap` containing the following properties: + +| Property | Type | Description | +| --------- | ------------------ | ---------------------- | +| `_id` |
String
| Document ID | +| `_score` |
Integer
| [Relevance score](https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-intro.html) | +| `_source` |
ConcurrentHashMap
| Document content | \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/index.md b/doc/3/core-classes/search-result/next/index.md index 1d2e5064..b2e75046 100644 --- a/doc/3/core-classes/search-result/next/index.md +++ b/doc/3/core-classes/search-result/next/index.md @@ -13,7 +13,7 @@ Advances through the search results and returns the next page of items. ## Arguments ```java -next(); +public SearchResult next() ``` ## Returns From 683f9421ad22644da7fcca743e8e68137ba5f8f9 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Wed, 15 Apr 2020 14:47:59 +0200 Subject: [PATCH 121/134] Add collection:refresh (#83) ## What does this PR do ? This PR implements the `collection:refresh` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data`, a `yellow-taxi` collection Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class refreshCollection { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); kuzzle.getCollectionController().refresh("nyc-open-data", "yellow-taxi").get(); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` --- doc/3/controllers/collection/refresh/index.md | 36 +++++++++++++++++++ .../collection/refresh/snippets/refresh.java | 4 +++ .../refresh/snippets/refresh.test.yml | 10 ++++++ .../API/Controllers/CollectionController.java | 26 ++++++++++++++ .../test/API/Controllers/CollectionTest.java | 30 ++++++++++++++++ 5 files changed, 106 insertions(+) create mode 100644 doc/3/controllers/collection/refresh/index.md create mode 100644 doc/3/controllers/collection/refresh/snippets/refresh.java create mode 100644 doc/3/controllers/collection/refresh/snippets/refresh.test.yml diff --git a/doc/3/controllers/collection/refresh/index.md b/doc/3/controllers/collection/refresh/index.md new file mode 100644 index 00000000..70cfe7be --- /dev/null +++ b/doc/3/controllers/collection/refresh/index.md @@ -0,0 +1,36 @@ +--- +code: true +type: page +title: refresh +description: Forces an Elasticsearch search index update +--- + +# refresh + +When writing or deleting documents in Kuzzle, it can take up to 1 second for search indexes to be updated, making the changes available in search results. + +This API route forces an immediate refresh of search indexes. + +:::info +A refresh operation comes with some performance costs. + +From the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/docs-refresh.html): +> "While a refresh is much lighter than a commit, it still has a performance cost. A manual refresh can be useful when writing tests, but don’t do a manual refresh every time you index a document in production; it will hurt your performance. Instead, your application needs to be aware of the near real-time nature of Elasticsearch and make allowances for it." + +::: + +
+ +```java +public CompletableFuture refresh( + final String index, + final String collection) throws NotConnectedException, InternalException +``` + +## Returns + +Returns a `CompletableFuture`. + +## Usage + +<<< ./snippets/refresh.java diff --git a/doc/3/controllers/collection/refresh/snippets/refresh.java b/doc/3/controllers/collection/refresh/snippets/refresh.java new file mode 100644 index 00000000..0fba71ce --- /dev/null +++ b/doc/3/controllers/collection/refresh/snippets/refresh.java @@ -0,0 +1,4 @@ + kuzzle + .getCollectionController() + .refresh("nyc-open-data", "yellow-taxi") + .get(); \ No newline at end of file diff --git a/doc/3/controllers/collection/refresh/snippets/refresh.test.yml b/doc/3/controllers/collection/refresh/snippets/refresh.test.yml new file mode 100644 index 00000000..017b05ab --- /dev/null +++ b/doc/3/controllers/collection/refresh/snippets/refresh.test.yml @@ -0,0 +1,10 @@ +--- +name: index#refresh +description: Forces an Elasticsearch search index update +hooks: + before: | + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index d61667c1..a1e2d278 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -137,6 +137,32 @@ public CompletableFuture> getMapping( (response) -> (ConcurrentHashMap) response.result); } + /** + * Refreshes collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture refresh( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "refresh"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> null); + } + /** * Deletes the validation specifications associated to the given index and collection. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index f9977e55..6a865821 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -179,6 +179,36 @@ public void getMappingShouldThrowWhenNotConnected() throws NotConnectedException kuzzleMock.getCollectionController().getMapping(index, collection); } + @Test + public void refreshCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().refresh(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "refresh"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test(expected = NotConnectedException.class) + public void refreshCollectionShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getCollectionController().refresh(index, collection); + } + @Test public void deleteSpecificationsCollectionTest() throws NotConnectedException, InternalException { From 3dd73259a24020fe18d36a6bfd70e2f80d1b7ec9 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 15 Apr 2020 15:54:39 +0200 Subject: [PATCH 122/134] searchResult next async --- doc/3/core-classes/search-result/next/index.md | 2 +- .../search-result/next/snippets/fromsize.java | 2 +- .../search-result/next/snippets/scroll.java | 2 +- .../io/kuzzle/sdk/CoreClasses/SearchResult.java | 16 ++++++++++------ .../CoreClasses/TaskTest/SearchResultTest.java | 4 ++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/doc/3/core-classes/search-result/next/index.md b/doc/3/core-classes/search-result/next/index.md index b2e75046..652a5030 100644 --- a/doc/3/core-classes/search-result/next/index.md +++ b/doc/3/core-classes/search-result/next/index.md @@ -13,7 +13,7 @@ Advances through the search results and returns the next page of items. ## Arguments ```java -public SearchResult next() +public CompletableFuture next() ``` ## Returns diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.java b/doc/3/core-classes/search-result/next/snippets/fromsize.java index 64f399e4..3a6e0540 100644 --- a/doc/3/core-classes/search-result/next/snippets/fromsize.java +++ b/doc/3/core-classes/search-result/next/snippets/fromsize.java @@ -34,7 +34,7 @@ while (results != null) { matched.addAll(results.hits); - results = results.next(); + results = results.next().get(); } /* diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.java b/doc/3/core-classes/search-result/next/snippets/scroll.java index 3c5e99f0..51ee6c38 100644 --- a/doc/3/core-classes/search-result/next/snippets/scroll.java +++ b/doc/3/core-classes/search-result/next/snippets/scroll.java @@ -35,7 +35,7 @@ while (results != null) { matched.addAll(results.hits); - results = results.next(); + results = results.next().get(); } /* diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index 84218219..a1414b7b 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -102,8 +102,10 @@ private ConcurrentHashMap getSearchAfterRequest() { return nextRequest; } - public SearchResult next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - if (this.fetched >= this.total) return null; + public CompletableFuture next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + System.out.println("fetched: " + this.fetched + " total: " + this.total); + + if (this.fetched >= this.total) return CompletableFuture.completedFuture(null); ConcurrentHashMap nextRequest = new ConcurrentHashMap<>(); if (this.scrollId != null) { @@ -113,7 +115,7 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec nextRequest = this.getSearchAfterRequest(); } else if (this.options.getSize() != null) { if (this.options.getFrom() != null && this.options.getFrom() > this.total) { - return null; + return CompletableFuture.completedFuture(null); } this.options.setFrom(this.fetched); @@ -121,10 +123,12 @@ public SearchResult next() throws NotConnectedException, InternalException, Exec } if (nextRequest == null) { - return null; + return CompletableFuture.completedFuture(null); } - Response response = this.kuzzle.query(nextRequest).get(); - return new SearchResult(this.kuzzle, nextRequest, this.options, response, this.fetched); + final ConcurrentHashMap request = nextRequest; + return this.kuzzle.query(nextRequest) + .thenApplyAsync( + (response) -> new SearchResult(this.kuzzle, request, this.options, response, this.fetched)); } } diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java index 74913f18..b5353882 100644 --- a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java @@ -68,7 +68,7 @@ public void nextTestA() throws InternalException, ExecutionException, NotConnect response.result = result; SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); - searchResult = searchResult.next(); + searchResult = searchResult.next().get(); Assert.assertNull(searchResult); } @@ -86,7 +86,7 @@ public void nextTestB() throws InternalException, ExecutionException, NotConnect response.result = result; SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); - searchResult = searchResult.next(); + searchResult = searchResult.next().get(); Assert.assertNull(searchResult); } } From 4be6e863f22fd7b6c45bab68925e373ba317f66a Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 15 Apr 2020 16:02:40 +0200 Subject: [PATCH 123/134] update doc --- doc/3/controllers/document/search/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/3/controllers/document/search/index.md b/doc/3/controllers/document/search/index.md index 0910e971..be93d933 100644 --- a/doc/3/controllers/document/search/index.md +++ b/doc/3/controllers/document/search/index.md @@ -9,8 +9,10 @@ description: Searches a document Searches document. +::: warning There is a limit to how many documents can be returned by a single search query. That limit is by default set at 10000 documents, and you can't get over it even with the from and size pagination options. +::: ::: info When processing a large number of documents (i.e. more than 1000), it is advised to paginate the results using [SearchResult.next](/sdk/java/3/core-classes/search-result/next) rather than increasing the size parameter. From 8ba1fe44642d3800fdc7f8c11e5c2da89e7f1e2f Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 16 Apr 2020 16:31:34 +0200 Subject: [PATCH 124/134] Add collection:searchSpecifications --- .../collection/search-specifications/index.md | 65 +++++++++ .../snippets/search-specifications.java | 45 ++++++ .../snippets/search-specifications.test.yml | 17 +++ doc/3/core-classes/search-options/index.md | 31 ++++ doc/3/core-classes/search-result/index.md | 6 + .../search-result/introduction/index.md | 42 ++++++ .../core-classes/search-result/next/index.md | 74 ++++++++++ .../search-result/next/snippets/fromsize.java | 51 +++++++ .../next/snippets/fromsize.test.yml | 11 ++ .../search-result/next/snippets/scroll.java | 52 +++++++ .../next/snippets/scroll.test.yml | 11 ++ .../API/Controllers/CollectionController.java | 50 +++++++ .../kuzzle/sdk/CoreClasses/SearchResult.java | 134 ++++++++++++++++++ .../io/kuzzle/sdk/Options/SearchOptions.java | 59 ++++++++ .../test/API/Controllers/CollectionTest.java | 111 +++++++++++++++ .../TaskTest/SearchResultTest.java | 92 ++++++++++++ 16 files changed, 851 insertions(+) create mode 100644 doc/3/controllers/collection/search-specifications/index.md create mode 100644 doc/3/controllers/collection/search-specifications/snippets/search-specifications.java create mode 100644 doc/3/controllers/collection/search-specifications/snippets/search-specifications.test.yml create mode 100644 doc/3/core-classes/search-options/index.md create mode 100644 doc/3/core-classes/search-result/index.md create mode 100644 doc/3/core-classes/search-result/introduction/index.md create mode 100644 doc/3/core-classes/search-result/next/index.md create mode 100644 doc/3/core-classes/search-result/next/snippets/fromsize.java create mode 100644 doc/3/core-classes/search-result/next/snippets/fromsize.test.yml create mode 100644 doc/3/core-classes/search-result/next/snippets/scroll.java create mode 100644 doc/3/core-classes/search-result/next/snippets/scroll.test.yml create mode 100644 src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java create mode 100644 src/main/java/io/kuzzle/sdk/Options/SearchOptions.java create mode 100644 src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java diff --git a/doc/3/controllers/collection/search-specifications/index.md b/doc/3/controllers/collection/search-specifications/index.md new file mode 100644 index 00000000..a31b2505 --- /dev/null +++ b/doc/3/controllers/collection/search-specifications/index.md @@ -0,0 +1,65 @@ +--- +code: true +type: page +title: searchSpecifications +description: Search for specifications +--- + +# searchSpecifications + + +Searches collection specifications. + +There is a limit to how many items can be returned by a single search query. +That limit is by default set at 10000, and you can't get over it even with the from and size pagination options. + +:::info +When processing a large number of items (i.e. more than 1000), it is advised to paginate the results using [SearchResult.next](/sdk/java/3/core-classes/search-result/next) rather than increasing the size parameter. +::: + +
+ +```java +public CompletableFuture searchSpecifications( + final ConcurrentHashMap searchQuery, + final SearchOptions options) throws NotConnectedException, InternalException + +public CompletableFuture searchSpecifications( + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException +``` + +
+ +| Arguments | Type | Description | +| --------- | ----------------- | ------------------------------------- | +| `searchQuery` |
ConcurrentHashMap
| An object containing the search query | +| `options` |
SearchOptions
| Query options | + +### searchQuery body properties: + +- `query`: the search query itself, using the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax. +- `aggregations`: control how the search results should be [aggregated](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-aggregations.html) +- `sort`: contains a list of fields, used to [sort search results](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-request-sort.html), in order of importance. + +An empty body matches all documents in the queried collection. + +### options + +A [SearchOptions](/sdk/java/3/core-classes/search-options) object. + +The following options can be set: + +| Options | Type
(default) | Description | +| ---------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `from` |
Integer

(`0`) | Offset of the first document to fetch | +| `size` |
Integer

(`10`) | Maximum number of documents to retrieve per page | +| `scroll` |
String

(`""`) | When set, gets a forward-only cursor having its ttl set to the given value (ie `1s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | + + ## Return + + Returns a [SearchResult](/sdk/java/3/core-classes/search-result) object. + + +## Usage + +<<< ./snippets/search-specifications.java \ No newline at end of file diff --git a/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java new file mode 100644 index 00000000..f6ae0388 --- /dev/null +++ b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java @@ -0,0 +1,45 @@ + +ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +ConcurrentHashMap filters = new ConcurrentHashMap<>(); +ConcurrentHashMap boost = new ConcurrentHashMap<>(); + +boost.put("boost", 1); +filters.put("match_all", boost); +searchQuery.put("query", filters); + +SearchOptions options = new SearchOptions(); +options.setSize(50); +options.setFrom(0); +options.setScroll("10s"); + +SearchResult result = kuzzle + .getCollectionController() + .searchSpecifications(searchQuery, options).get(); + + System.out.println("fetched: " + result.fetched); + /* + { + "total"=1, + "hits"=[ + { + "_index"="%kuzzle", + "_type"="validations", + "_id"="nyc-open-data#yellow-taxi", + "_score"=1, + "_source"={ + "validation"={ + "strict"=false, + "fields"={ + "license"={ + "type"="string" + } + } + }, + "index"="nyc-open-data", + "collection"="yellow-taxi" + } + } + ], + "scrollId"="DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAACSFlgtZTJFYjNiU1FxQzhSNUFpNlZHZGcAAAAAAAAAkxZYLWUyRWIzYlNRcUM4UjVBaTZWR2RnAAAAAAAAAJQWWC1lMkViM2JTUXFDOFI1QWk2VkdkZwAAAAAAAACVFlgtZTJFYjNiU1FxQzhSNUFpNlZHZGcAAAAAAAAAlhZYLWUyRWIzYlNRcUM4UjVBaTZWR2Rn" + } + */ \ No newline at end of file diff --git a/doc/3/controllers/collection/search-specifications/snippets/search-specifications.test.yml b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.test.yml new file mode 100644 index 00000000..c17b1b58 --- /dev/null +++ b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.test.yml @@ -0,0 +1,17 @@ +name: collection#searchSpecifications +description: Search for specifications +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -X POST kuzzle:7512/nyc-open-data/_create + curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + curl -X PUT -H "Content-Type: application/json" -d '{ + "strict": false, + "fields": { + "license": { + "type": "string" + } + } + }' kuzzle:7512/nyc-open-data/yellow-taxi/_specifications?refresh=wait_for +template: default +expected: 'fetched: 1' \ No newline at end of file diff --git a/doc/3/core-classes/search-options/index.md b/doc/3/core-classes/search-options/index.md new file mode 100644 index 00000000..5f4967d6 --- /dev/null +++ b/doc/3/core-classes/search-options/index.md @@ -0,0 +1,31 @@ +--- +code: true +type: page +title: SearchOptions +description: SearchOptions class documentation +order: 110 +--- + +# SearchOptions + +This class represents the options usable with the search related methods. + +It can be used with the following methods: + - [document:search](/sdk/java/3/controllers/document/search) + - [collection:searchSpecifications](/sdk/java/3/controllers/collection/search-specifications) + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.Options.SearchOptions; +``` + +## Properties + +| Property | Type | Description | +| -------- | --------------------- | ------------------------------------- | +| `from` |
Integer
| Offset of the first document to fetch | +| `scroll` |
String
| When set, gets a forward-only cursor having its ttl set to the given value (ie `1s`; cf [elasticsearch time limits](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#time-units)) | +| `size` |
Integer
| Maximum number of documents to retrieve per page | diff --git a/doc/3/core-classes/search-result/index.md b/doc/3/core-classes/search-result/index.md new file mode 100644 index 00000000..924a90f8 --- /dev/null +++ b/doc/3/core-classes/search-result/index.md @@ -0,0 +1,6 @@ +--- +code: true +type: branch +title: SearchResult +description: SearchResult documentation +--- \ No newline at end of file diff --git a/doc/3/core-classes/search-result/introduction/index.md b/doc/3/core-classes/search-result/introduction/index.md new file mode 100644 index 00000000..e5f59ad9 --- /dev/null +++ b/doc/3/core-classes/search-result/introduction/index.md @@ -0,0 +1,42 @@ +--- +code: true +type: page +title: constructor +description: SearchResult:constructor +order: 1 +--- + +# SearchResults + +This class represents a paginated search result. + +It can be returned by the following methods: + - [document:search](/sdk/java/3/controllers/document/search) + - [collection:searchSpecifications](/sdk/java/3/controllers/collection/search-specifications) + +## Namespace + +You must include the following package: + +```java +import io.kuzzle.sdk.CoreClasses.SearchResult; +``` + +## Properties + +| Property | Type | Description | +| -------------- | ------------------------------------------------------- | ------------------ | +| `aggregations` |
ConcurrentHashMap
| Search aggregations (can be undefined) | +| `hits` |
ArrayList>
| Page results | +| `total` |
Integer
| Total number of items that _can_ be retrieved | +| `fetched` |
Integer
| Number of retrieved items so far | + +### hits + +Each element of the `hits` ArrayList is a `ConcurrentHashMap` containing the following properties: + +| Property | Type | Description | +| --------- | ------------------ | ---------------------- | +| `_id` |
String
| Document ID | +| `_score` |
Integer
| [Relevance score](https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-intro.html) | +| `_source` |
ConcurrentHashMap
| Document content | \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/index.md b/doc/3/core-classes/search-result/next/index.md new file mode 100644 index 00000000..652a5030 --- /dev/null +++ b/doc/3/core-classes/search-result/next/index.md @@ -0,0 +1,74 @@ +--- +code: true +type: page +title: next +description: SearchResult next method +order: 200 +--- + +# next + +Advances through the search results and returns the next page of items. + +## Arguments + +```java +public CompletableFuture next() +``` + +## Returns + +Returns a `SearchResult` object, or `null` if no more pages are available. + +## Throw + +This method throws an exception if: + +- No pagination strategy can be applied (see below) +- If invoking it would lead to more than 10 000 items being retrieved with the `from/size` strategy + +## Pagination strategies + +Depending on the arguments given to the initial search, the `next` method will pick one of the following strategies, by decreasing order of priority. + +### Strategy: scroll cursor + +If the original search query is given a `scroll` parameter, the `next` method uses a cursor to paginate results. + +The results from a scroll request are frozen, and reflect the state of the index at the time the initial `search` request. +For that reason, this method is guaranteed to return consistent results, even if documents are updated or deleted in the database between two pages retrieval. + +This is the most consistent way to paginate results, however, this comes at a higher computing cost for the server. + +::: warning +When using a cursor with the `scroll` option, Elasticsearch has to duplicate the transaction log to keep the same result during the entire scroll session. +It can lead to memory leaks if ascroll duration too great is provided, or if too many scroll sessions are open simultaneously. +::: + +::: info + +You can restrict the scroll session maximum duration under the `services.storage.maxScrollDuration` configuration key. +::: + +<<< ./snippets/scroll.java + +### Strategy: sort / size + +If the initial search contains `sort` and `size` parameters, the `next` method retrieves the next page of results following the sort order, the last item of the current page acting as a live cursor. + +To avoid too many duplicates, it is advised to provide a sort combination that will always identify one item only. The recommended way is to use the field `_uid` which is certain to contain one unique value for each document. + +Because this method does not freeze the search results between two calls, there can be missing or duplicated documents between two result pages. + +This method efficiently mitigates the costs of scroll searches, but returns less consistent results: it's a middle ground, ideal for real-time search requests. + +### Strategy: from / size + +If the initial search contains `from` and `size` parameters, the `next` method retrieves the next page of result by incrementing the `from` offset. + +Because this method does not freeze the search results between two calls, there can be missing or duplicated documents between two result pages. + +It's the fastest pagination method available, but also the less consistent, and it is not possible to retrieve more than 10000 items using it. +Above that limit, any call to `next` throws an Exception. + +<<< ./snippets/fromsize.java \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.java b/doc/3/core-classes/search-result/next/snippets/fromsize.java new file mode 100644 index 00000000..3a6e0540 --- /dev/null +++ b/doc/3/core-classes/search-result/next/snippets/fromsize.java @@ -0,0 +1,51 @@ + ArrayList> documents = new ArrayList<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + body.put("category", "suv"); + for (int i = 0; i < 100; i++) { + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("_id", "suv_no" + i); + document.put("body", body); + documents.add(document); + } + + kuzzle + .getDocumentController() + .mCreate("nyc-open-data", "yellow-taxi", documents, true).get(); + + SearchOptions options = new SearchOptions(); + options.setFrom(1); + options.setSize(5); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("category", "suv"); + query.put("match", match); + searchQuery.put("query", query); + + SearchResult results = kuzzle.getDocumentController().search( + "nyc-open-data", + "yellow-taxi", + searchQuery, options).get(); + + // Fetch the matched items by advancing through the result pages + ArrayList> matched = new ArrayList<>(); + + while (results != null) { + matched.addAll(results.hits); + results = results.next().get(); + } + + /* + { _id="suv_no1", + _score=0.03390155, + _source= + { _kuzzle_info= + { author="-1", + updater=null, + updatedAt=null, + createdAt=1570093133057 }, + category="suv" } } + */ + System.out.println("Successfully retrieved " + matched.size() + " documents"); \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml b/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml new file mode 100644 index 00000000..f05d17ee --- /dev/null +++ b/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml @@ -0,0 +1,11 @@ +name: searchresult#fromsize +description: Next method with from/size +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: | + curl -XDELETE kuzzle:7512/nyc-open-data +template: default +expected: Successfully retrieved 100 documents \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.java b/doc/3/core-classes/search-result/next/snippets/scroll.java new file mode 100644 index 00000000..51ee6c38 --- /dev/null +++ b/doc/3/core-classes/search-result/next/snippets/scroll.java @@ -0,0 +1,52 @@ + ArrayList> documents = new ArrayList<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + body.put("category", "suv"); + + for (int i = 0; i < 100; i++) { + ConcurrentHashMap document = new ConcurrentHashMap<>(); + document.put("_id", "suv_no" + i); + document.put("body", body); + documents.add(document); + } + + kuzzle + .getDocumentController() + .mCreate("nyc-open-data", "yellow-taxi", documents, true).get(); + + SearchOptions options = new SearchOptions(); + options.setScroll("1s"); + options.setSize(10); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("category", "suv"); + query.put("match", match); + searchQuery.put("query", query); + + SearchResult results = kuzzle.getDocumentController().search( + "nyc-open-data", + "yellow-taxi", + searchQuery, options).get(); + + // Fetch the matched items by advancing through the result pages + ArrayList> matched = new ArrayList<>(); + + while (results != null) { + matched.addAll(results.hits); + results = results.next().get(); + } + + /* + { _id="suv_no1", + _score=0.03390155, + _source= + { _kuzzle_info= + { author="-1", + updater=null, + updatedAt=null, + createdAt=1570093133057 }, + category="suv" } } + */ + System.out.println("Successfully retrieved " + matched.size() + " documents"); diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.test.yml b/doc/3/core-classes/search-result/next/snippets/scroll.test.yml new file mode 100644 index 00000000..69926783 --- /dev/null +++ b/doc/3/core-classes/search-result/next/snippets/scroll.test.yml @@ -0,0 +1,11 @@ +name: searchresult#scroll +description: Next method with scroll +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: | + curl -XDELETE kuzzle:7512/nyc-open-data +template: default +expected: Successfully retrieved 100 documents \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index a1e2d278..eb127db7 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -1,9 +1,11 @@ package io.kuzzle.sdk.API.Controllers; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.SearchResult; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SearchOptions; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -276,4 +278,52 @@ public CompletableFuture> updateSpecifications .thenApplyAsync( (response) -> (ConcurrentHashMap) response.result); } + + /** + * Searches collection specifications. + * + * @param searchQuery + * @param options + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture searchSpecifications( + final ConcurrentHashMap searchQuery, + final SearchOptions options) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("controller", "collection") + .put("action", "searchSpecifications") + .put("body", new KuzzleMap(searchQuery)); + + if (options != null) { + query + .put("from", options.getFrom()) + .put("size", options.getSize()); + if (options.getScroll() != null) { + query.put("scroll", options.getScroll()); + } + } + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> new SearchResult(kuzzle, query, options, response)); + } + + /** + * Searches collection specifications. + * + * @param searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture searchSpecifications( + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + return this.searchSpecifications(searchQuery, null); + } } diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java new file mode 100644 index 00000000..a1414b7b --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -0,0 +1,134 @@ +package io.kuzzle.sdk.CoreClasses; + +import com.google.gson.internal.LazilyParsedNumber; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SearchOptions; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.jar.JarOutputStream; + +public class SearchResult { + + private SearchOptions options; + private ConcurrentHashMap request; + private String scrollAction = "scroll"; + private Kuzzle kuzzle; + + public ConcurrentHashMap aggregations; + public ArrayList> hits; + public Integer total; + public Integer fetched; + public String scrollId; + + public SearchResult( + Kuzzle kuzzle, + ConcurrentHashMap request, + SearchOptions options, + Response response) { + + ConcurrentHashMap _response = response.toMap(); + + this.kuzzle = kuzzle; + this.options = options; + this.request = request; + + this.aggregations = (ConcurrentHashMap) ((ConcurrentHashMap) _response.get("result")).get("aggregations"); + this.hits = (ArrayList>) ((ConcurrentHashMap) _response.get("result")).get("hits"); + this.total = ((LazilyParsedNumber) ((ConcurrentHashMap) _response.get("result")).get("total")).intValue(); + this.fetched = hits.size(); + this.scrollId = (String) ((ConcurrentHashMap) _response.get("result")).get("scrollId"); + } + + public SearchResult( + Kuzzle kuzzle, + ConcurrentHashMap request, + SearchOptions options, + Response response, + Integer previouslyFetched) { + + ConcurrentHashMap _response = response.toMap(); + + this.kuzzle = kuzzle; + this.options = options; + this.request = request; + + this.aggregations = (ConcurrentHashMap) ((ConcurrentHashMap) _response.get("result")).get("aggregations"); + this.hits = (ArrayList>) ((ConcurrentHashMap) _response.get("result")).get("hits"); + this.total = ((LazilyParsedNumber) ((ConcurrentHashMap) _response.get("result")).get("total")).intValue(); + this.fetched = hits.size() + previouslyFetched; + this.scrollId = (String) ((ConcurrentHashMap) _response.get("result")).get("scrollId"); + } + + private ConcurrentHashMap getScrollRequest() { + final ConcurrentHashMap obj = new ConcurrentHashMap<>(); + + obj.put("controller", this.request.get("controller")); + obj.put("action", this.scrollAction); + obj.put("scrollId", this.scrollId); + return obj; + } + + private ConcurrentHashMap getSearchAfterRequest() { + ConcurrentHashMap nextRequest = this.request; + ConcurrentHashMap lastItem = this.hits.get(this.hits.size()); + ArrayList searchAfter = new ArrayList<>(); + ArrayList sort = (ArrayList) ((ConcurrentHashMap) this.request.get("body")).get("sort"); + + ((ConcurrentHashMap) this.request.get("body")).put("search_after", searchAfter); + + for (Object value : sort) { + String key; + + if (value instanceof String) { + key = value.toString(); + } else { + key = ((ConcurrentHashMap) value).get("First").toString(); + } + + if (key.equals("_uid")) { + searchAfter.add(this.request.get("collection").toString() + "#" + lastItem.get("_id").toString()); + } else { + ConcurrentHashMap _source = (ConcurrentHashMap) lastItem.get("_source"); + searchAfter.add(_source.get(key)); + } + } + return nextRequest; + } + + public CompletableFuture next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + System.out.println("fetched: " + this.fetched + " total: " + this.total); + + if (this.fetched >= this.total) return CompletableFuture.completedFuture(null); + + ConcurrentHashMap nextRequest = new ConcurrentHashMap<>(); + if (this.scrollId != null) { + nextRequest = this.getScrollRequest(); + } else if (this.options.getSize() != null + && ((ConcurrentHashMap) this.request.get("body")).get("sort") != null) { + nextRequest = this.getSearchAfterRequest(); + } else if (this.options.getSize() != null) { + if (this.options.getFrom() != null && this.options.getFrom() > this.total) { + return CompletableFuture.completedFuture(null); + } + + this.options.setFrom(this.fetched); + nextRequest = this.request; + } + + if (nextRequest == null) { + return CompletableFuture.completedFuture(null); + } + + final ConcurrentHashMap request = nextRequest; + return this.kuzzle.query(nextRequest) + .thenApplyAsync( + (response) -> new SearchResult(this.kuzzle, request, this.options, response, this.fetched)); + } +} diff --git a/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java new file mode 100644 index 00000000..54d0badb --- /dev/null +++ b/src/main/java/io/kuzzle/sdk/Options/SearchOptions.java @@ -0,0 +1,59 @@ +package io.kuzzle.sdk.Options; + +import java.util.concurrent.ConcurrentHashMap; + +public class SearchOptions { + + private Integer from; + private String scroll; + private Integer size; + /** + * Constructor + */ + public SearchOptions() {} + + /** + * Copy constructor + * + * @param options + */ + public SearchOptions(SearchOptions options) { + this.from = options.getFrom(); + this.scroll = options.getScroll(); + this.size = options.getSize(); + } + + public Integer getFrom() { + return from; + } + + public Integer getSize() { + return size; + } + + public String getScroll() { + return scroll; + } + + public void setFrom(Integer from) { + this.from = from; + } + + public void setSize(Integer size) { + this.size = size; + } + + public void setScroll(String scroll) { + this.scroll = scroll; + } + + public ConcurrentHashMap toHashMap() { + ConcurrentHashMap options = new ConcurrentHashMap<>(); + + options.put("from", this.from); + options.put("scroll", this.scroll); + options.put("size", this.size); + + return options; + } +} diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 6a865821..e0e40204 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -1,9 +1,12 @@ package io.kuzzle.test.API.Controllers; +import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; +import io.kuzzle.sdk.CoreClasses.Responses.Response; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SearchOptions; import io.kuzzle.sdk.Protocol.AbstractProtocol; import io.kuzzle.sdk.Protocol.ProtocolState; import io.kuzzle.sdk.Protocol.WebSocket; @@ -12,9 +15,14 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; public class CollectionTest { @@ -374,4 +382,107 @@ public void updateSpecificationsCollectionThrowWhenNotConnected() throws NotConn kuzzleMock.getCollectionController().updateSpecifications(index, collection, specifications); } + + @Test + public void searchSpecificationsTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + CompletableFuture queryResponse = new CompletableFuture<>(); + + Response r = new Response(); + r.result = new ConcurrentHashMap(); + ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); + ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); + ((ConcurrentHashMap) r.result).put("scrollId", ""); + ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); + doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); + + new Thread(() -> { + try { + kuzzleMock.getCollectionController().searchSpecifications(searchQuery); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + queryResponse.complete(r); + Thread.sleep(1000); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test + public void searchSpecificationsTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + SearchOptions options = new SearchOptions(); + options.setSize(10); + options.setFrom(0); + options.setScroll("30s"); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + ConcurrentHashMap query = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + query.put("match", match); + searchQuery.put("query", query); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + CompletableFuture queryResponse = new CompletableFuture<>(); + + Response r = new Response(); + r.result = new ConcurrentHashMap(); + ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); + ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); + ((ConcurrentHashMap) r.result).put("scrollId", ""); + ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); + doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); + + new Thread(() -> { + try { + kuzzleMock.getCollectionController().searchSpecifications(searchQuery, options); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + queryResponse.complete(r); + Thread.sleep(1000); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); + assertEquals((arg.getValue()).getNumber("from"), 0); + assertEquals((arg.getValue()).getNumber("size"), 10); + assertEquals((arg.getValue()).getString("scroll"), "30s"); + + assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test(expected = NotConnectedException.class) + public void searchSpecificationsShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getCollectionController().searchSpecifications(searchQuery); + } } diff --git a/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java new file mode 100644 index 00000000..b5353882 --- /dev/null +++ b/src/test/java/io/kuzzle/test/CoreClasses/TaskTest/SearchResultTest.java @@ -0,0 +1,92 @@ +package io.kuzzle.test.CoreClasses.TaskTest; + +import com.google.gson.internal.LazilyParsedNumber; +import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.SearchResult; +import io.kuzzle.sdk.Exceptions.InternalException; +import io.kuzzle.sdk.Exceptions.NotConnectedException; +import io.kuzzle.sdk.Kuzzle; +import io.kuzzle.sdk.Options.SearchOptions; +import io.kuzzle.sdk.Protocol.AbstractProtocol; +import io.kuzzle.sdk.Protocol.WebSocket; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; + +import static org.mockito.Mockito.spy; + +public class SearchResultTest { + + private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class); + + private Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + private SearchOptions options = new SearchOptions(); + private ConcurrentHashMap request = new ConcurrentHashMap<>(); + private ConcurrentHashMap result = new ConcurrentHashMap<>(); + private ConcurrentHashMap aggregations = new ConcurrentHashMap<>(); + private ArrayList> hits = new ArrayList<>(); + private Response response = new Response(); + + @Test + public void constructorTestA() { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollId", ""); + result.put("total", new LazilyParsedNumber("1")); + + response.result = result; + + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response); + Assert.assertNotNull(searchResult); + } + + @Test + public void constructorTestB() { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollId", ""); + result.put("total", new LazilyParsedNumber("1")); + + response.result = result; + + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); + Assert.assertNotNull(searchResult); + } + + @Test + public void nextTestA() throws InternalException, ExecutionException, NotConnectedException, InterruptedException { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollId", "30s"); + result.put("scrollAction", "scroll"); + result.put("total", new LazilyParsedNumber("10")); + request.put("controller", "document"); + response.result = result; + + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); + searchResult = searchResult.next().get(); + Assert.assertNull(searchResult); + } + + @Test + public void nextTestB() throws InternalException, ExecutionException, NotConnectedException, InterruptedException { + result.put("aggregations", aggregations); + result.put("hits", hits); + result.put("scrollAction", "scroll"); + result.put("total", new LazilyParsedNumber("20")); + request.put("controller", "document"); + options.setSize(10); + options.setFrom(30); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + request.put("body", body); + response.result = result; + + SearchResult searchResult = new SearchResult(kuzzleMock, request, options, response, 10); + searchResult = searchResult.next().get(); + Assert.assertNull(searchResult); + } +} From 70c9070e52a8ea04b84ba876e7e9895bcdacc462 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 16 Apr 2020 16:52:17 +0200 Subject: [PATCH 125/134] template import --- .ci/doc/templates/default.tpl.java | 2 ++ doc/3/controllers/document/search/index.md | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 doc/3/controllers/document/search/index.md diff --git a/.ci/doc/templates/default.tpl.java b/.ci/doc/templates/default.tpl.java index 8052865d..8bfc6f53 100644 --- a/.ci/doc/templates/default.tpl.java +++ b/.ci/doc/templates/default.tpl.java @@ -5,9 +5,11 @@ import io.kuzzle.sdk.Options.KuzzleOptions; import java.util.concurrent.ConcurrentHashMap; import io.kuzzle.sdk.CoreClasses.Responses.Response; +import io.kuzzle.sdk.CoreClasses.SearchResult; import io.kuzzle.sdk.Options.SubscribeOptions; import io.kuzzle.sdk.Options.UpdateOptions; import io.kuzzle.sdk.Options.CreateOptions; +import io.kuzzle.sdk.Options.SearchOptions; public class SnippetTest { private static Kuzzle kuzzle; diff --git a/doc/3/controllers/document/search/index.md b/doc/3/controllers/document/search/index.md new file mode 100644 index 00000000..11b74146 --- /dev/null +++ b/doc/3/controllers/document/search/index.md @@ -0,0 +1,6 @@ +--- +code: true +type: page +title: search +description: Searches a document +--- \ No newline at end of file From 2f8ac5150beb21b867115355669d2ffc4e7635f0 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 17 Apr 2020 10:09:55 +0200 Subject: [PATCH 126/134] remove search snippets --- .../search-result/next/snippets/fromsize.java | 51 ------------------ .../next/snippets/fromsize.test.yml | 11 ---- .../search-result/next/snippets/scroll.java | 52 ------------------- .../next/snippets/scroll.test.yml | 11 ---- 4 files changed, 125 deletions(-) delete mode 100644 doc/3/core-classes/search-result/next/snippets/fromsize.java delete mode 100644 doc/3/core-classes/search-result/next/snippets/fromsize.test.yml delete mode 100644 doc/3/core-classes/search-result/next/snippets/scroll.java delete mode 100644 doc/3/core-classes/search-result/next/snippets/scroll.test.yml diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.java b/doc/3/core-classes/search-result/next/snippets/fromsize.java deleted file mode 100644 index 3a6e0540..00000000 --- a/doc/3/core-classes/search-result/next/snippets/fromsize.java +++ /dev/null @@ -1,51 +0,0 @@ - ArrayList> documents = new ArrayList<>(); - ConcurrentHashMap body = new ConcurrentHashMap<>(); - - body.put("category", "suv"); - for (int i = 0; i < 100; i++) { - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("_id", "suv_no" + i); - document.put("body", body); - documents.add(document); - } - - kuzzle - .getDocumentController() - .mCreate("nyc-open-data", "yellow-taxi", documents, true).get(); - - SearchOptions options = new SearchOptions(); - options.setFrom(1); - options.setSize(5); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("category", "suv"); - query.put("match", match); - searchQuery.put("query", query); - - SearchResult results = kuzzle.getDocumentController().search( - "nyc-open-data", - "yellow-taxi", - searchQuery, options).get(); - - // Fetch the matched items by advancing through the result pages - ArrayList> matched = new ArrayList<>(); - - while (results != null) { - matched.addAll(results.hits); - results = results.next().get(); - } - - /* - { _id="suv_no1", - _score=0.03390155, - _source= - { _kuzzle_info= - { author="-1", - updater=null, - updatedAt=null, - createdAt=1570093133057 }, - category="suv" } } - */ - System.out.println("Successfully retrieved " + matched.size() + " documents"); \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml b/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml deleted file mode 100644 index f05d17ee..00000000 --- a/doc/3/core-classes/search-result/next/snippets/fromsize.test.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: searchresult#fromsize -description: Next method with from/size -hooks: - before: | - curl -XDELETE kuzzle:7512/nyc-open-data - curl -XPOST kuzzle:7512/nyc-open-data/_create - curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi - after: | - curl -XDELETE kuzzle:7512/nyc-open-data -template: default -expected: Successfully retrieved 100 documents \ No newline at end of file diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.java b/doc/3/core-classes/search-result/next/snippets/scroll.java deleted file mode 100644 index 51ee6c38..00000000 --- a/doc/3/core-classes/search-result/next/snippets/scroll.java +++ /dev/null @@ -1,52 +0,0 @@ - ArrayList> documents = new ArrayList<>(); - ConcurrentHashMap body = new ConcurrentHashMap<>(); - - body.put("category", "suv"); - - for (int i = 0; i < 100; i++) { - ConcurrentHashMap document = new ConcurrentHashMap<>(); - document.put("_id", "suv_no" + i); - document.put("body", body); - documents.add(document); - } - - kuzzle - .getDocumentController() - .mCreate("nyc-open-data", "yellow-taxi", documents, true).get(); - - SearchOptions options = new SearchOptions(); - options.setScroll("1s"); - options.setSize(10); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("category", "suv"); - query.put("match", match); - searchQuery.put("query", query); - - SearchResult results = kuzzle.getDocumentController().search( - "nyc-open-data", - "yellow-taxi", - searchQuery, options).get(); - - // Fetch the matched items by advancing through the result pages - ArrayList> matched = new ArrayList<>(); - - while (results != null) { - matched.addAll(results.hits); - results = results.next().get(); - } - - /* - { _id="suv_no1", - _score=0.03390155, - _source= - { _kuzzle_info= - { author="-1", - updater=null, - updatedAt=null, - createdAt=1570093133057 }, - category="suv" } } - */ - System.out.println("Successfully retrieved " + matched.size() + " documents"); diff --git a/doc/3/core-classes/search-result/next/snippets/scroll.test.yml b/doc/3/core-classes/search-result/next/snippets/scroll.test.yml deleted file mode 100644 index 69926783..00000000 --- a/doc/3/core-classes/search-result/next/snippets/scroll.test.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: searchresult#scroll -description: Next method with scroll -hooks: - before: | - curl -XDELETE kuzzle:7512/nyc-open-data - curl -XPOST kuzzle:7512/nyc-open-data/_create - curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi - after: | - curl -XDELETE kuzzle:7512/nyc-open-data -template: default -expected: Successfully retrieved 100 documents \ No newline at end of file From 9f30253c845a551e37277da540828bf7e57058cc Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 17 Apr 2020 10:11:11 +0200 Subject: [PATCH 127/134] update doc --- doc/3/core-classes/search-result/next/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/3/core-classes/search-result/next/index.md b/doc/3/core-classes/search-result/next/index.md index 652a5030..22d8ae8f 100644 --- a/doc/3/core-classes/search-result/next/index.md +++ b/doc/3/core-classes/search-result/next/index.md @@ -50,7 +50,7 @@ It can lead to memory leaks if ascroll duration too great is provided, or if too You can restrict the scroll session maximum duration under the `services.storage.maxScrollDuration` configuration key. ::: -<<< ./snippets/scroll.java + ### Strategy: sort / size @@ -71,4 +71,3 @@ Because this method does not freeze the search results between two calls, there It's the fastest pagination method available, but also the less consistent, and it is not possible to retrieve more than 10000 items using it. Above that limit, any call to `next` throws an Exception. -<<< ./snippets/fromsize.java \ No newline at end of file From 4d72ccebb2c7ddef301c51afa5027f17a0ac4b3b Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 17 Apr 2020 10:28:22 +0200 Subject: [PATCH 128/134] remove debug --- src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index a1414b7b..931a6646 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -103,7 +103,6 @@ private ConcurrentHashMap getSearchAfterRequest() { } public CompletableFuture next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - System.out.println("fetched: " + this.fetched + " total: " + this.total); if (this.fetched >= this.total) return CompletableFuture.completedFuture(null); From 3f7ee03f741a1ee0beb82fb175e5a69415a1ff8e Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Fri, 17 Apr 2020 10:28:47 +0200 Subject: [PATCH 129/134] remove debug --- src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java index a1414b7b..931a6646 100644 --- a/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java +++ b/src/main/java/io/kuzzle/sdk/CoreClasses/SearchResult.java @@ -103,7 +103,6 @@ private ConcurrentHashMap getSearchAfterRequest() { } public CompletableFuture next() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - System.out.println("fetched: " + this.fetched + " total: " + this.total); if (this.fetched >= this.total) return CompletableFuture.completedFuture(null); From b7aecda6393b4854f77dcbf1f9abeedee7ade753 Mon Sep 17 00:00:00 2001 From: Yoann-Abbes <44844010+Yoann-Abbes@users.noreply.github.com> Date: Mon, 20 Apr 2020 13:40:13 +0200 Subject: [PATCH 130/134] Add collection:list (#82) ## What does this PR do ? This PR implements the `collection:list` method with its unit tests. ### How should this be manually tested? Clone this branch and run unit tests `./gradlew test` When it succeed, compile it `./gradlew jar` Initiate another java project by adding the compiled SDK as a dependency. Then, run Kuzzle, create an index `nyc-open-data`, a `yellow-taxi` collection. Finally, run this code ```java import io.kuzzle.sdk.*; import io.kuzzle.sdk.Options.KuzzleOptions; import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; import io.kuzzle.sdk.Protocol.WebSocket; import java.util.concurrent.ConcurrentHashMap; public class listCollection { private static Kuzzle kuzzle; public static void main(String[] args) { WebSocketOptions opts = new WebSocketOptions(); opts.setAutoReconnect(true).setConnectionTimeout(42000); try { WebSocket ws = new WebSocket("localhost", opts); kuzzle = new Kuzzle(ws, (KuzzleOptions) null); kuzzle.connect(); ConcurrentHashMap result = kuzzle.getCollectionController().list("nyc-open- data").get(); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } kuzzle.disconnect(); } }; ``` --- doc/3/controllers/collection/list/index.md | 45 +++++++++++++++++++ .../collection/list/snippets/list.java | 22 +++++++++ .../collection/list/snippets/list.test.yml | 7 +++ .../API/Controllers/CollectionController.java | 23 ++++++++++ .../test/API/Controllers/CollectionTest.java | 28 +++++++++++- 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 doc/3/controllers/collection/list/index.md create mode 100644 doc/3/controllers/collection/list/snippets/list.java create mode 100644 doc/3/controllers/collection/list/snippets/list.test.yml diff --git a/doc/3/controllers/collection/list/index.md b/doc/3/controllers/collection/list/index.md new file mode 100644 index 00000000..646eaf6f --- /dev/null +++ b/doc/3/controllers/collection/list/index.md @@ -0,0 +1,45 @@ +--- +code: true +type: page +title: list +description: Returns the collection list of an index +--- + +# list + +Returns the list of collections associated to a provided index. +The returned list is sorted in alphanumerical order. + +
+ +```java +public CompletableFuture> list( + final String index) throws NotConnectedException, InternalException +``` + + +| Arguments | Type | Description | +| --------- | ---------------------- | ------------- | +| `index` |
String
| Index name | + +## Returns + +Returns a `ConcurrentHashMap` containing the following properties: + +| Property | Type | Description | +| ------------- | ------------------- | ------------------------------------------------------------------ | +| `type` |
String
| Types of returned collections
(`all`, `realtime` or `stored`) | +| `collections` |
ArrayList | List of collections                                                |
+| `from`        | 
Integer
| Offset of the first result | +| `size` |
Integer
| Maximum number of returned results | + +Each object in the `collections` array contains the following properties: + +| Property | Type | Description | +| -------- | ----------------- | ---------------------------------------- | +| `name` |
String
| Collection name | +| `type` |
String
| Collection type (`realtime` or `stored`) | + +## Usage + +<<< ./snippets/list.java \ No newline at end of file diff --git a/doc/3/controllers/collection/list/snippets/list.java b/doc/3/controllers/collection/list/snippets/list.java new file mode 100644 index 00000000..05bd5975 --- /dev/null +++ b/doc/3/controllers/collection/list/snippets/list.java @@ -0,0 +1,22 @@ + ConcurrentHashMap result = kuzzle + .getCollectionController() + .list("nyc-open-data") + .get(); + +/* + { + size=10, + collections=[ + { + name=dark-taxi, + type=stored + }, + { + name=pink-taxi, + type=stored + } + ], + from=0, + type=all + } + */ \ No newline at end of file diff --git a/doc/3/controllers/collection/list/snippets/list.test.yml b/doc/3/controllers/collection/list/snippets/list.test.yml new file mode 100644 index 00000000..b748fa01 --- /dev/null +++ b/doc/3/controllers/collection/list/snippets/list.test.yml @@ -0,0 +1,7 @@ +name: collection#list +description: Returns the collection list of an index +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/pink-taxi && curl -X PUT kuzzle:7512/nyc-open-data/dark-taxi + after: +template: default +expected: Success \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index a1e2d278..c5831c54 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -276,4 +276,27 @@ public CompletableFuture> updateSpecifications .thenApplyAsync( (response) -> (ConcurrentHashMap) response.result); } + + /** + * List collections. + * + * @param index + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture> list( + final String index) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("controller", "collection") + .put("action", "list"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap) response.result); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 6a865821..edd2de00 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -155,7 +155,6 @@ public void getMappingCollectionTest() throws NotConnectedException, InternalExc String index = "nyc-open-data"; String collection = "yellow-taxi"; - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); kuzzleMock.getCollectionController().getMapping(index, collection); @@ -374,4 +373,31 @@ public void updateSpecificationsCollectionThrowWhenNotConnected() throws NotConn kuzzleMock.getCollectionController().updateSpecifications(index, collection, specifications); } + + @Test + public void listCollectionTest() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().list(index); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "list"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + } + + @Test(expected = NotConnectedException.class) + public void listCollectionShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + + kuzzleMock.getCollectionController().list(index); + } } From 940cd6c370464a985a514b0246244c52d94fc1d3 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 22 Apr 2020 16:17:21 +0200 Subject: [PATCH 131/134] conflict [ci skip] --- .../API/Controllers/CollectionController.java | 94 ++++---- .../test/API/Controllers/CollectionTest.java | 204 +++++++++--------- 2 files changed, 149 insertions(+), 149 deletions(-) diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index eb127db7..2f7b7c74 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -279,51 +279,51 @@ public CompletableFuture> updateSpecifications (response) -> (ConcurrentHashMap) response.result); } - /** - * Searches collection specifications. - * - * @param searchQuery - * @param options - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture searchSpecifications( - final ConcurrentHashMap searchQuery, - final SearchOptions options) throws NotConnectedException, InternalException { - - final KuzzleMap query = new KuzzleMap(); - query - .put("controller", "collection") - .put("action", "searchSpecifications") - .put("body", new KuzzleMap(searchQuery)); - - if (options != null) { - query - .put("from", options.getFrom()) - .put("size", options.getSize()); - if (options.getScroll() != null) { - query.put("scroll", options.getScroll()); - } - } - - return kuzzle - .query(query) - .thenApplyAsync( - (response) -> new SearchResult(kuzzle, query, options, response)); - } - - /** - * Searches collection specifications. - * - * @param searchQuery - * @return a CompletableFuture - * @throws NotConnectedException - * @throws InternalException - */ - public CompletableFuture searchSpecifications( - final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { - - return this.searchSpecifications(searchQuery, null); - } +// /** +// * Searches collection specifications. +// * +// * @param searchQuery +// * @param options +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture searchSpecifications( +// final ConcurrentHashMap searchQuery, +// final SearchOptions options) throws NotConnectedException, InternalException { +// +// final KuzzleMap query = new KuzzleMap(); +// query +// .put("controller", "collection") +// .put("action", "searchSpecifications") +// .put("body", new KuzzleMap(searchQuery)); +// +// if (options != null) { +// query +// .put("from", options.getFrom()) +// .put("size", options.getSize()); +// if (options.getScroll() != null) { +// query.put("scroll", options.getScroll()); +// } +// } +// +// return kuzzle +// .query(query) +// .thenApplyAsync( +// (response) -> new SearchResult(kuzzle, query, options, response)); +// } +// +// /** +// * Searches collection specifications. +// * +// * @param searchQuery +// * @return a CompletableFuture +// * @throws NotConnectedException +// * @throws InternalException +// */ +// public CompletableFuture searchSpecifications( +// final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { +// +// return this.searchSpecifications(searchQuery, null); +// } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index e0e40204..2bbc2854 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -383,106 +383,106 @@ public void updateSpecificationsCollectionThrowWhenNotConnected() throws NotConn kuzzleMock.getCollectionController().updateSpecifications(index, collection, specifications); } - @Test - public void searchSpecificationsTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap) r.result).put("scrollId", ""); - ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getCollectionController().searchSpecifications(searchQuery); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "collection"); - assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); - assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - - } - - @Test - public void searchSpecificationsTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - - Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); - SearchOptions options = new SearchOptions(); - options.setSize(10); - options.setFrom(0); - options.setScroll("30s"); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - ConcurrentHashMap query = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - query.put("match", match); - searchQuery.put("query", query); - - ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); - CompletableFuture queryResponse = new CompletableFuture<>(); - - Response r = new Response(); - r.result = new ConcurrentHashMap(); - ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); - ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); - ((ConcurrentHashMap) r.result).put("scrollId", ""); - ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); - doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); - - new Thread(() -> { - try { - kuzzleMock.getCollectionController().searchSpecifications(searchQuery, options); - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - queryResponse.complete(r); - Thread.sleep(1000); - Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); - - assertEquals((arg.getValue()).getString("controller"), "collection"); - assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); - assertEquals((arg.getValue()).getNumber("from"), 0); - assertEquals((arg.getValue()).getNumber("size"), 10); - assertEquals((arg.getValue()).getString("scroll"), "30s"); - - assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); - - } - - @Test(expected = NotConnectedException.class) - public void searchSpecificationsShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { - AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); - Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); - - Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); - - ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); - ConcurrentHashMap match = new ConcurrentHashMap<>(); - match.put("Hello", "Clarisse"); - searchQuery.put("match", match); - - kuzzleMock.getCollectionController().searchSpecifications(searchQuery); - } +// @Test +// public void searchSpecificationsTestA() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// ConcurrentHashMap query = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// query.put("match", match); +// searchQuery.put("query", query); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap) r.result).put("scrollId", ""); +// ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getCollectionController().searchSpecifications(searchQuery); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "collection"); +// assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); +// assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test +// public void searchSpecificationsTestB() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// +// Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); +// SearchOptions options = new SearchOptions(); +// options.setSize(10); +// options.setFrom(0); +// options.setScroll("30s"); +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// ConcurrentHashMap query = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// query.put("match", match); +// searchQuery.put("query", query); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); +// CompletableFuture queryResponse = new CompletableFuture<>(); +// +// Response r = new Response(); +// r.result = new ConcurrentHashMap(); +// ((ConcurrentHashMap) r.result).put("aggregations", new ConcurrentHashMap()); +// ((ConcurrentHashMap) r.result).put("total", new LazilyParsedNumber("1")); +// ((ConcurrentHashMap) r.result).put("scrollId", ""); +// ((ConcurrentHashMap) r.result).put("hits", new ArrayList>()); +// doReturn(queryResponse).when(kuzzleMock).query(any(ConcurrentHashMap.class)); +// +// new Thread(() -> { +// try { +// kuzzleMock.getCollectionController().searchSpecifications(searchQuery, options); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }).start(); +// queryResponse.complete(r); +// Thread.sleep(1000); +// Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); +// +// assertEquals((arg.getValue()).getString("controller"), "collection"); +// assertEquals((arg.getValue()).getString("action"), "searchSpecifications"); +// assertEquals((arg.getValue()).getNumber("from"), 0); +// assertEquals((arg.getValue()).getNumber("size"), 10); +// assertEquals((arg.getValue()).getString("scroll"), "30s"); +// +// assertEquals(((ConcurrentHashMap) ((ConcurrentHashMap) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); +// +// } +// +// @Test(expected = NotConnectedException.class) +// public void searchSpecificationsShouldThrowWhenNotConnected() throws NotConnectedException, InternalException, ExecutionException, InterruptedException { +// AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); +// Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); +// +// Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); +// +// ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); +// ConcurrentHashMap match = new ConcurrentHashMap<>(); +// match.put("Hello", "Clarisse"); +// searchQuery.put("match", match); +// +// kuzzleMock.getCollectionController().searchSpecifications(searchQuery); +// } } From 96c53720e86c3e3fe03c4730bd33f54fcc3cccc1 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 22 Apr 2020 16:22:01 +0200 Subject: [PATCH 132/134] update doc --- doc/3/controllers/collection/search-specifications/index.md | 2 -- doc/3/core-classes/search-result/next/index.md | 4 ---- 2 files changed, 6 deletions(-) diff --git a/doc/3/controllers/collection/search-specifications/index.md b/doc/3/controllers/collection/search-specifications/index.md index cc763b19..c51aa725 100644 --- a/doc/3/controllers/collection/search-specifications/index.md +++ b/doc/3/controllers/collection/search-specifications/index.md @@ -1,7 +1,6 @@ --- code: true type: page -<<<<<<< HEAD title: searchSpecifications description: Search for specifications --- @@ -64,4 +63,3 @@ The following options can be set: ## Usage <<< ./snippets/search-specifications.java - diff --git a/doc/3/core-classes/search-result/next/index.md b/doc/3/core-classes/search-result/next/index.md index 47f92d76..0b25a195 100644 --- a/doc/3/core-classes/search-result/next/index.md +++ b/doc/3/core-classes/search-result/next/index.md @@ -50,11 +50,7 @@ It can lead to memory leaks if ascroll duration too great is provided, or if too You can restrict the scroll session maximum duration under the `services.storage.maxScrollDuration` configuration key. ::: -<<<<<<< HEAD - -======= <<< ./snippets/scroll.java ->>>>>>> 3-dev ### Strategy: sort / size From 40d5843aa8f0c0dcb8e46dcff473c4e573331a06 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Thu, 30 Apr 2020 09:49:33 +0200 Subject: [PATCH 133/134] update snippet --- .../snippets/search-specifications.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java index f6ae0388..aabb4bd7 100644 --- a/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java +++ b/doc/3/controllers/collection/search-specifications/snippets/search-specifications.java @@ -1,10 +1,9 @@ ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); ConcurrentHashMap filters = new ConcurrentHashMap<>(); -ConcurrentHashMap boost = new ConcurrentHashMap<>(); +ConcurrentHashMap args = new ConcurrentHashMap<>(); -boost.put("boost", 1); -filters.put("match_all", boost); +filters.put("match_all", args); searchQuery.put("query", filters); SearchOptions options = new SearchOptions(); @@ -16,7 +15,7 @@ .getCollectionController() .searchSpecifications(searchQuery, options).get(); - System.out.println("fetched: " + result.fetched); +System.out.println("fetched: " + result.fetched); /* { "total"=1, From e80bb576048b8257da46161e1169a916ec9a6651 Mon Sep 17 00:00:00 2001 From: Yoann Abbes Date: Wed, 6 May 2020 15:42:06 +0200 Subject: [PATCH 134/134] getting started doc --- doc/3/getting-started/install/index.md | 120 ++++++++++++++++++ .../install/snippets/document.java | 50 ++++++++ .../install/snippets/document.test.yml | 9 ++ .../install/snippets/firstconnection.java | 52 ++++++++ .../install/snippets/firstconnection.test.yml | 10 ++ .../install/snippets/realtime.java | 68 ++++++++++ .../install/snippets/realtime.test.yml | 10 ++ 7 files changed, 319 insertions(+) create mode 100644 doc/3/getting-started/install/index.md create mode 100644 doc/3/getting-started/install/snippets/document.java create mode 100644 doc/3/getting-started/install/snippets/document.test.yml create mode 100644 doc/3/getting-started/install/snippets/firstconnection.java create mode 100644 doc/3/getting-started/install/snippets/firstconnection.test.yml create mode 100644 doc/3/getting-started/install/snippets/realtime.java create mode 100644 doc/3/getting-started/install/snippets/realtime.test.yml diff --git a/doc/3/getting-started/install/index.md b/doc/3/getting-started/install/index.md new file mode 100644 index 00000000..3f8e164b --- /dev/null +++ b/doc/3/getting-started/install/index.md @@ -0,0 +1,120 @@ +--- +code: false +type: page +title: Getting started +description: Java Getting started +order: 99 +--- + +# Getting Started + +In this tutorial you will learn how to install the Kuzzle **Java SDK**. +This page shows examples of scripts that **store** documents in Kuzzle, and of scripts that subcribe to real-time **notifications** for each new document created. + +::: success +Before proceeding, please make sure your system meets the following requirements: + +- **Oracle JDK or OpenJDK** version 8 or higher ([OpenJDK installation instructions](https://openjdk.java.net/install/)) +- A running Kuzzle Server ([Kuzzle installation guide](/core/2/guides/essentials/installing-kuzzle)) + +::: + + +::: info +Having trouble? Get in touch with us on [Discord](http://join.discord.kuzzle.io)! +::: + +## Installation + +You can find the SDK JARs directly on [bintray](https://bintray.com/kuzzle/maven/kuzzle-sdk-java). Download and add it to your classpath. + +::: info +The following examples are made to be executed without any IDE. +If you're using Eclipse, IntelliJ or another Java IDE, you need to add the SDK as a project dependency in your classpath. +::: + +## First connection + +Initialize a new Java project, create a `gettingstartedfirstconnection.java` file and start by adding the code below: + +<<< ./snippets/firstconnection.java + +This program initializes the Kuzzle Server storage by creating a index, and a collection inside it +Run the program with the following command: + +```bash +$ javac -classpath ./path/to/the/sdk.jar gettingstartedfirstconnection.java +$ java -classpath .:./path/to/the/sdk.jar gettingstartedfirstconnection +Connected! +Index nyc-open-data created! +Collection yellow-taxi created! +``` + +Congratulations, you performed your first connection to Kuzzle Server via a Java program. +You now know how to: + +- Instantiate Kuzzle SDK and connect to Kuzzle Server using a specific protocol (here `websocket`) +- Create a index +- Create a collection within an existing index + +## Create your first document + +Now that you successfully connected to your Kuzzle Server instance, and created an index and a collection, it's time to manipulate some data. + +Here is how Kuzzle structures its storage space: + +- indexes contain collections +- collections contain documents + Create a `gettingstartedstorage.java` file in the playground and add this code: + +<<< ./snippets/document.java + +As you did before, build and run your program: + +```bash +$ javac -classpath ./path/to/the/sdk.jar gettingstartedstorage.java +$ java -classpath .:./path/to/the/sdk.jar gettingstartedstorage +Connected! +New document added to yellow-taxi collection! +``` + +You can perform other actions such as [delete](/sdk/java/3/controllers/document/delete), [replace](/sdk/java/3/controllers/document/replace) or [search](/sdk/java/3/controllers/document/search) documents. There are also other ways to interact with Kuzzle like our [Admin Console](/core/2/guides/essentials/admin-console), the [Kuzzle HTTP API](/core/2/api/essentials/connecting-to-kuzzle) or by using your [own protocol](/core/2/protocols/essentials/getting-started). + +Now you know how to: + +- Store documents in a Kuzzle Server, and access those + +## Subscribe to realtime document notifications (pub/sub) + +Time to use realtime with Kuzzle. Create a new file `gettingstartedrealtime.java` with the following code: + +<<< ./snippets/realtime.java + +This program subscribes to changes made to documents with a `license` field set to `B`, within the `yellow-taxi` collection. Whenever a document matching the provided filters changes, a new notification is received from Kuzzle. + +Build and run your program: + +```bash +$ javac -classpath ./path/to/the/sdk.jar gettingstartedrealtime.java +$ java -classpath .:./path/to/the/sdk.jar gettingstartedrealtime +Connected! +Successfully subscribing! +New document added to yellow-taxi collection! +New created document notification: [Document content as ConcurrentHashMap] +``` + +You should see document content as a `ConcurrentHashMap`. + +Now, you know how to: + +- Create realtime filters +- Subscribe to notifications + +## Where do we go from here? + +Now that you're more familiar with the Java SDK, you can dive even deeper to learn how to leverage its full capabilities: + +- discover what this SDK has to offer by browsing other sections of this documentation +- learn how to use [Koncorde](/core/2/guides/cookbooks/realtime-api) to create incredibly fine-grained and blazing-fast subscriptions +- follow our guide to learn how to perform [basic authentication](/core/2/guides/essentials/user-authentication#local-strategy) +- follow our guide to learn how to [manage users and how to set up fine-grained access control](/core/2/guides/essentials/security) \ No newline at end of file diff --git a/doc/3/getting-started/install/snippets/document.java b/doc/3/getting-started/install/snippets/document.java new file mode 100644 index 00000000..47008b1b --- /dev/null +++ b/doc/3/getting-started/install/snippets/document.java @@ -0,0 +1,50 @@ +import io.kuzzle.sdk.*; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.WebSocket; + +import java.util.concurrent.ConcurrentHashMap; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] args) { + + try { + // Creates a WebSocket connection. + // Replace "kuzzle" with + // your Kuzzle hostname like "localhost" + WebSocketOptions opts = new WebSocketOptions(); + opts.setAutoReconnect(true).setConnectionTimeout(42000); + + WebSocket ws = new WebSocket("kuzzle", opts); + + // Instantiates a Kuzzle client + kuzzle = new Kuzzle(ws, (KuzzleOptions) null); + + // Connects to the server. + kuzzle.connect(); + System.out.println("Connected!"); + } catch(Exception e){ + e.printStackTrace(); + } + + // New document content + ConcurrentHashMap content = new ConcurrentHashMap<>(); + content.put("name", "John"); + content.put("birthday", "1995-11-27"); + content.put("license", "B"); + + // Stores the document in the "yellow-taxi" collection. + try { + kuzzle.getDocumentController() + .create( "nyc-open-data", "yellow-taxi", content).get(); + System.out.println("New document added to the yellow-taxi collection!"); + } catch(Exception e){ + e.printStackTrace(); + } + + // Disconnects the SDK. + kuzzle.disconnect(); + } +} \ No newline at end of file diff --git a/doc/3/getting-started/install/snippets/document.test.yml b/doc/3/getting-started/install/snippets/document.test.yml new file mode 100644 index 00000000..d1a79d2f --- /dev/null +++ b/doc/3/getting-started/install/snippets/document.test.yml @@ -0,0 +1,9 @@ +name: gettingstarted#storage +description: Data manipulation +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create ; curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi/; curl -X DELETE kuzzle:7512/nyc-open-data/yellow-taxi/some-id + after: +template: empty +expected: + - Connected! + - New document added to the yellow-taxi collection! \ No newline at end of file diff --git a/doc/3/getting-started/install/snippets/firstconnection.java b/doc/3/getting-started/install/snippets/firstconnection.java new file mode 100644 index 00000000..6676e9ed --- /dev/null +++ b/doc/3/getting-started/install/snippets/firstconnection.java @@ -0,0 +1,52 @@ +import io.kuzzle.sdk.*; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.WebSocket; + +import java.util.concurrent.ConcurrentHashMap; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] args) { + + try { + // Creates a WebSocket connection. + // Replace "kuzzle" with + // your Kuzzle hostname like "localhost" + WebSocketOptions opts = new WebSocketOptions(); + opts.setAutoReconnect(true).setConnectionTimeout(42000); + + WebSocket ws = new WebSocket("kuzzle", opts); + + // Instantiates a Kuzzle client + kuzzle = new Kuzzle(ws, (KuzzleOptions) null); + + // Connects to the server. + kuzzle.connect(); + System.out.println("Connected!"); + } catch(Exception e){ + e.printStackTrace(); + } + + // Freshly installed Kuzzle servers are empty: we need to create + // a new index. + try { + kuzzle.getIndexController().create("nyc-open-data").get(); + System.out.println("Index nyc-open-data created!"); + } catch(Exception e){ + e.printStackTrace(); + } + + // Creates a collection + try { + kuzzle.getCollectionController().create("nyc-open-data", "yellow-taxi").get(); + System.out.println("Collection yellow-taxi created!"); + } catch(Exception e){ + e.printStackTrace(); + } + + // Disconnects the SDK + kuzzle.disconnect(); + } +} \ No newline at end of file diff --git a/doc/3/getting-started/install/snippets/firstconnection.test.yml b/doc/3/getting-started/install/snippets/firstconnection.test.yml new file mode 100644 index 00000000..f7201621 --- /dev/null +++ b/doc/3/getting-started/install/snippets/firstconnection.test.yml @@ -0,0 +1,10 @@ +name: gettingstarted#firstconnection +description: First connection +hooks: + before: curl -X DELETE kuzzle:7512/nyc-open-data + after: +template: empty +expected: + - Connected! + - Index nyc-open-data created! + - Collection yellow-taxi created! diff --git a/doc/3/getting-started/install/snippets/realtime.java b/doc/3/getting-started/install/snippets/realtime.java new file mode 100644 index 00000000..59600632 --- /dev/null +++ b/doc/3/getting-started/install/snippets/realtime.java @@ -0,0 +1,68 @@ +import io.kuzzle.sdk.*; +import io.kuzzle.sdk.Options.KuzzleOptions; +import io.kuzzle.sdk.Options.Protocol.WebSocketOptions; +import io.kuzzle.sdk.Protocol.WebSocket; + +import java.util.concurrent.ConcurrentHashMap; + +public class SnippetTest { + private static Kuzzle kuzzle; + + public static void main(String[] args) { + + try { + // Creates a WebSocket connection. + // Replace "kuzzle" with + // your Kuzzle hostname like "localhost" + WebSocketOptions opts = new WebSocketOptions(); + opts.setAutoReconnect(true).setConnectionTimeout(42000); + + WebSocket ws = new WebSocket("kuzzle", opts); + + // Instantiates a Kuzzle client + kuzzle = new Kuzzle(ws, (KuzzleOptions) null); + + // Connects to the server. + kuzzle.connect(); + System.out.println("Connected!"); + } catch (Exception e) { + e.printStackTrace(); + } + + // Subscribes to notifications for drivers having a "B" driver license. + ConcurrentHashMap filters = new ConcurrentHashMap<>(); + ConcurrentHashMap equals = new ConcurrentHashMap<>(); + equals.put("license", "B"); + filters.put("equals", equals); + + try { + // Sends the subscription + kuzzle.getRealtimeController() + .subscribe("nyc-open-data", "yellow-taxi", filters, notification -> { + ConcurrentHashMap content = ((ConcurrentHashMap)(notification.result)); + System.out.println("New created document notification: " + content); + }).get(); + System.out.println("Successfully subscribed!"); + } catch (Exception e) { + e.printStackTrace(); + } + + // Writes a new document. This triggers a notification + // sent to our subscription. + ConcurrentHashMap content = new ConcurrentHashMap<>(); + content.put("name", "John"); + content.put("birthday", "1995-11-27"); + content.put("license", "B"); + + try { + kuzzle.getDocumentController() + .create("nyc-open-data", "yellow-taxi", content).get(); + System.out.println("New document added to the yellow-taxi collection!"); + } catch (Exception e) { + e.printStackTrace(); + } + + // Disconnects the SDK. + kuzzle.disconnect(); + } +} \ No newline at end of file diff --git a/doc/3/getting-started/install/snippets/realtime.test.yml b/doc/3/getting-started/install/snippets/realtime.test.yml new file mode 100644 index 00000000..0f45f938 --- /dev/null +++ b/doc/3/getting-started/install/snippets/realtime.test.yml @@ -0,0 +1,10 @@ +name: gettingstarted#realtime +description: Realtime interactions +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create ; curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi/ + after: +template: empty +expected: + - Connected! + - Successfully subscribed! + - ^New created document notification:.*$