From 88039badcdfad591d0db850081263a5d24b8ba23 Mon Sep 17 00:00:00 2001 From: Michael Russo Date: Fri, 2 Sep 2016 09:37:20 -0700 Subject: [PATCH] Initial commit of Usergrid Java SDK into its own repo --- .gitignore | 3 + LICENSE | 202 ++++++ README.md | 580 +++++++++++++++ pom.xml | 127 ++++ .../apache/usergrid/java/client/Usergrid.java | 285 ++++++++ .../usergrid/java/client/UsergridClient.java | 429 +++++++++++ .../java/client/UsergridClientConfig.java | 60 ++ .../usergrid/java/client/UsergridEnums.java | 170 +++++ .../usergrid/java/client/UsergridRequest.java | 205 ++++++ .../java/client/UsergridRequestManager.java | 97 +++ .../java/client/auth/UsergridAppAuth.java | 55 ++ .../java/client/auth/UsergridAuth.java | 76 ++ .../java/client/auth/UsergridUserAuth.java | 68 ++ .../client/exception/UsergridException.java | 50 ++ .../java/client/model/UsergridDevice.java | 60 ++ .../java/client/model/UsergridEntity.java | 487 +++++++++++++ .../java/client/model/UsergridUser.java | 198 +++++ .../java/client/query/UsergridQuery.java | 431 +++++++++++ .../client/response/UsergridResponse.java | 230 ++++++ .../response/UsergridResponseError.java | 98 +++ .../usergrid/java/client/utils/JsonUtils.java | 152 ++++ .../usergrid/java/client/utils/MapUtils.java | 36 + .../java/client/utils/ObjectUtils.java | 38 + .../utils/UsergridEntityDeserializer.java | 41 ++ .../client/ClientAuthFallBackTestCase.java | 72 ++ .../usergrid/client/ClientAuthTestCase.java | 85 +++ .../client/ClientConnectionsTestCase.java | 171 +++++ .../usergrid/client/ClientRestTestCase.java | 90 +++ .../usergrid/client/EntityTestCase.java | 676 ++++++++++++++++++ .../apache/usergrid/client/QueryTestCase.java | 194 +++++ .../usergrid/client/SDKTestConfiguration.java | 38 + .../apache/usergrid/client/SDKTestUtils.java | 108 +++ .../client/UsergridClientAuthTestCase.java | 73 ++ .../usergrid/client/UsergridInitTestCase.java | 48 ++ .../client/UsergridResponseErrorTestCase.java | 62 ++ .../client/UsergridResponseTestCase.java | 85 +++ .../usergrid/client/UsergridTestCase.java | 30 + usergrid-java-client-2.1.0.jar | Bin 0 -> 1992232 bytes 38 files changed, 5910 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/org/apache/usergrid/java/client/Usergrid.java create mode 100644 src/main/java/org/apache/usergrid/java/client/UsergridClient.java create mode 100644 src/main/java/org/apache/usergrid/java/client/UsergridClientConfig.java create mode 100644 src/main/java/org/apache/usergrid/java/client/UsergridEnums.java create mode 100644 src/main/java/org/apache/usergrid/java/client/UsergridRequest.java create mode 100644 src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java create mode 100644 src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java create mode 100644 src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java create mode 100644 src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java create mode 100644 src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java create mode 100644 src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java create mode 100644 src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java create mode 100644 src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java create mode 100644 src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java create mode 100644 src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java create mode 100644 src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java create mode 100644 src/main/java/org/apache/usergrid/java/client/utils/JsonUtils.java create mode 100644 src/main/java/org/apache/usergrid/java/client/utils/MapUtils.java create mode 100644 src/main/java/org/apache/usergrid/java/client/utils/ObjectUtils.java create mode 100644 src/main/java/org/apache/usergrid/java/client/utils/UsergridEntityDeserializer.java create mode 100644 src/test/java/org/apache/usergrid/client/ClientAuthFallBackTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/ClientAuthTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/ClientConnectionsTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/ClientRestTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/EntityTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/QueryTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/SDKTestConfiguration.java create mode 100644 src/test/java/org/apache/usergrid/client/SDKTestUtils.java create mode 100644 src/test/java/org/apache/usergrid/client/UsergridClientAuthTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/UsergridInitTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/UsergridResponseErrorTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/UsergridResponseTestCase.java create mode 100644 src/test/java/org/apache/usergrid/client/UsergridTestCase.java create mode 100644 usergrid-java-client-2.1.0.jar diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40f7468 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +target/ +*.iml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e06d208 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..95e4d04 --- /dev/null +++ b/README.md @@ -0,0 +1,580 @@ +# Usergrid Java SDK + +Usergrid SDK written for Java + +## Initialization + +There are two different ways of initializing the Usergrid Java SDK: + +1. The singleton pattern is both convenient and enables the developer to use a globally available and always-initialized instance of Usergrid. + +```java +Usergrid.initSharedInstance("orgId", "appId"); +``` + +2. The Instance pattern enables the developer to manage instances of the Usergrid client independently and in an isolated fashion. The primary use-case for this is when an application connects to multiple Usergrid targets. + +```java +UsergridClient client = new UsergridClient("orgId","appId"); +``` + +_Note: Examples in this readme assume you are using the `Usergrid` shared instance. If you've implemented the instance pattern instead, simply replace `Usergrid` with your client instance variable._ + +## RESTful operations + +When making any RESTful call, a `type` parameter (or `path`) is always required. Whether you specify this as an argument or in an object as a parameter is up to you. + +### GET + +- To get entities in a collection: + +```java +UsergridResponse response = Usergrid.GET("collection"); +List entities = response.getEntities(); +``` + +- To get a specific entity in a collection by uuid or name: + +```java +UsergridResponse response = Usergrid.GET("collection",""); +UsergridEntity entities = response.entity(); +``` + +- To get specific entities in a collection by passing a `UsergridQuery` object: + +```java +UsergridQuery query = new UsergridQuery("cats").gt("weight", 2.4) + .contains("color", "bl*") + .not() + .eq("color", "blue") + .or() + .eq("color", "orange"); + +// this will build out the following query: +// select * where weight > 2.4 and color contains 'bl*' and not color = 'blue' or color = 'orange' + +UsergridResponse response = Usergrid.GET(query); +List entities = response.getEntities(); +``` + +### POST and PUT + +POST and PUT requests both require a JSON body payload. You can pass either a Java object or a `UsergridEntity` instance. While the former works in principle, best practise is to use a `UsergridEntity` wherever practical. When an entity has a uuid or name property and already exists on the server, use a PUT request to update it. If it does not, use POST to create it. + +- To create a new entity in a collection (**POST**): + +```java +HashMap propertyMap = new HashMap<>(); +propertyMap.put("cuisine","pizza"); +UsergridEntity entity = new UsergridEntity("restaurant","Dino's Deep Dish", propertyMap); +Usergrid.POST(entity); // entity should now have a uuid property and be created + +// you can also POST an array of entities: + +HashMap propertyMap = new HashMap<>(); +propertyMap.put("cuisine","pizza"); + +ArrayList entities = new ArrayList<>(); +entities.add(new UsergridEntity("restaurant","Dino's Deep Dish", propertyMap)); +entities.add(new UsergridEntity("restaurant","Pizza da Napoli", propertyMap)); +UsergridResponse response = Usergrid.POST(entities); +List responseEntities = response.getEntities(); // responseEntities should now contain now valid posted entities. +``` + +- To update an entity in a collection (**PUT**): + +```java +HashMap propertyMap = new HashMap<>(); +propertyMap.put("cuisine","pizza"); +UsergridEntity entity = new UsergridEntity("restaurant","Dino's Deep Dish", propertyMap); +UsergridResponse response = Usergrid.POST(entity); +if( response.ok() ) { + entity.putProperty("owner","Mia Carrara"); + Usergrid.PUT(entity); // entity now has the property 'owner' +} + +// or update a set of entities by passing a UsergridQuery object + +HashMap propertiesToUpdate = new HashMap<>(); +propertiesToUpdate.put("cuisine","pizza"); +UsergridQuery query = new UsergridQuery("restaurants").eq("cuisine","italian"); + +UsergridResponse response = Usergrid.PUT(query, propertiesToUpdate); + + /* the first 10 entities matching this query criteria will be updated: + e.g.: + [ + { + "type": "restaurant", + "restaurant": "Il Tarazzo", + "cuisine": "italian", + "keywords": ["pasta"] + }, + { + "type": "restaurant", + "restaurant": "Cono Sur Pizza & Pasta", + "cuisine": "italian", + "keywords": ["pasta"] + } + ] + */ +``` + +### DELETE + +DELETE requests require either a specific entity or a `UsergridQuery` object to be passed as an argument. + +- To delete a specific entity in a collection by uuid or name: + +```java +UsergridResponse response = Usergrid.DELETE("collection", ""); // if successful, entity will now be deleted +``` + +- To specific entities in a collection to delete by passing a `UsergridQuery` object: + +```java +UsergridQuery query = new UsergridQuery("cats").eq("color","black").or().eq("color","white"); + +// this will build out the following query: +// select * where color = 'black' or color = 'white' + +UsergridResponse response = Usergrid.DELETE(query); // the first 10 entities matching this query criteria will be deleted +``` + +## Entity operations and convenience methods + +`UsergridEntity` has a number of helper/convenience methods to make working with entities more convenient. + +### reload() + +Reloads the entity from the server: + +```java +entity.reload(); // entity is now reloaded from the server +``` + +### save() + +Saves (or creates) the entity on the server: + + +```java +entity.putProperty("aNewProperty","A new value"); +entity.save(); // entity is now updated on the server +``` + +### remove() + +Deletes the entity from the server: + +```java +entity.remove(); // entity is now deleted on the server and the local instance should be destroyed +``` + +## Authentication, current user, and auth-fallback + +### appAuth and authenticateApp() + +`Usergrid` can use the app client ID and secret that were passed upon initialization and automatically retrieve an app-level token for these credentials. + +```java +Usergrid.setAppAuth(new UsergridAppAuth("", "")); +Usergrid.authenticateApp(); // Usergrid.appAuth is authenticated automatically when this call is successful +``` + +### currentUser, userAuth, and authenticateUser() + +`Usergrid` has a special `currentUser` property. + +By default, when calling `authenticateUser()`, `.currentUser` will be set to this user if the authentication flow is successful. + +```java +UsergridUserAuth userAuth = new UsergridUserAuth("",""); +Usergrid.authenticateUser(userAuth); // Usergrid.currentUser is set to the authenticated user and the token is stored within that context +``` + +If you want to utilize authenticateUser without setting as the current user, simply pass a `false` boolean value as the second parameter: + +```java +UsergridUserAuth userAuth = new UsergridUserAuth("",""); +Usergrid.authenticateUser(userAuth,false); // user is authenticated but Usergrid.currentUser is not set. +``` + +### authMode + +Auth-mode defines what the client should pass in for the authorization header. + +By default, `Usergrid.authMode` is set to `.User`, when a `Usergrid.currentUser` is present and authenticated, an API call will be performed using the token for the user. + +If `Usergrid.authMode` is set to `.None`, all API calls will be performed unauthenticated. + +If instead `Usergrid.authMode` is set to `.App`, the API call will instead be performed using client credentials, _if_ they're available (i.e. `authenticateApp()` was performed at some point). + +### usingAuth() + +At times it is desireable to have complete, granular control over the authentication context of an API call. + +To facilitate this, the passthrough function `.usingAuth()` allows you to pre-define the auth context of the next API call. + +```java +// assume Usergrid.authMode = UsergridAuthMode.NONE. + +Map permissionsMap = new HashMap<>(); +permissionsMap.put("permission","get,post,put,delete:/**"); +UsergridResponse response = Usergrid.usingAuth(Usergrid.getAppAuth()).POST("roles/guest/permissions",permissionsMap); + +// here we've temporarily used the client credentials to modify permissions +// subsequent calls will not use this auth context +``` + +## User operations and convenience methods + +`UsergridUser` has a number of helper/convenience methods to make working with user entities more convenient. If you are _not_ utilizing the `Usergrid` shared instance, you must pass an instance of `UsergridClient` as the first argument to any of these helper methods. + +### create() + +Creating a new user: + +```java +UsergridUser user = new UsergridUser("username","password"); +user.create(); // user has now been created and should have a valid uuid +``` + +### login() + +A simpler means of retrieving a user-level token: + +```java +user.login("username","password"); // user is now logged in +``` + +### logout() + +Logs out the selected user. You can also use this convenience method on `Usergrid.currentUser`. + +```java +user.logout(); // user is now logged out +``` + +### resetPassword() + +Resets the password for the selected user. + +```java +// if it was done correctly, the new password will be changed +user.resetPassword("oldPassword", "newPassword"); +``` + +### UsergridUser.CheckAvailable() + +This is a class (static) method that allows you to check whether a username or email address is available or not. + +```java +boolean available = UsergridUser.checkAvailable("email", null); // 'available' == whether an email already exists for a user + +available = UsergridUser.checkAvailable(null, "username"); // 'available' == whether an username already exists for a user + +available = UsergridUser.checkAvailable("email", "username"); // 'available' == whether an email or username already exist for a user +``` + +## Querying and filtering data + +### UsergridQuery initialization + +The `UsergridQuery` class allows you to build out complex query filters using the Usergrid [query syntax](http://docs.apigee.com/app-services/content/querying-your-data). + +The first parameter of the `UsergridQuery` builder pattern should be the collection (or type) you intend to query. You can either pass this as an argument, or as the first builder object: + +```java +UsergridQuery query = new UsergridQuery("cats"); +// or +UsergridQuery query = new UsergridQuery().collection("cats"); +``` + +You then can layer on additional queries: + +```java +UsergridQuery query = new UsergridQuery("cats").gt("weight",2.4).contains("color","bl*") + .not() + .eq("color","white") + .or() + .eq("color","orange"); +``` + +You can also adjust the number of results returned: + +```java +UsergridQuery query = new UsergridQuery("cats").eq("color","black").limit(100); + +// returns a maximum of 100 entities +``` + +And sort the results: + +```java +UsergridQuery query = new UsergridQuery("cats").eq("color","black").limit(100).asc("name") + +// sorts by 'name', ascending +``` + +And you can do geo-location queries: + +```java +UsergridQuery query = new UsergridQuery("devices").locationWithin(, , ); +``` + +### Using a query in a request + +Queries can be passed as parameters to GET, PUT, and DELETE requests: + +```java +// Gets entities matching the query. +Usergrid.GET(query); + +// Updates the entities matching the query with the new property. +Usergrid.PUT(query, Collections.singletonMap("aNewProperty","A new value")); + +// Deletes entities of a given type matching the query. +Usergrid.DELETE(query); +``` +### List of query builder objects + +`type("string")` + +> The collection name to query + +`collection("string")` + +> An alias for `type` + +`eq("key","value")` or +`equals("key","value")` or +`filter("key","value")` + +> Equal to (e.g. `where color = 'black'`) + +`contains("key","value")` or +`containsString("key","value")` or +`containsWord("key","value")` + +> Contains a string (e.g.` where color contains 'bl*'`) + +`gt("key","value")` or +`greaterThan("key","value")` + +> Greater than (e.g. `where weight > 2.4`) + +`gte("key","value")` or +`greaterThanOrEqual("key","value")` + +> Greater than or equal to (e.g. `where weight >= 2.4`) + +`lt("key","value")` or `lessThan("key","value")` + +> Less than (e.g. `where weight < 2.4`) + +`lte("key","value")` or `lessThanOrEqual("key","value")` + +> Less than or equal to (e.g. `where weight <= 2.4`) + +`not()` + +> Negates the next block in the builder pattern, e.g.: + +```java +UsergridQuery query = new UsergridQuery("cats").not().eq("color","black"); +// select * from cats where not color = 'black' +``` + +`and()` + +> Joins two queries by requiring both of them. `and` is also implied when joining two queries _without_ an operator. E.g.: + +```java +UsergridQuery query = new UsergridQuery("cats").eq("color","black").eq("fur","longHair"); +// is identical to: +UsergridQuery query = new UsergridQuery("cats").eq("color","black").and().eq("fur","longHair"); +``` + +`or()` + +> Joins two queries by requiring only one of them. `or` is never implied. e.g.: + +```java +UsergridQuery query = new UsergridQuery("cats").eq("color","black").or().eq("color", "white"); +``` + +> When using `or()` and `and()` operators, `and()` joins will take precedence over `or()` joins. You can read more about query operators and precedence [here](http://docs.apigee.com/api-baas/content/supported-query-operators-data-types). + +`locationWithin(distanceInMeters, latitude, longitude)` + +> Returns entities which have a location within the specified radius. Arguments can be `float` or `int`. + +`asc("key")` or `ascending("key")` + +> Sorts the results by the specified property, ascending + +`desc("key")` or `descending("key")` + +> Sorts the results by the specified property, descending + +`sort("key",UsergridQuerySortOrder.ASC)` + +> Sorts the results by the specified property, in the specified `UsergridQuerySortOrder` (`.ASC` or `.DESC`). + +`limit(int)` + +> The maximum number of entities to return + +`cursor("string")` + +> A pagination cursor string + +`fromString("query string")` + +> A special builder property that allows you to input a pre-defined query string. All builder properties will be ignored when this property is defined. For example: + +```java +UsergridQuery query = new UsergridQuery().fromString("select * where color = 'black' order by name asc"); +``` + +## UsergridResponse object + +`UsergridResponse` is the core class that handles both successful and unsuccessful HTTP responses from Usergrid. + +If a request is successful, any entities returned in the response will be automatically parsed into `UsergridEntity` objects and pushed to the `entities` property. + +If a request fails, the `error` property will contain information about the problem encountered. + +### ok + +You can check `UsergridResponse.ok`, a `Bool` value, to see if the response was successful. Any status code `< 400` returns true. + +```java +UsergridResponse response = Usergrid.GET("collection"); +if( response.ok() ) { + // woo! +} +``` + +### entity, entities, user, users, first, last + +Depending on the call you make, any entities returned in the response will be automatically parsed into `UsergridEntity` objects and pushed to the `entities` property. If you're querying the `users` collection, these will also be `UsergridUser` objects, a subclass of `UsergridEntity`. + +- `.first()` returns the first entity in an array of entities; `.entity()` is an alias to `.first()`. If there are no entities, both of these will be undefined. + +- `.last()` returns the last entity in an array of entities; if there is only one entity in the array, this will be the same as `.first()` _and_ `.entity()`, and will be undefined if there are no entities in the response. + +- `.getEntities()` will either be an array of entities in the response, or an empty array. + +- `.user()` is a special alias for `.entity()` for when querying the `users()` collection. Instead of being a `UsergridEntity`, it will be its subclass, `UsergridUser`. + +- `.users()` is the same as `.user()`, though behaves as `.getEntities()` does by returning either an array of UsergridUser objects or an empty array. + +Examples: + +```java +UsergridResponse response = Usergrid.GET("collection"); + // you can access: + // response.getEntities() (the returned entities) + // response.first() (the first entity) + // response.entity() (same as response.first) + // response.last() (the last entity returned) + +UsergridResponse response = Usergrid.GET("collection",""); + // you can access: + // response.entity() (the returned entity) + // response.getEntities() (containing only the returned entity) + // response.first() (same as response.entity) + // response.last() (same as response.entity) + +UsergridResponse response = Usergrid.GET("users"); + // you can access: + // response.users() (the returned users) + // response.getEntities() (same as response.users) + // response.user() (the first user) + // response.entity() (same as response.user) + // response.first() (same as response.user) + // response.last() (the last user) + +UsergridResponse response = Usergrid.GET("users",""); + // you can access; + // response.users() (containing only the one user) + // response.getEntities() (same as response.users) + // response.user() (the returned user) + // response.entity() (same as response.user) + // response.first() (same as response.user) + // response.last() (same as response.user) +``` + +## Connections + +Connections can be managed using `Usergrid.connect()`, `Usergrid.disconnect()`, and `Usergrid.getConnections()`, or entity convenience methods of the same name. + +When retrieving connections via `Usergrid.getConnections()`, you can pass in a optional `UsergridQuery` object in order to filter the connectioned entities returned. + +### Connect + +Create a connection between two entities: + +```java +Usergrid.connect(entity1, "relationship", entity2); // entity1 now has an outbound connection to entity2 +``` + +### Retrieve Connections + +Retrieve outbound connections: + +```java +Usergrid.getConnections(UsergridDirection.OUT, entity1, "relationship"); + // entities is an array of entities that entity1 is connected to via 'relationship' + // in this case, we'll see entity2 in the array +``` + +Retrieve inbound connections: + +```java +Usergrid.getConnections(UsergridDirection.IN, entity2, "relationship"); + // entities is an array of entities that connect to entity2 via 'relationship' + // in this case, we'll see entity1 in the array +``` + +### Disconnect + +Delete a connection between two entities: + +```java +Usergrid.disconnect(entity1, "relationship", entity2); + // entity1's outbound connection to entity2 has been destroyed +``` + +## Custom UsergridEntity Subclasses + +Creating custom subclasses of the base `UsergridEntity` class (just like `UsergridUser` and `UsergridDevice`) is possible. + +- To do so, subclass `UsergridEntity` and implement the required methods: + +```java +public class ActivityEntity extends UsergridEntity { + public static final String ACTIVITY_ENTITY_TYPE = "activity"; + + public ActivityEntity(){ + super(ACTIVITY_ENTITY_TYPE); + } +} +``` +- You will also need to register the custom subclass: + +```java +Usergrid.initSharedInstance("orgId","appId"); +UsergridEntity.mapCustomSubclassToType("activity", ActivityEntity.class); +``` + +By registering your custom subclass, the `UsergridEntity` and `UsergridResponse` classes are able to generate instances of these classes based on the an entities `type`. + +In the above example, entities which have a `type` value of `activity` can now be cast as `ActivityEntity` objects. e.g.: + +```java +UsergridResponse response = Usergrid.GET("activity"); +ActivityEntity activityEntity = (ActivityEntity)response.entity(); +``` diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a4bb6dc --- /dev/null +++ b/pom.xml @@ -0,0 +1,127 @@ + + + UTF-8 + org.apache.usergrid + org.apache.usergrid + 2.7.3 + 4.11 + 3.2.0 + 9.0.4 + + + 4.0.0 + org.apache.usergrid + usergrid-java-client + 2.2.0-SNAPSHOT + jar + A Java client for Usergrid + http://usergrid.apache.org + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + eanuff + Ed Anuff + + + tnine + Todd Nine + + + sganyo + Scott Ganyo + + + jwest + Jeffrey West + + + adastagiri + Ayesha Dastagiri + + + rwalsh + Robert Walsh + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + com.sun.tools.doclets.standard.Standard + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.7 + 1.7 + + + + + + + + junit + junit + ${junit-version} + test + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + + com.squareup.okhttp3 + okhttp + ${okhttp-version} + + + + com.intellij + annotations + ${intellij-annotations-version} + + + Apache Usergrid Java SDK + + The Apache Software Foundation + http://apache.org + + + JIRA + https://issues.apache.org/jira/browse/USERGRID + + \ No newline at end of file diff --git a/src/main/java/org/apache/usergrid/java/client/Usergrid.java b/src/main/java/org/apache/usergrid/java/client/Usergrid.java new file mode 100644 index 0000000..f7cd545 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/Usergrid.java @@ -0,0 +1,285 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridAuthMode; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.model.*; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.apache.usergrid.java.client.UsergridEnums.UsergridDirection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public final class Usergrid { + @NotNull public static final String UsergridSDKVersion = "2.1.0"; + + private static UsergridClient sharedClient; + private Usergrid() { /** Private constructor because we only have static methods. **/ } + + public static boolean isInitialized() { + return (Usergrid.sharedClient != null); + } + public static void reset() { Usergrid.sharedClient = null; } + + @NotNull + public static UsergridClient getInstance() throws NullPointerException { + if (!Usergrid.isInitialized()) { + throw new NullPointerException("Shared client has not been initialized!"); + } + return Usergrid.sharedClient; + } + + @NotNull + public static UsergridClient initSharedInstance(@NotNull final UsergridClientConfig config) { + if (Usergrid.isInitialized()) { + System.out.print("The Usergrid shared instance was already initialized. All subsequent initialization attempts (including this) will be ignored."); + } else { + Usergrid.sharedClient = new UsergridClient(config); + } + return Usergrid.sharedClient; + } + + @NotNull + public static UsergridClient initSharedInstance(@NotNull final String orgId, @NotNull final String appId) { + return Usergrid.initSharedInstance(new UsergridClientConfig(orgId, appId)); + } + + @NotNull + public static UsergridClient initSharedInstance(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl) { + return Usergrid.initSharedInstance(new UsergridClientConfig(orgId, appId, baseUrl)); + } + + @NotNull + public static UsergridClient initSharedInstance(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl, @NotNull final UsergridAuthMode authMode) { + return Usergrid.initSharedInstance(new UsergridClientConfig(orgId, appId, baseUrl, authMode)); + } + + @NotNull public static UsergridClientConfig getConfig() { return Usergrid.getInstance().getConfig(); } + public static void setConfig(@NotNull UsergridClientConfig config) { Usergrid.getInstance().setConfig(config); } + + @NotNull public static String getAppId() { return Usergrid.getInstance().getAppId(); } + public static void setAppId(@NotNull String appId) { Usergrid.getInstance().setAppId(appId); } + + @NotNull public static String getOrgId() { return Usergrid.getInstance().getOrgId(); } + public static void setOrgId(@NotNull String orgId) { Usergrid.getInstance().setOrgId(orgId); } + + @NotNull public static String getBaseUrl() { return Usergrid.getInstance().getBaseUrl(); } + public static void setBaseUrl(@NotNull String baseUrl) { Usergrid.getInstance().setBaseUrl(baseUrl); } + + @NotNull public static String clientAppUrl() { return Usergrid.getInstance().clientAppUrl(); } + + @NotNull public static UsergridAuthMode getAuthMode() { return Usergrid.getInstance().getAuthMode(); } + public static void setAuthMode(@NotNull final UsergridAuthMode authMode) { Usergrid.getInstance().setAuthMode(authMode); } + + @Nullable public static UsergridAppAuth getAppAuth() { return Usergrid.getInstance().getAppAuth(); } + public static void setAppAuth(@Nullable final UsergridAppAuth appAuth) { Usergrid.getInstance().setAppAuth(appAuth); } + + @Nullable public static UsergridUser getCurrentUser() { return Usergrid.getInstance().getCurrentUser(); } + public static void setCurrentUser(@Nullable final UsergridUser currentUser) { Usergrid.getInstance().setCurrentUser(currentUser); } + + @Nullable + public static UsergridAuth authForRequests() { + return Usergrid.getInstance().authForRequests(); + } + + @NotNull + public static UsergridClient usingAuth(@NotNull final UsergridAuth auth) { + return Usergrid.getInstance().usingAuth(auth); + } + + @NotNull + public static UsergridClient usingToken(@NotNull final String accessToken) { + return Usergrid.getInstance().usingToken(accessToken); + } + + @NotNull + public static UsergridResponse resetPassword(@NotNull final UsergridUser user, @NotNull final String oldPassword, @NotNull final String newPassword) { + return Usergrid.getInstance().resetPassword(user, oldPassword, newPassword); + } + + @NotNull + public static UsergridResponse authenticateApp() { + return Usergrid.getInstance().authenticateApp(); + } + + @NotNull + public static UsergridResponse authenticateApp(@NotNull final UsergridAppAuth appAuth) { + return Usergrid.getInstance().authenticateApp(appAuth); + } + + @NotNull + public static UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth) { + return Usergrid.getInstance().authenticateUser(userAuth); + } + + @NotNull + public static UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth, final boolean setAsCurrentUser) { + return Usergrid.getInstance().authenticateUser(userAuth,setAsCurrentUser); + } + + @NotNull + public static UsergridResponse logoutCurrentUser() { + return Usergrid.getInstance().logoutCurrentUser(); + } + + @NotNull + public static UsergridResponse logoutUserAllTokens(@NotNull final String uuidOrUsername) { + return Usergrid.getInstance().logoutUserAllTokens(uuidOrUsername); + } + + @NotNull + public static UsergridResponse logoutUser(@NotNull final String uuidOrUsername, @Nullable final String token) { + return Usergrid.getInstance().logoutUser(uuidOrUsername,token); + } + + @NotNull + public static UsergridResponse sendRequest(@NotNull final UsergridRequest request) { + return Usergrid.getInstance().sendRequest(request); + } + + @NotNull + public static UsergridResponse GET(@NotNull final String type, @NotNull final String uuidOrName) { + return Usergrid.getInstance().GET(type, uuidOrName); + } + + @NotNull + public static UsergridResponse GET(@NotNull final String type) { + return Usergrid.getInstance().GET(type); + } + + @NotNull + public static UsergridResponse GET(@NotNull final UsergridQuery query) { + return Usergrid.getInstance().GET(query); + } + + @NotNull + public static UsergridResponse PUT(@NotNull final String type, @NotNull final String uuidOrName, @NotNull final Map jsonBody) { + return Usergrid.getInstance().PUT(type, uuidOrName, jsonBody); + } + + @NotNull + public static UsergridResponse PUT(@NotNull final String type, @NotNull final Map jsonBody) { + return Usergrid.getInstance().PUT(type, jsonBody); + } + + @NotNull + public static UsergridResponse PUT(@NotNull final UsergridEntity entity) { + return Usergrid.getInstance().PUT(entity); + } + + @NotNull + public static UsergridResponse PUT(@NotNull final UsergridQuery query, @NotNull final Map jsonBody) { + return Usergrid.getInstance().PUT(query, jsonBody); + } + + @NotNull + public static UsergridResponse POST(@NotNull final String type, @NotNull final String uuidOrName, @NotNull final Map jsonBody) { + return Usergrid.getInstance().POST(type, uuidOrName, jsonBody); + } + + @NotNull + public static UsergridResponse POST(@NotNull final String type, @NotNull final Map jsonBody) { + return Usergrid.getInstance().POST(type, jsonBody); + } + + @NotNull + public static UsergridResponse POST(@NotNull final String type, @NotNull final List> jsonBodies) { + return Usergrid.getInstance().POST(type, jsonBodies); + } + + @NotNull + public static UsergridResponse POST(@NotNull final UsergridEntity entity) throws NullPointerException { + return Usergrid.getInstance().POST(entity); + } + + @NotNull + public static UsergridResponse POST(@NotNull final List entities) { + return Usergrid.getInstance().POST(entities); + } + + @NotNull + public static UsergridResponse DELETE(@NotNull final String type, @NotNull final String uuidOrName) { + return Usergrid.getInstance().DELETE(type, uuidOrName); + } + + @NotNull + public static UsergridResponse DELETE(@NotNull final UsergridEntity entity) { + return Usergrid.getInstance().DELETE(entity); + } + + @NotNull + public static UsergridResponse DELETE(@NotNull final UsergridQuery query) { + return Usergrid.getInstance().DELETE(query); + } + + @NotNull + public static UsergridResponse connect(@NotNull final UsergridEntity entity, @NotNull final String relationship, @NotNull final UsergridEntity to) { + return Usergrid.getInstance().connect(entity, relationship, to); + } + + @NotNull + public static UsergridResponse connect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String fromUuid) { + return Usergrid.getInstance().connect(entityType,entityId,relationship,fromUuid); + } + + @NotNull + public static UsergridResponse connect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String toType, @NotNull final String toName) { + return Usergrid.getInstance().connect(entityType,entityId,relationship,toType,toName); + } + + @NotNull + public static UsergridResponse disconnect(@NotNull final UsergridEntity entity, @NotNull final String relationship, @NotNull final UsergridEntity from) { + return Usergrid.getInstance().disconnect(entity, relationship, from); + } + + @NotNull + public static UsergridResponse disconnect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String fromUuid) { + return Usergrid.getInstance().disconnect(entityType, entityId, relationship, fromUuid); + } + + @NotNull + public static UsergridResponse disconnect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String fromType, @NotNull final String fromName) { + return Usergrid.getInstance().disconnect(entityType, entityId, relationship, fromType, fromName); + } + + @NotNull + public static UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final UsergridEntity entity, @NotNull final String relationship) { + return Usergrid.getInstance().getConnections(direction, entity, relationship); + } + + @NotNull + public static UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final UsergridEntity entity, @NotNull final String relationship, @Nullable final UsergridQuery query) { + return Usergrid.getInstance().getConnections(direction, entity, relationship, query); + } + + @NotNull + public static UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String type, @NotNull final String uuidOrName, @NotNull final String relationship, @Nullable final UsergridQuery query) { + return Usergrid.getInstance().getConnections(direction,type,uuidOrName,relationship,query); + } + + @NotNull + public static UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String uuid, @NotNull final String relationship, @Nullable final UsergridQuery query) { + return Usergrid.getInstance().getConnections(direction, uuid, relationship, query); + } +} \ No newline at end of file diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridClient.java b/src/main/java/org/apache/usergrid/java/client/UsergridClient.java new file mode 100644 index 0000000..a317d07 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridClient.java @@ -0,0 +1,429 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.model.*; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public class UsergridClient { + + @NotNull public static String DEFAULT_BASE_URL = "https://api.usergrid.com"; + + @NotNull private UsergridClientConfig config; + @Nullable private UsergridUser currentUser = null; + @Nullable private UsergridAuth tempAuth = null; + + @NotNull private final UsergridRequestManager requestManager; + + public UsergridClient(@NotNull final UsergridClientConfig config) { + this.config = config; + this.requestManager = new UsergridRequestManager(this); + } + + public UsergridClient(@NotNull final String orgId, @NotNull final String appId) { + this(new UsergridClientConfig(orgId, appId)); + } + + public UsergridClient(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl) { + this(new UsergridClientConfig(orgId, appId, baseUrl)); + } + + public UsergridClient(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl, @NotNull final UsergridAuthMode authMode) { + this(new UsergridClientConfig(orgId, appId, baseUrl, authMode)); + } + + @NotNull public UsergridClientConfig getConfig() { return this.config; } + public void setConfig(@NotNull final UsergridClientConfig config) { this.config = config; } + + @NotNull public String getAppId() { return this.config.appId; } + public void setAppId(@NotNull final String appId) { this.config.appId = appId; } + + @NotNull public String getOrgId() { return this.config.orgId; } + public void setOrgId(@NotNull final String orgId) { this.config.orgId = orgId; } + + @NotNull public String getBaseUrl() { return this.config.baseUrl; } + public void setBaseUrl(@NotNull final String baseUrl) { this.config.baseUrl = baseUrl; } + + @NotNull public String clientAppUrl() { return getBaseUrl() + "/" + getOrgId() + "/" + getAppId(); } + + @NotNull public String managementUrl() { return getBaseUrl() + "/management"; } + + @NotNull public UsergridAuthMode getAuthMode() { return this.config.authMode; } + public void setAuthMode(@NotNull final UsergridAuthMode authMode) { this.config.authMode = authMode; } + + @Nullable public UsergridUser getCurrentUser() { return this.currentUser; } + public void setCurrentUser(@Nullable final UsergridUser currentUser) { this.currentUser = currentUser; } + + @Nullable public UsergridUserAuth getUserAuth() { return (this.currentUser != null) ? this.currentUser.getUserAuth() : null; } + + @Nullable public UsergridAppAuth getAppAuth() { return this.config.appAuth; } + public void setAppAuth(@Nullable final UsergridAppAuth appAuth) { this.config.appAuth = appAuth; } + + @Nullable + public UsergridAuth authForRequests() { + UsergridAuth authForRequests = null; + if (tempAuth != null) { + if (tempAuth.isValidToken()) { + authForRequests = tempAuth; + } + tempAuth = null; + } else { + switch (config.authMode) { + case USER: { + if (this.currentUser != null && this.currentUser.getUserAuth() != null && this.currentUser.getUserAuth().isValidToken()) { + authForRequests = this.currentUser.getUserAuth(); + } + break; + } + case APP: { + if (this.config.appAuth != null && this.config.appAuth.isValidToken()) { + authForRequests = this.config.appAuth; + } + break; + } + } + } + return authForRequests; + } + + @NotNull + public UsergridClient usingAuth(@Nullable final UsergridAuth auth) { + this.tempAuth = auth; + return this; + } + + @NotNull + public UsergridClient usingToken(@NotNull final String accessToken) { + this.tempAuth = new UsergridAuth(accessToken); + return this; + } + + @NotNull + public UsergridResponse authenticateApp() { + if( this.config.appAuth == null ) { + return UsergridResponse.fromError(this, "Invalid UsergridAppAuth.", "UsergridClient's appAuth is null."); + } + return this.authenticateApp(this.config.appAuth); + } + + @NotNull + public UsergridResponse authenticateApp(@NotNull final UsergridAppAuth auth) { + this.config.appAuth = auth; + return this.requestManager.authenticateApp(auth); + } + + @NotNull + public UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth) { + return this.authenticateUser(userAuth,true); + } + + @NotNull + public UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth, final boolean setAsCurrentUser) { + UsergridResponse response = this.requestManager.authenticateUser(userAuth); + if( response.ok() && setAsCurrentUser ) { + this.setCurrentUser(response.user()); + } + return response; + } + + @NotNull + public UsergridResponse resetPassword(@NotNull final UsergridUser user, @NotNull final String oldPassword, @NotNull final String newPassword) { + String usernameOrEmail = user.usernameOrEmail(); + if( usernameOrEmail == null ) { + return UsergridResponse.fromError(this, "Error resetting password.", "The UsergridUser object must contain a valid username or email to reset the password."); + } + Map data = new HashMap<>(); + data.put("newpassword", newPassword); + data.put("oldpassword", oldPassword); + String[] pathSegments = { "users", usernameOrEmail, "password"}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, data, this.authForRequests() ,pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse logoutCurrentUser() { + UsergridUser currentUser = this.currentUser; + if( currentUser != null ) { + String uuidOrUsername = currentUser.uuidOrUsername(); + UsergridUserAuth userAuth = currentUser.getUserAuth(); + if( uuidOrUsername != null && userAuth != null ) { + String accessToken = userAuth.getAccessToken(); + if( accessToken != null ) { + return logoutUser(uuidOrUsername, accessToken); + } + } + } + return UsergridResponse.fromError(this,"UsergridClient's currentUser is not valid.", "UsergridClient's currentUser is null or has no uuid or username."); + } + + @NotNull + public UsergridResponse logoutUserAllTokens(@NotNull final String uuidOrUsername) { + return logoutUser(uuidOrUsername, null); + } + + @NotNull + public UsergridResponse logoutUser(@NotNull final String uuidOrUsername, @Nullable final String token){ + String[] pathSegments = {"users", uuidOrUsername, ""}; + int len = pathSegments.length; + Map param = new HashMap<>(); + if(token != null){ + pathSegments[len-1] = "revoketoken"; + param.put("token",token); + } + else{ + pathSegments[len-1] = "revoketokens"; + } + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.PUT, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), param, null, this.authForRequests() , pathSegments); + UsergridResponse response = this.sendRequest(request); + UsergridUser currentUser = this.getCurrentUser(); + if( currentUser != null && response.ok() ) { + if( uuidOrUsername.equalsIgnoreCase(currentUser.uuidOrUsername()) ) { + this.setCurrentUser(null); + } + } + return response; + } + + @NotNull + public UsergridResponse sendRequest(@NotNull final UsergridRequest request) { + return this.requestManager.performRequest(request); + } + + @NotNull + public UsergridResponse GET(@NotNull final String type, @NotNull final String uuidOrName) { + String[] pathSegments = {type, uuidOrName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse GET(@NotNull final String type) { + String[] pathSegments = {type}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse GET(@NotNull final UsergridQuery query) { + String collectionName = query.getCollection(); + if( collectionName == null ) { + return UsergridResponse.fromError(this, "Query collection name missing.", "Query collection name is missing."); + } + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), query, this.authForRequests() , collectionName); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse PUT(@NotNull final String type, @NotNull final String uuidOrName, @NotNull final Map jsonBody) { + String[] pathSegments = { type, uuidOrName }; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.PUT, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBody, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse PUT(@NotNull final String type, @NotNull final Map jsonBody) { + String uuidOrName = null; + Object uuid = jsonBody.get(UsergridEntityProperties.UUID.toString()); + if( uuid != null ) { + uuidOrName = uuid.toString(); + } else { + Object name = jsonBody.get(UsergridEntityProperties.NAME.toString()); + if( name != null ) { + uuidOrName = name.toString(); + } + } + if( uuidOrName == null ) { + return UsergridResponse.fromError(this, "jsonBody not valid..", "The `jsonBody` must contain a valid value for either `uuid` or `name`."); + } + String[] pathSegments = { type, uuidOrName }; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.PUT, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBody, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse PUT(@NotNull final UsergridEntity entity) { + String entityUuidOrName = entity.uuidOrName(); + if( entityUuidOrName == null ) { + return UsergridResponse.fromError(this, "No UUID or name found.", "The entity object must have a `uuid` or `name` assigned."); + } + String[] pathSegments = { entity.getType(), entityUuidOrName }; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.PUT, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, entity, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse PUT(@NotNull final UsergridQuery query, @NotNull final Map jsonBody) { + String collectionName = query.getCollection(); + if( collectionName == null ) { + return UsergridResponse.fromError(this, "Query collection name missing.", "Query collection name is missing."); + } + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.PUT, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBody, null, query, this.authForRequests(),collectionName); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse POST(final @NotNull UsergridEntity entity) { + String[] pathSegments = {entity.getType()}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, entity, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse POST(@NotNull final List entities) { + if( entities.isEmpty() ) { + return UsergridResponse.fromError(this, "Unable to POST entities.", "entities array is empty."); + } + String[] pathSegments = {entities.get(0).getType()}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, entities, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse POST(@NotNull final String type, @NotNull final String uuidOrName, @NotNull final Map jsonBody) { + String[] pathSegments = {type, uuidOrName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBody, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse POST(@NotNull final String type, @NotNull final Map jsonBody) { + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBody, this.authForRequests() , type); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse POST(@NotNull final String type, @NotNull final List> jsonBodies) { + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), null, jsonBodies, this.authForRequests() , type); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse DELETE(@NotNull final UsergridEntity entity) { + String entityUuidOrName = entity.uuidOrName(); + if( entityUuidOrName == null ) { + return UsergridResponse.fromError(this, "No UUID or name found.", "The entity object must have a `uuid` or `name` assigned."); + } + String[] pathSegments = {entity.getType(), entityUuidOrName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse DELETE(@NotNull final String type, @NotNull final String uuidOrName) { + String[] pathSegments = {type, uuidOrName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse DELETE(@NotNull final UsergridQuery query) { + String collectionName = query.getCollection(); + if( collectionName == null ) { + return UsergridResponse.fromError(this, "Query collection name missing.", "Query collection name is missing."); + } + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), query, this.authForRequests() , collectionName); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse connect(@NotNull final UsergridEntity entity, @NotNull final String relationship, @NotNull final UsergridEntity to) { + String entityUuidOrName = entity.uuidOrName(); + String toUuidOrName = to.uuidOrName(); + if( entityUuidOrName == null || toUuidOrName == null ) { + return UsergridResponse.fromError(this, "Invalid Entity Connection Attempt.", "One or both entities that are attempting to be connected do not contain a valid UUID or Name property."); + } + return this.connect(entity.getType(), entityUuidOrName, relationship, to.getType(), toUuidOrName); + } + + @NotNull + public UsergridResponse connect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String toType, @NotNull final String toName) { + String[] pathSegments = {entityType, entityId, relationship, toType, toName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse connect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String toId) { + String[] pathSegments = { entityType, entityId, relationship, toId}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String fromUuid) { + String[] pathSegments = {entityType, entityId, relationship, fromUuid}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final String entityType, @NotNull final String entityId, @NotNull final String relationship, @NotNull final String fromType, @NotNull final String fromName) { + String[] pathSegments = {entityType, entityId, relationship, fromType, fromName}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final UsergridEntity entity, @NotNull final String relationship, @NotNull final UsergridEntity from) { + String entityUuidOrName = entity.uuidOrName(); + String fromUuidOrName = from.uuidOrName(); + if( entityUuidOrName == null || fromUuidOrName == null ) { + return UsergridResponse.fromError(this, "Invalid Entity Disconnect Attempt.", "One or both entities that are attempting to be disconnected do not contain a valid UUID or Name property."); + } + return this.disconnect(entity.getType(), entityUuidOrName, relationship, from.getType(), fromUuidOrName); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final UsergridEntity entity, @NotNull final String relationship) { + return this.getConnections(direction,entity,relationship,null); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final UsergridEntity entity, @NotNull final String relationship, @Nullable final UsergridQuery query) { + String entityUuidOrName = entity.uuidOrName(); + if( entityUuidOrName == null ) { + return UsergridResponse.fromError(this, "Invalid Entity Get Connections Attempt.", "The entity must have a `uuid` or `name` assigned."); + } + return this.getConnections(direction,entity.getType(),entityUuidOrName,relationship,query); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String type, @NotNull final String uuidOrName, @NotNull final String relationship, @Nullable final UsergridQuery query) { + String[] pathSegments = {type, uuidOrName, direction.connectionValue(), relationship}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), query, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String uuid, @NotNull final String relationship, @Nullable final UsergridQuery query) { + String[] pathSegments = {uuid, direction.connectionValue(), relationship}; + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, this.clientAppUrl(), query, this.authForRequests() , pathSegments); + return this.sendRequest(request); + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridClientConfig.java b/src/main/java/org/apache/usergrid/java/client/UsergridClientConfig.java new file mode 100644 index 0000000..f12f9ec --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridClientConfig.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridAuthMode; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class UsergridClientConfig { + + // The organization identifier. + @NotNull public String orgId; + + // The application identifier. + @NotNull public String appId; + + // The base URL that all calls will be made with. + @NotNull public String baseUrl = UsergridClient.DEFAULT_BASE_URL; + + // The `UsergridAuthMode` value used to determine what type of token will be sent, if any. + @NotNull public UsergridAuthMode authMode = UsergridAuthMode.USER; + + @Nullable public UsergridAppAuth appAuth = null; + + @SuppressWarnings("unused") + private UsergridClientConfig() {} + + public UsergridClientConfig(@NotNull final String orgId, @NotNull final String appId) { + this.orgId = orgId; + this.appId = appId; + } + + public UsergridClientConfig(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl) { + this.orgId = orgId; + this.appId = appId; + this.baseUrl = baseUrl; + } + + public UsergridClientConfig(@NotNull final String orgId, @NotNull final String appId, @NotNull final String baseUrl, @NotNull final UsergridAuthMode authMode) { + this.orgId = orgId; + this.appId = appId; + this.baseUrl = baseUrl; + this.authMode = authMode; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridEnums.java b/src/main/java/org/apache/usergrid/java/client/UsergridEnums.java new file mode 100644 index 0000000..4e2a8b0 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridEnums.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("unused") +public class UsergridEnums { + public enum UsergridAuthMode { + NONE, + USER, + APP + } + + public enum UsergridDirection { + IN("connecting"), + OUT("connections"); + + @NotNull private final String connectionValue; + + UsergridDirection(@NotNull final String connectionValue) { + this.connectionValue = connectionValue; + } + + @NotNull + public String connectionValue() { + return this.connectionValue; + } + } + + public enum UsergridHttpMethod { + GET, + PUT, + POST, + DELETE; + + @Nullable + public static UsergridHttpMethod fromString(@NotNull final String stringValue) { + try { + return UsergridHttpMethod.valueOf(stringValue.toUpperCase()); + } catch(Exception e) { + return null; + } + } + + @Override @NotNull + public String toString() { + return super.toString().toUpperCase(); + } + } + + public enum UsergridQueryOperator { + EQUAL("="), + GREATER_THAN(">"), + GREATER_THAN_EQUAL_TO(">="), + LESS_THAN("<"), + LESS_THAN_EQUAL_TO("<="); + + @NotNull private final String operatorValue; + + UsergridQueryOperator(@NotNull final String operatorValue) { + this.operatorValue = operatorValue; + } + + @NotNull + public String operatorValue() { + return this.operatorValue; + } + } + + public enum UsergridQuerySortOrder { + ASC, + DESC; + + @Nullable + public static UsergridQuerySortOrder fromString(@NotNull final String stringValue) { + try { + return UsergridQuerySortOrder.valueOf(stringValue.toUpperCase()); + } catch(Exception e) { + return null; + } + } + + @Override @NotNull + public String toString() { + return super.toString().toLowerCase(); + } + } + + public enum UsergridEntityProperties { + TYPE, + UUID, + NAME, + CREATED, + MODIFIED, + LOCATION; + + @Nullable + public static UsergridEntityProperties fromString(@NotNull final String stringValue) { + try { + return UsergridEntityProperties.valueOf(stringValue.toUpperCase()); + } catch(Exception e) { + return null; + } + } + + @Override @NotNull + public String toString() { + return super.toString().toLowerCase(); + } + + public boolean isMutableForEntity(@NotNull final UsergridEntity entity) { + switch(this) { + case LOCATION: { + return true; + } + case NAME: { + return entity.isUser(); + } + case TYPE: + case UUID: + case CREATED: + case MODIFIED: + default: { + return false; + } + } + } + } + + public enum UsergridUserProperties { + NAME, + USERNAME, + PASSWORD, + EMAIL, + ACTIVATED, + DISABLED, + PICTURE; + + @Nullable + public static UsergridUserProperties fromString(@NotNull final String stringValue) { + try { + return UsergridUserProperties.valueOf(stringValue.toUpperCase()); + } catch(Exception e) { + return null; + } + } + + @Override @NotNull + public String toString() { + return super.toString().toLowerCase(); + } + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java b/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java new file mode 100644 index 0000000..b16783e --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.apache.usergrid.java.client.UsergridEnums.UsergridHttpMethod; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@SuppressWarnings("unused") +public class UsergridRequest { + @NotNull public static final MediaType APPLICATION_JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8"); + + @NotNull private UsergridHttpMethod method; + @NotNull private String baseUrl; + @NotNull private MediaType contentType; + + @Nullable private UsergridQuery query; + @Nullable private Map headers; + @Nullable private Map parameters; + @Nullable private Object data; + @Nullable private UsergridAuth auth; + @Nullable private String[] pathSegments; + + @NotNull + public UsergridHttpMethod getMethod() { return method; } + public void setMethod(@NotNull final UsergridHttpMethod method) { this.method = method; } + + @NotNull + public String getBaseUrl() { return baseUrl; } + public void setBaseUrl(@NotNull final String baseUrl) { this.baseUrl = baseUrl; } + + @NotNull + public MediaType getContentType() { return contentType; } + public void setContentType(@NotNull final MediaType contentType) { this.contentType = contentType; } + + @Nullable + public UsergridQuery getQuery() { return query; } + public void setQuery(@Nullable final UsergridQuery query) { this.query = query; } + + @Nullable + public Map getHeaders() { return headers; } + public void setHeaders(@Nullable final Map headers) { this.headers = headers; } + + @Nullable + public Map getParameters() { return parameters; } + public void setParameters(@Nullable final Map parameters) { this.parameters = parameters; } + + @Nullable + public Object getData() { return data; } + public void setData(@Nullable final Object data) { this.data = data; } + + @Nullable + public UsergridAuth getAuth() { return auth; } + public void setAuth(@Nullable final UsergridAuth auth) { this.auth = auth; } + + @Nullable + public String[] getPathSegments() { return pathSegments; } + public void setPathSegments(@Nullable final String[] pathSegments) { this.pathSegments = pathSegments; } + + private UsergridRequest() {} + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final UsergridQuery query, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.query = query; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final Map params, + @Nullable final Object data, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.parameters = params; + this.data = data; + this.headers = null; + this.query = null; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final Map params, + @Nullable final Object data, + @Nullable final Map headers, + @Nullable final UsergridQuery query, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.parameters = params; + this.data = data; + this.headers = headers; + this.query = query; + this.auth = auth; + this.pathSegments = pathSegments; + } + + @NotNull + public Request buildRequest() { + Request.Builder requestBuilder = new Request.Builder(); + requestBuilder.url(this.constructUrl()); + this.addHeaders(requestBuilder); + requestBuilder.method(this.method.toString(),this.constructRequestBody()); + return requestBuilder.build(); + } + + @NotNull + protected HttpUrl constructUrl() { + String url = this.baseUrl; + if( this.query != null ) { + url += this.query.build(false); + } + HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); + if( this.pathSegments != null ) { + for( String path : this.pathSegments ) { + urlBuilder.addPathSegments(path); + } + } + if( this.parameters != null ) { + for (Map.Entry param : this.parameters.entrySet()) { + urlBuilder.addQueryParameter(param.getKey(),param.getValue().toString()); + } + } + return urlBuilder.build(); + } + + protected void addHeaders(@NotNull final Request.Builder requestBuilder) { + requestBuilder.addHeader("User-Agent", UsergridRequestManager.USERGRID_USER_AGENT); + if (this.auth != null ) { + String accessToken = this.auth.getAccessToken(); + if( accessToken != null ) { + requestBuilder.addHeader("Authorization", "Bearer " + accessToken); + } + } + if( this.headers != null ) { + for( Map.Entry header : this.headers.entrySet() ) { + requestBuilder.addHeader(header.getKey(),header.getValue().toString()); + } + } + } + + @Nullable + protected RequestBody constructRequestBody() { + RequestBody requestBody = null; + if (method == UsergridHttpMethod.POST || method == UsergridHttpMethod.PUT) { + String jsonString = ""; + if( this.data != null ) { + jsonString = JsonUtils.toJsonString(this.data); + } + requestBody = RequestBody.create(this.contentType,jsonString); + } + return requestBody; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java b/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java new file mode 100644 index 0000000..7099d42 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.apache.usergrid.java.client.UsergridEnums.UsergridHttpMethod; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.Map; + +import static org.apache.usergrid.java.client.utils.ObjectUtils.isEmpty; + +public class UsergridRequestManager { + + @NotNull public static String USERGRID_USER_AGENT = "usergrid-java/v" + Usergrid.UsergridSDKVersion; + + @NotNull private final UsergridClient usergridClient; + @NotNull private final OkHttpClient httpClient; + + public UsergridRequestManager(@NotNull final UsergridClient usergridClient) { + this.usergridClient = usergridClient; + this.httpClient = new OkHttpClient(); + } + + @NotNull + public UsergridResponse performRequest(@NotNull final UsergridRequest usergridRequest) { + Request request = usergridRequest.buildRequest(); + UsergridResponse usergridResponse; + try { + Response response = this.httpClient.newCall(request).execute(); + usergridResponse = UsergridResponse.fromResponse(this.usergridClient,usergridRequest,response); + } catch( IOException exception ) { + usergridResponse = UsergridResponse.fromException(this.usergridClient,exception); + } + return usergridResponse; + } + + @NotNull + private UsergridResponse authenticate(@NotNull final UsergridAuth auth) { + Map credentials = auth.credentialsMap(); + String url = this.usergridClient.clientAppUrl(); + if ( auth instanceof UsergridUserAuth){ + + UsergridUserAuth userAuth = (UsergridUserAuth) auth; + if( userAuth.isAdminUser()){ + + url = this.usergridClient.managementUrl(); + } + + } + + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, url, null, credentials, this.usergridClient.authForRequests(), "token"); + UsergridResponse response = performRequest(request); + if (!isEmpty(response.getAccessToken()) && !isEmpty(response.getExpires())) { + auth.setAccessToken(response.getAccessToken()); + auth.setExpiry(System.currentTimeMillis() + response.getExpires() - 5000); + } + return response; + } + + @NotNull + public UsergridResponse authenticateApp(@NotNull final UsergridAppAuth appAuth) { + return this.authenticate(appAuth); + } + + @NotNull + public UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth) { + UsergridResponse response = this.authenticate(userAuth); + UsergridUser responseUser = response.user(); + if ( response.ok() && responseUser != null) { + responseUser.setUserAuth(userAuth); + } + return response; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java new file mode 100644 index 0000000..a7ac64d --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridAppAuth extends UsergridAuth { + + @NotNull private String clientId; + @NotNull private String clientSecret; + + @NotNull public String getClientId() { return clientId; } + public void setClientId(@NotNull final String clientId) { this.clientId = clientId; } + + @NotNull private String getClientSecret() { return clientSecret; } + public void setClientSecret(@NotNull final String clientSecret) { this.clientSecret = clientSecret; } + + @NotNull + @Override + public HashMap credentialsMap() { + HashMap credentials = super.credentialsMap(); + credentials.put("grant_type", "client_credentials"); + credentials.put("client_id", this.clientId); + credentials.put("client_secret", this.clientSecret); + return credentials; + } + + public UsergridAppAuth() { + this("",""); + } + + public UsergridAppAuth(@JsonProperty("clientId") @NotNull final String clientId, @JsonProperty("clientSecret") @NotNull final String clientSecret) { + super(); + this.clientId = clientId; + this.clientSecret = clientSecret; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java new file mode 100644 index 0000000..1ed61da --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridAuth { + + @Nullable private String accessToken = null; + @Nullable private Long expiry = null; + private boolean usingToken = false; + private boolean isAdminUser = false; + + public UsergridAuth() { } + + public UsergridAuth(@JsonProperty("accessToken") @Nullable final String accessToken) { + this.usingToken = true; + setAccessToken(accessToken); + } + + public UsergridAuth(@JsonProperty("accessToken") @Nullable final String accessToken, @JsonProperty("expiry") @Nullable final Long expiry) { + this.usingToken = true; + setAccessToken(accessToken); + setExpiry(expiry); + } + + public void destroy() { + setAccessToken(null); + setExpiry(null); + } + + @Nullable public String getAccessToken() { return accessToken; } + public void setAccessToken(@Nullable final String accessToken) { + this.accessToken = accessToken; + } + + @Nullable public Long getExpiry() { return expiry; } + public void setExpiry(@Nullable final Long tokenExpiry) { this.expiry = tokenExpiry; } + + public boolean isValidToken() { return (hasToken() && !isExpired()); } + + public boolean hasToken() { return accessToken != null; } + + public boolean isExpired() { + if (expiry != null) { + Long currentTime = System.currentTimeMillis() / 1000; + return ((expiry / 1000) < currentTime); + } else { + return !this.usingToken; + } + } + + @NotNull + public HashMap credentialsMap() { + return new HashMap<>(); + } +} \ No newline at end of file diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java new file mode 100644 index 0000000..7cb42ad --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridUserAuth extends UsergridAuth { + + @NotNull private String username; + @NotNull private String password; + private boolean isAdminUser = false; + + @NotNull public String getUsername() { return username; } + public void setUsername(@NotNull final String username) { this.username = username; } + + @NotNull private String getPassword() { return password; } + public void setPassword(@NotNull final String password) { this.password = password; } + + public boolean isAdminUser() { return isAdminUser; } + + @NotNull + @Override + public HashMap credentialsMap() { + HashMap credentials = super.credentialsMap(); + credentials.put("grant_type", "password"); + credentials.put("username", this.username); + credentials.put("password", this.password); + return credentials; + } + + public UsergridUserAuth() { + this("",""); + } + + public UsergridUserAuth(@JsonProperty("username") @NotNull final String username, + @JsonProperty("password") @NotNull final String password) { + super(); + this.username = username; + this.password = password; + } + + public UsergridUserAuth(@JsonProperty("username") @NotNull final String username, + @JsonProperty("password") @NotNull final String password, + @JsonProperty("isAdminUser") final boolean isAdminUser) { + super(); + this.username = username; + this.password = password; + this.isAdminUser = isAdminUser; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java b/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java new file mode 100644 index 0000000..ff30a0d --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.exception; + +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public class UsergridException extends RuntimeException { + + private int responseCode; + + public int getResponseCode() { + return responseCode; + } + public void setResponseCode(final int responseCode) { this.responseCode = responseCode; } + + private UsergridException() {} + + public UsergridException(@NotNull final String message) { + super(message); + } + + public UsergridException(@NotNull final String message, @NotNull final Throwable cause) { + super(message, cause); + } + + public UsergridException(@NotNull final String message, final int responseCode) { + super(message); + this.responseCode = responseCode; + } + + public UsergridException(@NotNull final String message, @NotNull final Throwable cause, final int responseCode) { + super(message, cause); + this.responseCode = responseCode; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java new file mode 100644 index 0000000..1833afb --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java @@ -0,0 +1,60 @@ +package org.apache.usergrid.java.client.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@SuppressWarnings("unused") +public class UsergridDevice extends UsergridEntity { + @NotNull public static String DEVICE_ENTITY_TYPE = "device"; + + @Nullable private String model; + @Nullable private String platform; + @Nullable private String osVersion; + + public UsergridDevice() { + super(DEVICE_ENTITY_TYPE); + } + + public UsergridDevice(@Nullable final String name) { + super(DEVICE_ENTITY_TYPE,name); + } + + public UsergridDevice(@NotNull final Map properties) { + super(DEVICE_ENTITY_TYPE,null,properties); + } + + public UsergridDevice(@Nullable final String name, @NotNull final Map properties) { + super(DEVICE_ENTITY_TYPE,name,properties); + } + + @Nullable @JsonProperty("deviceModel") + public String getModel() { + return this.model; + } + @JsonProperty("deviceModel") + public void setModel(@Nullable final String model) { + this.model = model; + } + + @Nullable @JsonProperty("devicePlatform") + public String getPlatform() { + return this.platform; + } + @JsonProperty("devicePlatform") + public void setPlatform(@Nullable final String platform) { + this.platform = platform; + } + + @Nullable @JsonProperty("deviceOSVersion") + public String getOsVersion() { + return this.osVersion; + } + @JsonProperty("deviceOSVersion") + public void setOsVersion(@Nullable final String osVersion) { + this.osVersion = osVersion; + } +} \ No newline at end of file diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java new file mode 100644 index 0000000..3444de0 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java @@ -0,0 +1,487 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.model; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.node.*; +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.*; + +import static org.apache.usergrid.java.client.utils.JsonUtils.*; + +@SuppressWarnings("unused") +public class UsergridEntity { + + @NotNull private static final HashMap> subclassMappings = new HashMap<>(); + @NotNull private static final ObjectMapper entityUpdateMapper = new ObjectMapper(); + @NotNull private final ObjectReader entityUpdateReader = entityUpdateMapper.readerForUpdating(this); + + static { + subclassMappings.put("user",UsergridUser.class); + subclassMappings.put("device",UsergridDevice.class); + } + + @NotNull private String type; + @Nullable private String uuid; + @Nullable private String name; + @Nullable private Long created; + @Nullable private Long modified; + + @NotNull private Map properties = new HashMap<>(); + + public UsergridEntity(@JsonProperty("type") @NotNull final String type) { + this.type = type; + } + + public UsergridEntity(@NotNull final String type, @Nullable final String name) { + this(type); + if( name != null ) { + this.name = name; + } + } + + public UsergridEntity(@NotNull final String type, @Nullable final String name, @NotNull final Map properties) { + this(type,name); + this.updatePropertiesWithMap(properties); + } + + @Nullable + public static Class customSubclassForType(@NotNull final String type) { + return UsergridEntity.subclassMappings.get(type); + } + + public void copyAllProperties(@NotNull final UsergridEntity fromEntity) { + try { + this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(fromEntity)); + } catch( IllegalArgumentException e ) { System.out.print("Usergrid Error: Unable to update properties from entity - " + fromEntity.toString()); } + } + + public void updatePropertiesWithMap(@NotNull final Map properties) { + try { + this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(properties)); + } catch( IllegalArgumentException e ) { System.out.print("Usergrid Error: Unable to update properties from map - " + properties.toString()); } + } + + public void updatePropertiesWithJsonNode(@NotNull final JsonNode node) { + try { + entityUpdateReader.readValue(node); + } catch( IOException e ) { System.out.print("Usergrid Error: Unable to update properties from jsonNode - " + node.toString()); } + } + + public static void mapCustomSubclassToType(@NotNull final String type, @NotNull final Class subclass) { + UsergridEntity.subclassMappings.put(type,subclass); + } + + @NotNull @Override public String toString() { + return toJsonString(this); + } + @NotNull public String toPrettyString() { return toPrettyJsonString(this); } + @NotNull public JsonNode toJsonObjectValue() { + return toJsonNode(this); + } + @SuppressWarnings("unchecked") + @NotNull public Map toMapValue() { return toMap(this); } + + @JsonIgnore + public boolean isUser() { return (this instanceof UsergridUser || this.getType().equalsIgnoreCase(UsergridUser.USER_ENTITY_TYPE)); } + + @NotNull public String getType() { return this.type; } + private void setType(@NotNull final String type) { this.type = type; } + + @Nullable public String getUuid() { return this.uuid; } + private void setUuid(@NotNull final String uuid) { this.uuid = uuid; } + + @Nullable public String getName() { return this.name; } + protected void setName(@Nullable final String name) { this.name = name; } + + @Nullable public Long getCreated() { return this.created; } + private void setCreated(@NotNull final Long created) { this.created = created; } + + @Nullable public Long getModified() { return this.modified; } + private void setModified(@NotNull final Long modified) { this.modified = modified; } + + public void setLocation(final double latitude, final double longitude) { + ObjectNode rootNode = JsonUtils.createObjectNode(); + rootNode.put("latitude", latitude); + rootNode.put("longitude", longitude); + setObjectProperty(this.properties, "location", rootNode); + } + + @Nullable + public String uuidOrName() { + String uuidOrName = this.getUuid(); + if( uuidOrName == null ) { + uuidOrName = this.getName(); + } + return uuidOrName; + } + + @NotNull + public UsergridResponse reload() { + return this.reload(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse reload(@NotNull final UsergridClient client) { + String uuidOrName = this.uuidOrName(); + if( uuidOrName == null ) { + return UsergridResponse.fromError(client, "No UUID or name found.", "The entity object must have a `uuid` or `name` assigned."); + } + UsergridResponse response = client.GET(this.getType(), uuidOrName); + if( response.ok() ) { + UsergridEntity responseEntity = response.first(); + if( responseEntity != null ) { + this.copyAllProperties(responseEntity); + } + } + return response; + } + + @NotNull + public UsergridResponse save() { + return this.save(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse save(@NotNull final UsergridClient client) { + UsergridResponse response; + if( this.getUuid() != null ) { + response = client.PUT(this); + } else { + response = client.POST(this); + } + if( response.ok() ) { + UsergridEntity responseEntity = response.first(); + if( responseEntity != null ) { + this.copyAllProperties(responseEntity); + } + } + return response; + } + + @NotNull + public UsergridResponse remove() { + return this.remove(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse remove(@NotNull final UsergridClient client) { + return client.DELETE(this); + } + + @NotNull + public UsergridResponse connect(@NotNull final String relationship, @NotNull final UsergridEntity toEntity) { + return this.connect(Usergrid.getInstance(), relationship, toEntity); + } + + @NotNull + public UsergridResponse connect(@NotNull final UsergridClient client, @NotNull final String relationship, @NotNull final UsergridEntity toEntity) { + return client.connect(this,relationship,toEntity); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final String relationship, @NotNull final UsergridEntity fromEntity) { + return this.disconnect(Usergrid.getInstance(), relationship, fromEntity); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final UsergridClient client, @NotNull final String relationship, @NotNull final UsergridEntity fromEntity) { + return client.disconnect(this,relationship,fromEntity); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String relationship) { + return this.getConnections(Usergrid.getInstance(),direction,relationship); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridClient client, @NotNull final UsergridDirection direction, @NotNull final String relationship) { + return client.getConnections(direction,this,relationship); + } + + public void removeProperty(@NotNull final String name) { + putProperty(name, NullNode.getInstance()); + } + + public void removeProperties(@NotNull final List names) { + for( String propertyName : names ) { + this.removeProperty(propertyName); + } + } + + public void putProperty(@NotNull final String name, @NotNull final String value) { + this.putProperty(name, JsonNodeFactory.instance.textNode(value)); + } + public void putProperty(@NotNull final String name, final boolean value) { + this.putProperty(name, JsonNodeFactory.instance.booleanNode(value)); + } + public void putProperty(@NotNull final String name, @NotNull final List value) { + this.putProperty(name, JsonNodeFactory.instance.pojoNode(value)); + } + public void putProperty(@NotNull final String name, final int value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, final long value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, final float value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, @Nullable final JsonNode value) { + UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(name); + if( entityProperty != null && !entityProperty.isMutableForEntity(this)) { + return; + } + + JsonNode valueNode = value; + if( valueNode == null ) { + valueNode = NullNode.getInstance(); + } + this.updatePropertiesWithMap(Collections.singletonMap(name,valueNode)); + } + public void putProperties(@NotNull final String jsonString) { + try { + JsonNode jsonNode = entityUpdateMapper.readTree(jsonString); + this.putProperties(jsonNode); + } catch( Exception ignore ) {} + } + public void putProperties(@NotNull final Map properties) { + try { + JsonNode jsonNode = entityUpdateMapper.valueToTree(properties); + this.putProperties(jsonNode); + } catch( Exception ignore ) {} + } + public void putProperties(@NotNull final JsonNode jsonNode) { + HashMap propertiesToUpdate = new HashMap<>(); + Iterator> keys = jsonNode.fields(); + while (keys.hasNext()) { + Map.Entry entry = keys.next(); + String key = entry.getKey(); + UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(key); + if( entityProperty == null || entityProperty.isMutableForEntity(this) ) { + propertiesToUpdate.put(key,entry.getValue()); + } + } + if( !propertiesToUpdate.isEmpty() ) { + this.updatePropertiesWithMap(propertiesToUpdate); + } + } + + @SuppressWarnings("unchecked") + public void append(@NotNull final String name, @NotNull final Object value) { + this.append(name, (value instanceof List) ? (List) value : Collections.singletonList(value)); + } + + public void append(@NotNull final String name, @NotNull final List value) { + this.insert(name, value, Integer.MAX_VALUE); + } + + @SuppressWarnings("unchecked") + public void insert(@NotNull final String name, @NotNull final Object value) { + this.insert(name, (value instanceof List) ? (List) value : Collections.singletonList(value), 0); + } + + @SuppressWarnings("unchecked") + public void insert(@NotNull final String name, @NotNull final Object value, final int index) { + this.insert(name, (value instanceof List) ? (List) value : Collections.singletonList(value), index); + } + + public void insert(@NotNull final String name, @NotNull final List value) { + this.insert(name,value,0); + } + + public void insert(@NotNull final String name, @NotNull final List value, final int index) { + int indexToInsert = index; + if (indexToInsert < 0) { + indexToInsert = 0; + } + Object propertyValue = this.getEntityProperty(name); + if( propertyValue != null ) { + ArrayList propertyArrayValue = this.convertToList(propertyValue); + propertyArrayValue = this.insertIntoArray(propertyArrayValue,value,indexToInsert); + this.putProperty(name, propertyArrayValue); + } else { + this.putProperty(name, value); + } + } + + public void pop(@NotNull final String name) { + ArrayList arrayToPop = this.getArrayToPopOrShift(name); + if( arrayToPop != null && !arrayToPop.isEmpty() ) { + arrayToPop.remove(arrayToPop.size() - 1); + this.putProperty(name, arrayToPop); + } + } + + public void shift(@NotNull final String name) { + ArrayList arrayToShift = this.getArrayToPopOrShift(name); + if( arrayToShift != null && !arrayToShift.isEmpty() ) { + arrayToShift.remove(0); + this.putProperty(name, arrayToShift); + } + } + + @Nullable + public T getEntityProperty(@NotNull final String name) { + return JsonUtils.getProperty(this.properties, name); + } + + @Nullable + public JsonNode getJsonNodeProperty(@NotNull final String name) { + return this.getProperties().get(name); + } + + @Nullable + public String getStringProperty(@NotNull final String name) { + return JsonUtils.getStringProperty(this.getProperties(), name); + } + + @Nullable + public Boolean getBooleanProperty(@NotNull final String name) { + Boolean booleanValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Boolean ) { + booleanValue = (Boolean)object; + } + return booleanValue; + } + + @Nullable + public Number getNumberProperty(@NotNull final String name) { + Number numberValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + numberValue = (Number)object; + } + return numberValue; + } + + @Nullable + public Integer getIntegerProperty(@NotNull final String name) { + Integer integerValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + integerValue = ((Number)object).intValue(); + } + return integerValue; + } + + @Nullable + public Float getFloatProperty(@NotNull final String name) { + Float floatValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + floatValue = ((Number)object).floatValue(); + } + return floatValue; + } + + @Nullable + public Long getLongProperty(@NotNull final String name) { + Long longValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + longValue = ((Number)object).longValue(); + } + return longValue; + } + + @JsonAnyGetter @NotNull + public Map getProperties() { + return this.properties; + } + + @JsonAnySetter + private void internalPutProperty(@NotNull final String name, @Nullable final JsonNode value) { + if (value == null) { + properties.put(name, NullNode.instance); + } else { + properties.put(name, value); + } + } + + @Nullable + @SuppressWarnings("unchecked") + private ArrayList getArrayToPopOrShift(@NotNull final String name) { + Object entityProperty = getEntityProperty(name); + ArrayList arrayToPopOrShift = null; + if (entityProperty instanceof POJONode) { + Object objectValue = ((POJONode) entityProperty).getPojo(); + if (objectValue instanceof List) { + arrayToPopOrShift = new ArrayList<>((List) objectValue); + } else { + arrayToPopOrShift = new ArrayList<>(); + arrayToPopOrShift.add(objectValue); + } + } else if( entityProperty instanceof ArrayNode ) { + arrayToPopOrShift = JsonUtils.convertToArrayList((ArrayNode)entityProperty); + } else if( entityProperty instanceof List ) { + arrayToPopOrShift = new ArrayList<>((List) entityProperty); + } + return arrayToPopOrShift; + } + + @NotNull + private ArrayList convertToList(@NotNull final Object value) { + ArrayList arrayList = new ArrayList<>(); + if( value instanceof ArrayNode ) { + arrayList = JsonUtils.convertToArrayList((ArrayNode)value); + } else if (value instanceof POJONode) { + Object objectValue = ((POJONode) value).getPojo(); + if( objectValue instanceof List ) { + arrayList.addAll((List)objectValue); + } else { + arrayList.add(objectValue); + } + } else if (value instanceof List) { + arrayList.addAll((List)value); + } else { + arrayList.add(value); + } + return arrayList; + } + + @NotNull + private ArrayList insertIntoArray(@NotNull final List propertyArrayNode, @NotNull final List arrayToInsert, final int index) { + ArrayList mergedArray = new ArrayList<>(); + if (propertyArrayNode.size() <= 0 || arrayToInsert.isEmpty()) { + mergedArray.addAll(arrayToInsert); + } else if ( index <= 0 ) { + mergedArray.addAll(arrayToInsert); + mergedArray.addAll(propertyArrayNode); + } else if ( index > 0 ) { + mergedArray.addAll(propertyArrayNode); + if ( index > propertyArrayNode.size() ) { + mergedArray.addAll(arrayToInsert); + } else { + mergedArray.addAll(index,arrayToInsert); + } + } + return mergedArray; + } +} \ No newline at end of file diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java new file mode 100644 index 0000000..f967e46 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridUser extends UsergridEntity { + @NotNull public final static String USER_ENTITY_TYPE = "user"; + + @Nullable private UsergridUserAuth userAuth = null; + + @Nullable private String username; + @Nullable private String email; + @Nullable private String password; + @Nullable private String picture; + + private boolean activated = false; + private boolean disabled = false; + + public UsergridUser() { + super(USER_ENTITY_TYPE); + } + + public UsergridUser(@NotNull final String username, @Nullable final String password) { + super(USER_ENTITY_TYPE); + setUsername(username); + setPassword(password); + } + + public UsergridUser(@NotNull final String name, @NotNull final HashMap propertyMap) { + super(USER_ENTITY_TYPE,name); + putProperties(propertyMap); + } + + public UsergridUser(@Nullable final String name, @Nullable final String username, @Nullable final String email, @Nullable final String password) { + super(USER_ENTITY_TYPE,name); + setUsername(username); + setEmail(email); + setPassword(password); + } + + public void setName(@Nullable final String name) { super.setName(name); } + + @Nullable public String getUsername() { return this.username; } + public void setUsername(@Nullable final String username) { this.username = username; } + + @Nullable public String getEmail() { return this.email; } + public void setEmail(@Nullable final String email) { this.email = email; } + + @Nullable public String getPassword() { return this.password; } + public void setPassword(@Nullable final String password) { this.password = password; } + + @Nullable public String getPicture() { return this.picture; } + public void setPicture(@Nullable final String picture) { this.picture = picture; } + + public boolean isActivated() { return this.activated; } + public void setActivated(final boolean activated) { this.activated = activated; } + + public boolean isDisabled() { return this.disabled; } + public void setDisabled(final boolean disabled) { this.disabled = disabled; } + + @JsonIgnore @Nullable public UsergridUserAuth getUserAuth() { return this.userAuth; } + @JsonIgnore public void setUserAuth(@Nullable final UsergridUserAuth userAuth) { this.userAuth = userAuth; } + + @Nullable + public String uuidOrUsername() { + String uuidOrUsername = this.getUuid(); + if( uuidOrUsername == null ) { + uuidOrUsername = this.getUsername(); + } + return uuidOrUsername; + } + + @Nullable + public String usernameOrEmail() { + String usernameOrEmail = this.getUsername(); + if( usernameOrEmail == null ) { + usernameOrEmail = this.getEmail(); + } + return usernameOrEmail; + } + + public static boolean checkAvailable(@Nullable final String email, @Nullable final String username) { + return UsergridUser.checkAvailable(Usergrid.getInstance(), email, username); + } + + public static boolean checkAvailable(@NotNull final UsergridClient client, @Nullable final String email, @Nullable final String username) { + if (email == null && username == null) { + throw new IllegalArgumentException("email and username both are null "); + } + UsergridQuery query = new UsergridQuery(USER_ENTITY_TYPE); + if (username != null) { + query.eq(UsergridUserProperties.USERNAME.toString(), username); + } + if (email != null) { + query.or().eq(UsergridUserProperties.EMAIL.toString(), email); + } + return client.GET(query).first() != null; + } + + @NotNull + public UsergridResponse create() { + return this.create(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse create(@NotNull final UsergridClient client) { + UsergridResponse response = client.POST(this); + UsergridUser createdUser = response.user(); + if( createdUser != null ) { + this.copyAllProperties(createdUser); + } + return response; + } + + @NotNull + public UsergridResponse login(@NotNull final String username, @NotNull final String password) { + return this.login(Usergrid.getInstance(),username,password); + } + + @NotNull + public UsergridResponse login(@NotNull final UsergridClient client, @NotNull final String username, @NotNull final String password) { + UsergridUserAuth userAuth = new UsergridUserAuth(username,password); + UsergridResponse response = client.authenticateUser(userAuth,false); + if( response.ok() ) { + this.userAuth = userAuth; + } + return response; + } + + @NotNull + public UsergridResponse resetPassword(@NotNull final String oldPassword, @NotNull final String newPassword) { + return this.resetPassword(Usergrid.getInstance(),oldPassword,newPassword); + } + + @NotNull + public UsergridResponse resetPassword(@NotNull final UsergridClient client, @NotNull final String oldPassword, @NotNull final String newPassword) { + return client.resetPassword(this,oldPassword,newPassword); + } + + @NotNull + public UsergridResponse reauthenticate() { + return this.reauthenticate(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse reauthenticate(@NotNull final UsergridClient client) { + return this.userAuth == null ? UsergridResponse.fromError(client, "Invalid UsergridUserAuth.", "No UsergridUserAuth found on the UsergridUser.") : client.authenticateUser(this.userAuth, false); + } + + @NotNull + public UsergridResponse logout() { + return this.logout(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse logout(@NotNull final UsergridClient client) { + UsergridResponse response; + String uuidOrUsername = this.uuidOrUsername(); + String accessToken = (this.userAuth != null) ? this.userAuth.getAccessToken() : null; + if (uuidOrUsername == null || accessToken == null ) { + response = UsergridResponse.fromError(client, "Logout Failed.", "UUID or Access Token not found on UsergridUser object."); + } else { + response = client.logoutUser(uuidOrUsername, accessToken); + if( response.ok() ) { + this.userAuth = null; + } + } + return response; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java b/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java new file mode 100644 index 0000000..e8c78c2 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java @@ -0,0 +1,431 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.query; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridQueryOperator; +import org.apache.usergrid.java.client.UsergridEnums.UsergridQuerySortOrder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.net.URLEncoder; +import java.util.*; + +@SuppressWarnings("unused") +public final class UsergridQuery { + + @NotNull private final ArrayList requirementStrings = new ArrayList<>(); + @NotNull private final ArrayList urlTerms = new ArrayList<>(); + @NotNull private final HashMap orderClauses = new HashMap<>(); + @NotNull private Integer limit = UsergridQuery.LIMIT_DEFAULT; + @Nullable private String cursor = null; + @Nullable private String fromStringValue = null; + @Nullable private String collectionName = null; + + public UsergridQuery() { + this(null); + } + + public UsergridQuery(@Nullable final String collectionName) { + this.collectionName = collectionName; + this.requirementStrings.add(UsergridQuery.EMPTY_STRING); + } + + private static boolean isUUID(@NotNull final String string) { + try { + UUID uuid = UUID.fromString(string); + return true; + } catch (Exception ex) { + return false; + } + } + + @NotNull + private static String encode(@NotNull final String stringValue) { + String escapedString; + try { + escapedString = URLEncoder.encode(stringValue, UTF8); + } catch (Exception e) { + escapedString = stringValue; + } + return escapedString; + } + + @NotNull + public static String strJoin(@NotNull final List array, @NotNull final String separator) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0, il = array.size(); i < il; i++) { + if (i > 0) { + stringBuilder.append(separator); + } + stringBuilder.append(array.get(i)); + } + return stringBuilder.toString(); + } + + @NotNull + public UsergridQuery fromString(@NotNull final String stringValue) { + this.fromStringValue = stringValue; + return this; + } + + @Nullable + public String getType() { + return this.collectionName; + } + + @Nullable + public String getCollectionName() { + return this.collectionName; + } + + @Nullable + public String getCollection() { + return this.collectionName; + } + + @NotNull + public UsergridQuery type(@Nullable final String type) { + this.collectionName = type; + return this; + } + + @NotNull + public UsergridQuery collection(@Nullable final String collectionName) { + return this.type(collectionName); + } + + @NotNull + public UsergridQuery collectionName(@Nullable final String collectionName) { + return this.type(collectionName); + } + + @NotNull + public UsergridQuery cursor(@Nullable final String value) { + this.cursor = value; + return this; + } + + @NotNull + public UsergridQuery limit(@NotNull final Integer limit) { + this.limit = limit; + return this; + } + + @NotNull + private UsergridQuery addConditionalSeparator(@NotNull final String separator) { + if (!this.requirementStrings.get(0).isEmpty()) { + this.requirementStrings.add(0, separator); + this.requirementStrings.add(0, UsergridQuery.EMPTY_STRING); + } + return this; + } + + @NotNull + public UsergridQuery and() { + return this.addConditionalSeparator(UsergridQuery.AND); + } + + @NotNull + public UsergridQuery or() { + return this.addConditionalSeparator(UsergridQuery.OR); + } + + @NotNull + public UsergridQuery not() { + return this.addConditionalSeparator(UsergridQuery.NOT); + } + + @NotNull + public UsergridQuery sort(@NotNull final String term, @NotNull final UsergridQuerySortOrder sortOrder) { + this.orderClauses.put(term, sortOrder); + return this; + } + + @NotNull + public UsergridQuery ascending(@NotNull final String term) { + return this.asc(term); + } + + @NotNull + public UsergridQuery asc(@NotNull final String term) { + return this.sort(term, UsergridQuerySortOrder.ASC); + } + + @NotNull + public UsergridQuery descending(@NotNull final String term) { + return this.desc(term); + } + + @NotNull + public UsergridQuery desc(@NotNull final String term) { + return this.sort(term, UsergridQuerySortOrder.DESC); + } + + @NotNull + public UsergridQuery contains(@NotNull final String term, @NotNull final String value) { + return this.containsWord(term, value); + } + + @NotNull + public UsergridQuery containsString(@NotNull final String term, @NotNull final String value) { + return this.containsWord(term, value); + } + + @NotNull + public UsergridQuery containsWord(@NotNull final String term, @NotNull final String value) { + return this.addRequirement(term + SPACE + CONTAINS + SPACE + ((UsergridQuery.isUUID(value)) ? EMPTY_STRING : APOSTROPHE) + value + ((UsergridQuery.isUUID(value)) ? EMPTY_STRING : APOSTROPHE)); + } + + @NotNull + public UsergridQuery filter(@NotNull final String term, @NotNull final Object value) { + return this.eq(term, value); + } + + @NotNull + public UsergridQuery equals(@NotNull final String term, @NotNull final Object value) { + return this.eq(term, value); + } + + @NotNull + public UsergridQuery eq(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.EQUAL, value); + } + + @NotNull + public UsergridQuery greaterThan(@NotNull final String term, @NotNull final Object value) { + return this.gt(term, value); + } + + @NotNull + public UsergridQuery gt(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.GREATER_THAN, value); + } + + @NotNull + public UsergridQuery greaterThanOrEqual(@NotNull final String term, @NotNull final Object value) { + return this.gte(term, value); + } + + @NotNull + public UsergridQuery gte(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.GREATER_THAN_EQUAL_TO, value); + } + + @NotNull + public UsergridQuery lessThan(@NotNull final String term, @NotNull final Object value) { + return this.lt(term, value); + } + + @NotNull + public UsergridQuery lt(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.LESS_THAN, value); + } + + @NotNull + public UsergridQuery lessThanOrEqual(@NotNull final String term, @NotNull final Object value) { + return this.lte(term, value); + } + + @NotNull + public UsergridQuery lte(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.LESS_THAN_EQUAL_TO, value); + } + + @NotNull + public UsergridQuery locationWithin(final double distance, final double latitude, final double longitude) { + return this.addRequirement(LOCATION + SPACE + WITHIN + SPACE + distance + SPACE + OF + SPACE + latitude + SPACE + COMMA + longitude); + } + + @NotNull + public UsergridQuery urlTerm(@NotNull final String term, @NotNull final String equalsValue) { + if (term.equalsIgnoreCase(QL)) { + this.ql(equalsValue); + } else { + this.urlTerms.add(UsergridQuery.encode(term) + EQUALS + UsergridQuery.encode(equalsValue)); + } + return this; + } + + @NotNull + public UsergridQuery ql(final String value) { + + return value != null && !value.isEmpty() ? this.addRequirement(value) : this; + + } + + @NotNull + public UsergridQuery addRequirement(@NotNull final String requirement) { + String requirementString = this.requirementStrings.remove(0); + if (!requirement.isEmpty() && !requirementString.isEmpty()) { + requirementString += SPACE + AND + SPACE; + } + requirementString += requirement; + this.requirementStrings.add(0, requirementString); + return this; + } + + @NotNull + public UsergridQuery addOperationRequirement(@NotNull final String term, @NotNull final UsergridQueryOperator operation, final int intValue) { + return this.addOperationRequirement(term, operation, Integer.valueOf(intValue)); + } + + @NotNull + public UsergridQuery addOperationRequirement(@NotNull final String term, @NotNull final UsergridQueryOperator operation, @NotNull final Object value) { + if (value instanceof String) { + String valueString = value.toString(); + if (!UsergridQuery.isUUID(valueString)) { + valueString = APOSTROPHE + value + APOSTROPHE; + } + return addRequirement(term + SPACE + operation.operatorValue() + SPACE + valueString); + } else { + return addRequirement(term + SPACE + operation.operatorValue() + SPACE + value.toString()); + } + } + + @NotNull + private String constructOrderByString() { + String orderByString = EMPTY_STRING; + if (!this.orderClauses.isEmpty()) { + for (Map.Entry orderClause : this.orderClauses.entrySet()) { + if (!orderByString.isEmpty()) { + orderByString += COMMA; + } + orderByString += orderClause.getKey() + SPACE + orderClause.getValue().toString(); + } + if (!orderByString.isEmpty()) { + orderByString = SPACE + ORDER_BY + SPACE + orderByString; + } + } + return orderByString; + } + + @NotNull + private String constructURLTermsString() { + String urlTermsString = EMPTY_STRING; + if (!this.urlTerms.isEmpty()) { + urlTermsString = UsergridQuery.strJoin(this.urlTerms, AMPERSAND); + } + return urlTermsString; + } + + @NotNull + private String constructRequirementString() { + ArrayList requirementStrings = new ArrayList<>(this.requirementStrings); + String firstString = requirementStrings.get(0); + if (firstString.isEmpty()) { + requirementStrings.remove(0); + } + String requirementsString = EMPTY_STRING; + if (!requirementStrings.isEmpty()) { + firstString = requirementStrings.get(0); + if (firstString.equalsIgnoreCase(OR) || firstString.equalsIgnoreCase(AND) || firstString.equalsIgnoreCase(NOT)) { + requirementStrings.remove(0); + } + if (!requirementStrings.isEmpty()) { + Collections.reverse(requirementStrings); + requirementsString = UsergridQuery.strJoin(requirementStrings, SPACE); + } + } + return requirementsString; + } + + @NotNull + private String constructURLAppend() { + return this.constructURLAppend(true); + } + + @NotNull + private String constructURLAppend(final boolean autoURLEncode) { + if (this.fromStringValue != null) { + String requirementsString = this.fromStringValue; + if (autoURLEncode) { + requirementsString = UsergridQuery.encode(requirementsString); + } + return QUESTION_MARK + QL + EQUALS + requirementsString; + } + String urlAppend = EMPTY_STRING; + if (this.limit != LIMIT_DEFAULT) { + urlAppend += LIMIT + EQUALS + this.limit.toString(); + } + String urlTermsString = this.constructURLTermsString(); + if (!urlTermsString.isEmpty()) { + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += urlTermsString; + } + if (this.cursor != null && !this.cursor.isEmpty()) { + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += CURSOR + EQUALS + this.cursor; + } + + String requirementsString = this.constructRequirementString(); + + String orderByString = this.constructOrderByString(); + if (!orderByString.isEmpty()) { + requirementsString += orderByString; + } + if (!requirementsString.isEmpty()) { + if (autoURLEncode) { + requirementsString = UsergridQuery.encode(requirementsString); + } + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += QL + EQUALS + requirementsString; + } + if (!urlAppend.isEmpty()) { + urlAppend = QUESTION_MARK + urlAppend; + } + return urlAppend; + } + + @NotNull + public String build() { + return this.build(true); + } + + @NotNull + public String build(final boolean autoURLEncode) { + return this.constructURLAppend(autoURLEncode); + } + + private static final int LIMIT_DEFAULT = 10; + @NotNull private static final String AMPERSAND = "&"; + @NotNull private static final String AND = "and"; + @NotNull private static final String APOSTROPHE = "'"; + @NotNull private static final String COMMA = ","; + @NotNull private static final String CONTAINS = "contains"; + @NotNull private static final String CURSOR = "cursor"; + @NotNull private static final String EMPTY_STRING = ""; + @NotNull private static final String EQUALS = "="; + @NotNull private static final String LIMIT = "limit"; + @NotNull private static final String LOCATION = "location"; + @NotNull private static final String NOT = "not"; + @NotNull private static final String OF = "of"; + @NotNull private static final String OR = "or"; + @NotNull private static final String ORDER_BY = "order by"; + @NotNull private static final String QL = "ql"; + @NotNull private static final String QUESTION_MARK = "?"; + @NotNull private static final String SELECT_ALL = "select *"; + @NotNull private static final String SPACE = " "; + @NotNull private static final String UTF8 = "UTF-8"; + @NotNull private static final String WHERE = "where"; + @NotNull private static final String WITHIN = "within"; +} diff --git a/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java new file mode 100644 index 0000000..ee649c4 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.response; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.JsonNode; +import okhttp3.Headers; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.UsergridEnums; +import org.apache.usergrid.java.client.UsergridRequest; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +import static org.apache.usergrid.java.client.utils.JsonUtils.toJsonString; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridResponse { + + @Nullable private UsergridClient client; + @NotNull private Map properties = new HashMap<>(); + + private int statusCode = 0; + @Nullable private JsonNode responseJson = null; + @Nullable private String cursor; + @Nullable private List entities; + @Nullable private Map headers; + @Nullable private UsergridQuery query; + @Nullable private UsergridResponseError responseError = null; + + @Nullable private String accessToken; + @Nullable private Long expires; + + public boolean ok() { return (statusCode > 0 && statusCode < 400); } + public int count() { return (entities == null) ? 0 : entities.size(); } + public boolean hasNextPage() { return (cursor != null); } + @NotNull @Override public String toString() { + return toJsonString(this); + } + + @Nullable public UsergridEntity first() { return (entities == null || entities.isEmpty()) ? null : entities.get(0); } + @Nullable public UsergridEntity entity() { + return first(); + } + @Nullable public UsergridEntity last() { return (entities == null || entities.isEmpty()) ? null : entities.get(entities.size() - 1); } + + @Nullable + public UsergridUser user() { + UsergridEntity entity = this.first(); + if( entity != null && entity instanceof UsergridUser ) { + return (UsergridUser) entity; + } + return null; + } + + @Nullable + public List users() { + ArrayList users = null; + if( entities != null && !entities.isEmpty() ) { + for( UsergridEntity entity : entities ) { + if( entity instanceof UsergridUser ) { + if( users == null ) { + users = new ArrayList<>(); + } + users.add((UsergridUser)entity); + } + } + } + return users; + } + + public int getStatusCode() { return this.statusCode; } + + @Nullable @JsonIgnore + public UsergridClient getClient() { + return client; + } + @JsonIgnore public void setClient(@Nullable final UsergridClient client) { this.client = client; } + + @Nullable @JsonIgnore + public JsonNode getResponseJson() { + return responseJson; + } + private void setResponseJson(@Nullable final JsonNode responseJson) {this.responseJson = responseJson; } + + @Nullable @JsonIgnore + public UsergridQuery getQuery() { + return query; + } + private void setQuery(@Nullable final UsergridQuery query) { this.query = query; } + + @Nullable + public UsergridResponseError getResponseError() { + return responseError; + } + private void setResponseError(@Nullable final UsergridResponseError responseError) { this.responseError = responseError; } + + @Nullable + public Map getHeaders() { + return headers; + } + private void setHeaders(@Nullable final Map headers) { this.headers = headers; } + + @Nullable + public List getEntities() { return entities; } + private void setEntities(@NotNull final List entities) { this.entities = entities; } + + @Nullable @JsonProperty("cursor") + public String getCursor() { + return cursor; + } + @JsonProperty("cursor") + private void setCursor(@NotNull final String cursor) { this.cursor = cursor; } + + @Nullable @JsonProperty("access_token") + public String getAccessToken() { return this.accessToken; } + @JsonProperty("access_token") + private void setAccessToken(@NotNull final String accessToken) { this.accessToken = accessToken; } + + @Nullable @JsonProperty("expires_in") + public Long getExpires() { return this.expires; } + @JsonProperty("expires_in") + private void setExpires(@NotNull final Long expires) { this.expires = expires; } + + @JsonProperty("user") + private void setUser(@NotNull final UsergridUser user) { + if( this.entities == null ) { + this.entities = new ArrayList<>(); + } + this.entities.add(user); + } + + @NotNull @JsonAnyGetter + public Map getProperties() { + return properties; + } + @JsonAnySetter + private void setProperty(@NotNull final String key, @NotNull final JsonNode value) { + properties.put(key, value); + } + + @NotNull + public UsergridResponse loadNextPage() { + UsergridClient client = this.client; + UsergridEntity entity = this.first(); + if( this.hasNextPage() && client != null && entity != null ) { + Map paramsMap = new HashMap<>(); + paramsMap.put("cursor", getCursor()); + UsergridRequest request = new UsergridRequest(UsergridEnums.UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, client.clientAppUrl(), paramsMap, null, null, this.getQuery(), client.authForRequests() , entity.getType()); + return client.sendRequest(request); + } else { + return UsergridResponse.fromError(client,"Error Loading Next Page.","Unable to load next page."); + } + } + + @NotNull + public static UsergridResponse fromError(@Nullable final UsergridClient client, @NotNull final String errorName, @NotNull final String errorDescription) { + UsergridResponse response = new UsergridResponse(); + response.client = client; + response.responseError = new UsergridResponseError(errorName,errorDescription); + return response; + } + + @NotNull + public static UsergridResponse fromException(@Nullable final UsergridClient client, @NotNull final Exception ex) { + final UsergridResponse response = new UsergridResponse(); + response.client = client; + final UsergridResponseError responseError = new UsergridResponseError(); + responseError.setErrorDescription(ex.getMessage()); + if( ex.getClass() != null ) { + responseError.setErrorName(ex.getClass().toString()); + } + if( ex.getCause() != null ) { + responseError.setErrorException(ex.getCause().toString()); + } + response.responseError = responseError; + return response; + } + + @NotNull + public static UsergridResponse fromResponse(@NotNull final UsergridClient client, @NotNull final UsergridRequest request, @NotNull final okhttp3.Response requestResponse) { + UsergridResponse response; + JsonNode responseJson; + try { + String responseJsonString = requestResponse.body().string(); + responseJson = JsonUtils.mapper.readTree(responseJsonString); + } catch ( Exception e ) { + return UsergridResponse.fromException(client,e); + } + if ( responseJson.has("error") ) { + response = new UsergridResponse(); + response.responseError = JsonUtils.fromJsonNode(responseJson,UsergridResponseError.class); + } else { + response = JsonUtils.fromJsonNode(responseJson,UsergridResponse.class); + } + response.client = client; + response.responseJson = responseJson; + response.statusCode = requestResponse.code(); + + Headers responseHeaders = requestResponse.headers(); + HashMap headers = new HashMap<>(); + for (int i = 0; i < responseHeaders.size(); i++) { + headers.put(responseHeaders.name(i),responseHeaders.value(i)); + } + + response.headers = headers; + response.query = request.getQuery(); + return response; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java new file mode 100644 index 0000000..387ae56 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.response; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridResponseError { + + @Nullable private String errorName; + @Nullable private String errorDescription; + @Nullable private String errorException; + + @NotNull private final Map properties = new HashMap<>(); + + public UsergridResponseError() { + this(null,null,null); + } + public UsergridResponseError(@Nullable final String errorName) { + this(errorName, null, null); + } + public UsergridResponseError(@Nullable final String errorName, @Nullable final String errorDescription) { + this(errorName,errorDescription,null); + } + public UsergridResponseError(@Nullable final String errorName, @Nullable final String errorDescription, @Nullable final String errorException) { + this.errorName = errorName; + this.errorDescription = errorDescription; + this.errorException = errorException; + } + + @NotNull + @JsonAnyGetter + public Map getProperties() { + return properties; + } + + @JsonAnySetter + public void setProperty(@NotNull final String key, @NotNull final JsonNode value) { + properties.put(key, value); + } + + @Nullable + @JsonProperty("error") + public String getErrorName() { + return errorName; + } + + @JsonProperty("error") + public void setErrorName(@NotNull final String errorName) { + this.errorName = errorName; + } + + @Nullable + @JsonProperty("exception") + public String getErrorException() { + return errorException; + } + + @JsonProperty("exception") + public void setErrorException(@NotNull final String errorException) { + this.errorException = errorException; + } + + @Nullable + @JsonProperty("error_description") + public String getErrorDescription() { + return errorDescription; + } + + @JsonProperty("error_description") + public void setErrorDescription(@NotNull final String errorDescription) { + this.errorDescription = errorDescription; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/utils/JsonUtils.java b/src/main/java/org/apache/usergrid/java/client/utils/JsonUtils.java new file mode 100644 index 0000000..dc1514b --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/utils/JsonUtils.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.utils; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.*; +import org.apache.usergrid.java.client.exception.UsergridException; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +@SuppressWarnings("unused") +public final class JsonUtils { + + @NotNull public static final ObjectMapper mapper = new ObjectMapper(); + + static { + SimpleModule module = new SimpleModule(); + module.addDeserializer(UsergridEntity.class, new UsergridEntityDeserializer()); + mapper.registerModule(module); + } + + @NotNull + public static ObjectNode createObjectNode() { + return mapper.createObjectNode(); + } + + @Nullable + public static String getStringProperty(@NotNull final Map properties, @NotNull final String name) { + JsonNode value = properties.get(name); + if (value != null) { + return value.asText(); + } + return null; + } + + @NotNull + public static ArrayList convertToArrayList(@NotNull final ArrayNode arrayNode) { + ArrayList arrayList = new ArrayList<>(); + Iterator iterator = arrayNode.elements(); + while( iterator.hasNext() ) { + arrayList.add(iterator.next()); + } + return arrayList; + } + + @NotNull + public static String toJsonString(@NotNull final Object obj) { + try { + return mapper.writeValueAsString(obj); + } catch (JsonGenerationException e) { + throw new UsergridException("Unable to generate json", e); + } catch (JsonMappingException e) { + throw new UsergridException("Unable to map json", e); + } catch (IOException e) { + throw new UsergridException("IO error", e); + } + } + + @NotNull + public static String toPrettyJsonString(@NotNull final Object obj) { + try { + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); + } catch (JsonGenerationException e) { + throw new UsergridException("Unable to generate json", e); + } catch (JsonMappingException e) { + throw new UsergridException("Unable to map json", e); + } catch (IOException e) { + throw new UsergridException("IO error", e); + } + } + + @NotNull + public static JsonNode toJsonNode(@NotNull final Object obj) { + return mapper.convertValue(obj, JsonNode.class); + } + + @NotNull + public static Map toMap(@NotNull final Object obj) { + return mapper.convertValue(obj,Map.class); + } + + @NotNull + public static T fromJsonNode(@NotNull final JsonNode json, @NotNull final Class c) { + try { + JsonParser jp = json.traverse(); + return mapper.readValue(jp, c); + } catch (JsonGenerationException e) { + throw new UsergridException("Unable to generate json", e); + } catch (JsonMappingException e) { + throw new UsergridException("Unable to map json", e); + } catch (IOException e) { + throw new UsergridException("IO error", e); + } + } + + public static void setObjectProperty(@NotNull final Map properties, @NotNull final String name, @Nullable final ObjectNode value) { + if (value == null) { + properties.remove(name); + } else { + properties.put(name, value); + } + } + + @Nullable + @SuppressWarnings("unchecked") + public static T getProperty(@NotNull final Map properties, @NotNull final String name) { + JsonNode value = properties.get(name); + if( value == null ) { + return null; + } else if (value instanceof TextNode) { + return (T) value.asText(); + } else if (value instanceof LongNode) { + Long valueLong = value.asLong(); + return (T) valueLong; + } else if (value instanceof BooleanNode) { + Boolean valueBoolean = value.asBoolean(); + return (T) valueBoolean; + } else if (value instanceof IntNode) { + Integer valueInteger = value.asInt(); + return (T) valueInteger; + } else if (value instanceof FloatNode) { + return (T) Float.valueOf(value.toString()); + } else { + return (T) value; + } + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/utils/MapUtils.java b/src/main/java/org/apache/usergrid/java/client/utils/MapUtils.java new file mode 100644 index 0000000..cbf6d51 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/utils/MapUtils.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.utils; + +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public final class MapUtils { + + @NotNull + public static Map newMapWithoutKeys(@NotNull final Map map, @NotNull final List keys) { + Map newMap = new HashMap<>(); + for (String key : keys) { + newMap.remove(key); + } + return newMap; + } +} diff --git a/src/main/java/org/apache/usergrid/java/client/utils/ObjectUtils.java b/src/main/java/org/apache/usergrid/java/client/utils/ObjectUtils.java new file mode 100644 index 0000000..1d05405 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/utils/ObjectUtils.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.utils; + +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public final class ObjectUtils { + + public static boolean isEmpty(@Nullable final Object s) { + if (s == null) { + return true; + } + if ((s instanceof String) && (((String) s).trim().length() == 0)) { + return true; + } + if (s instanceof Map) { + return ((Map) s).isEmpty(); + } + return false; + } + +} diff --git a/src/main/java/org/apache/usergrid/java/client/utils/UsergridEntityDeserializer.java b/src/main/java/org/apache/usergrid/java/client/utils/UsergridEntityDeserializer.java new file mode 100644 index 0000000..5daeace --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/utils/UsergridEntityDeserializer.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.java.client.utils; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public final class UsergridEntityDeserializer extends JsonDeserializer { + + @NotNull private static final ObjectMapper objectMapper = new ObjectMapper(); + + @NotNull + public UsergridEntity deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException { + UsergridEntity entity = UsergridEntityDeserializer.objectMapper.readValue(jsonParser,UsergridEntity.class); + Class entitySubClass = UsergridEntity.customSubclassForType(entity.getType()); + if( entitySubClass != null ) { + entity = JsonUtils.mapper.convertValue(entity,entitySubClass); + } + return entity; + } +} diff --git a/src/test/java/org/apache/usergrid/client/ClientAuthFallBackTestCase.java b/src/test/java/org/apache/usergrid/client/ClientAuthFallBackTestCase.java new file mode 100644 index 0000000..944aaef --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/ClientAuthFallBackTestCase.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.*; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertTrue; + +public class ClientAuthFallBackTestCase { + + private static UsergridQuery usersQuery = new UsergridQuery("users").desc("created"); + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + Usergrid.authenticateApp(new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET)); + + String[] segments = {"roles","guest","permissions"}; + Map params = new HashMap<>(); + params.put("permission","get,post,put,delete:/**"); + UsergridRequest request = new UsergridRequest(UsergridEnums.UsergridHttpMethod.DELETE, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, Usergrid.clientAppUrl(), params, null, Usergrid.authForRequests(), segments); + Usergrid.sendRequest(request); + } + + @After + public void after() { + Usergrid.setAuthMode(UsergridEnums.UsergridAuthMode.APP); + String[] segments = {"roles","guest","permissions"}; + Map params = new HashMap<>(); + params.put("permission","get,post,put,delete:/**"); + UsergridRequest request = new UsergridRequest(UsergridEnums.UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, Usergrid.clientAppUrl(), params, null, Usergrid.authForRequests(), segments); + Usergrid.sendRequest(request); + Usergrid.reset(); + } + + @Test + public void authFallBackNONETest() { + Usergrid.setAuthMode(UsergridEnums.UsergridAuthMode.NONE); + UsergridResponse resp = Usergrid.GET(usersQuery); + assertTrue("The returned response should have error", resp.getResponseError() != null); + } + + @Test + public void authFallBackAPPTest() { + Usergrid.setAuthMode(UsergridEnums.UsergridAuthMode.APP); + UsergridResponse resp = Usergrid.GET(usersQuery); + assertTrue("The returned response should not have error", resp.getResponseError() == null); + } +} diff --git a/src/test/java/org/apache/usergrid/client/ClientAuthTestCase.java b/src/test/java/org/apache/usergrid/client/ClientAuthTestCase.java new file mode 100644 index 0000000..79e1bbc --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/ClientAuthTestCase.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ClientAuthTestCase { + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL); + } + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void clientAuth_APP() { + Usergrid.setAuthMode(UsergridAuthMode.APP); + UsergridAppAuth appAuth = new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET); + UsergridResponse response = Usergrid.authenticateApp(appAuth); + assertTrue("response status is OK", response.ok()); + assertNull("no error thrown", response.getResponseError()); + assertTrue("appAuth.isValidToken should be true", appAuth.isValidToken()); + assertNotNull("should have a valid token", appAuth.getAccessToken()); + assertNotNull("should have an expiry", appAuth.getExpiry()); + assertEquals("client.appAuth.token should be set to the token returned from Usergrid", Usergrid.getAppAuth(), appAuth); + assertTrue("should have a token that is not empty", appAuth.getAccessToken().length() > 0); + assertTrue("client.appAuth.expiry should be set to a future date", appAuth.getExpiry() > System.currentTimeMillis()); + } + + @Test + public void clientAuth_USER() { + Usergrid.setAuthMode(UsergridAuthMode.USER); + UsergridUserAuth userAuth = new UsergridUserAuth(SDKTestConfiguration.APP_UserName, SDKTestConfiguration.APP_Password); + UsergridResponse response = Usergrid.authenticateUser(userAuth); + assertTrue("response status is OK", response.ok()); + assertNull("no error thrown", response.getResponseError()); + assertTrue("appAuth.isValidToken should be true", userAuth.isValidToken()); + assertNotNull("should have a token", userAuth.getAccessToken()); + assertNotNull("should have an expiry", userAuth.getExpiry()); + + UsergridUser currentUser = Usergrid.getCurrentUser(); + assertNotNull("client.currentUser should not be null", currentUser); + assertNotNull("client.currentUser().getUserAuth() should not be null", currentUser.getUserAuth()); + assertEquals("client.currentUser().userAuth should be the same as userAuth", currentUser.getUserAuth(), userAuth); + assertTrue("should have a token that is not empty", userAuth.getAccessToken().length() > 0); + assertTrue("client.currentUser().userAuth.getExpiry() should be set to a future date", userAuth.getExpiry() > System.currentTimeMillis()); + assertEquals("client.authForRequests() should be the same as userAuth", Usergrid.authForRequests(), userAuth); + } + + @Test + public void clientAuth_NONE() { + Usergrid.setAuthMode(UsergridAuthMode.NONE); + UsergridUserAuth userAuth = new UsergridUserAuth(SDKTestConfiguration.APP_UserName, SDKTestConfiguration.APP_Password); + Usergrid.authenticateUser(userAuth); + assertNull("no auth should be returned from client.authForRequests", Usergrid.authForRequests()); + } +} diff --git a/src/test/java/org/apache/usergrid/client/ClientConnectionsTestCase.java b/src/test/java/org/apache/usergrid/client/ClientConnectionsTestCase.java new file mode 100644 index 0000000..72b88dd --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/ClientConnectionsTestCase.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridDirection; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ClientConnectionsTestCase { + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + UsergridAppAuth appAuth = new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET); + Usergrid.authenticateApp(appAuth); + } + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void clientConnect() { + String collectionName = "testClientConnection" + System.currentTimeMillis(); + + UsergridEntity entityOne = new UsergridEntity(collectionName,"john"); + entityOne.putProperty("place","San Jose"); + entityOne.save(); + assertNotNull(entityOne.getUuid()); + + UsergridEntity entityTwo = new UsergridEntity(collectionName,"amici"); + entityOne.putProperty("place","San Jose"); + entityTwo.save(); + assertNotNull(entityTwo.getUuid()); + + //should connect entities by passing UsergridEntity objects as parameters + Usergrid.connect(entityOne, "likes", entityTwo); + + UsergridEntity responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityOne, "likes").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityTwo.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityTwo.getUuid(),responseEntity.getUuid()); + + //should connect entities by passing a source UsergridEntity object and a target uuid. + Usergrid.connect(entityOne.getType(), entityOne.getUuid(), "visited", entityTwo.getUuid()); + + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityOne, "visited").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityTwo.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityTwo.getUuid(),responseEntity.getUuid()); + + //should connect entities by passing source type, source uuid, and target uuid as parameters + Usergrid.connect(entityTwo.getType(), entityTwo.getUuid(), "visitor", entityOne.getUuid()); + + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityTwo, "visitor").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityOne.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityOne.getUuid(),responseEntity.getUuid()); + + //should connect entities by passing source type, source name, target type, and target name as parameters + assertNotNull(entityOne.getName()); + assertNotNull(entityTwo.getName()); + Usergrid.connect(entityTwo.getType(), entityTwo.getName(), "welcomed", entityOne.getType(), entityOne.getName()); + + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityTwo, "welcomed").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityOne.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityOne.getUuid(),responseEntity.getUuid()); + + //should connect entities by passing source type, source name, target type, and target name as parameters + Usergrid.connect(entityTwo.getType(), entityTwo.getName(), "invalidLink", "invalidName"); + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityTwo, "invalidLink").first(); + assertNull("response entity should be null.", responseEntity); + } + + @Test + public void clientGetConnect() { + String collectionName = "testClientGetConnection" + System.currentTimeMillis(); + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entityOne = new UsergridEntity(collectionName, "john"); + entityOne.putProperty("place","San Jose"); + entityOne.save(); + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entityTwo = new UsergridEntity(collectionName, "amici"); + entityTwo.putProperty("place","San Jose"); + entityTwo.save(); + + //should connect entities by passing UsergridEntity objects as parameters + Usergrid.connect(entityOne, "likes", entityTwo); + Usergrid.connect(entityOne, "visited", entityTwo); + + UsergridEntity responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityOne, "likes").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityTwo.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityTwo.getUuid(),responseEntity.getUuid()); + + responseEntity = Usergrid.getConnections(UsergridDirection.IN, entityTwo, "visited").first(); + assertNotNull(responseEntity); + assertEquals("both entities name should be same", entityOne.getName(),responseEntity.getName()); + assertEquals("both entities uuid should be same", entityOne.getUuid(),responseEntity.getUuid()); + + } + + @Test + public void clientDisConnect() { + String collectionName = "testClientGetConnection" + System.currentTimeMillis(); + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entityOne = new UsergridEntity(collectionName,"john"); + entityOne.putProperty("place","San Jose"); + entityOne.save(); + assertNotNull(entityOne.getName()); + assertNotNull(entityOne.getUuid()); + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entityTwo = new UsergridEntity(collectionName, "amici"); + entityTwo.putProperty("place","San Jose"); + entityTwo.save(); + assertNotNull(entityTwo.getName()); + assertNotNull(entityTwo.getUuid()); + + //should connect entities by passing UsergridEntity objects as parameters + Usergrid.connect(entityOne, "likes", entityTwo); + Usergrid.connect(entityOne, "visited", entityTwo); + Usergrid.connect(entityOne, "twice", entityTwo); + Usergrid.connect(entityOne, "thrice", entityTwo); + + //should disConnect entities by passing UsergridEntity objects as parameters + Usergrid.disconnect(entityOne, "likes", entityTwo); + UsergridEntity responseEntity = Usergrid.getConnections(UsergridDirection.IN, entityTwo, "likes").first(); + assertNull("responseEntity should be null", responseEntity); + + //should disConnect entities by passing source type, source uuid, and target uuid as parameters + Usergrid.disconnect(entityOne.getType(), entityOne.getUuid(), "visited", entityTwo.getUuid()); + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityOne, "visited").first(); + assertNull("responseEntity should be null", responseEntity); + + //should disConnect entities by passing source type, source name, target type, and target name as parameters + Usergrid.disconnect(entityOne.getType(), entityOne.getName(), "twice", entityTwo.getType(), entityTwo.getName()); + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityOne, "twice").first(); + assertNull("responseEntity should be null", responseEntity); + + //should fail to disConnect entities when specifying target name without type + Usergrid.disconnect(entityTwo.getType(), entityTwo.getName(), "thrice", entityOne.getName()); + responseEntity = Usergrid.getConnections(UsergridDirection.OUT, entityTwo, "thrice").first(); + assertNull("both entities name should be same",responseEntity); + } +} diff --git a/src/test/java/org/apache/usergrid/client/ClientRestTestCase.java b/src/test/java/org/apache/usergrid/client/ClientRestTestCase.java new file mode 100644 index 0000000..b01a167 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/ClientRestTestCase.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.*; + +public class ClientRestTestCase { + + final String collectionName = "testClientConnection" + System.currentTimeMillis(); + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + UsergridAppAuth appAuth = new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET); + Usergrid.authenticateApp(appAuth); + createCollectionAndEntity(); + } + + @After + public void after() { + Usergrid.reset(); + } + + public void createCollectionAndEntity() { + UsergridEntity entityOne = new UsergridEntity(collectionName,"john"); + entityOne.putProperty("place", "San Jose"); + entityOne.save(); + + UsergridEntity entityTwo = new UsergridEntity(collectionName,"amici"); + entityTwo.putProperty("place", "San Jose"); + entityTwo.save(); + + assertNotNull(entityOne.getUuid()); + assertNotNull(entityTwo.getUuid()); + + Usergrid.connect(entityOne, "likes", entityTwo); + Usergrid.connect(entityOne.getType(), entityOne.getUuid(), "visited", entityTwo.getUuid()); + } + + @Test + public void clientGET() { + // Retrieve the response. + UsergridResponse response = Usergrid.GET(collectionName, "john"); + assertTrue("response should be ok", response.ok()); + assertNull("no error thrown", response.getResponseError()); + + assertNotNull(response.getEntities()); + assertTrue("response entities is an Array", response.getEntities().getClass() == ArrayList.class); + + // response.first should exist and have a valid uuid + UsergridEntity firstEntity = response.first(); + assertNotNull(firstEntity); + assertNotNull("first entity is not null and has uuid", firstEntity.getUuid()); + + // response.entity should exist, equals the first entity, and have a valid uuid + UsergridEntity responseEntity = response.entity(); + assertNotNull(responseEntity); + assertEquals(firstEntity, responseEntity); + assertNotNull("entity is not null and has uuid", responseEntity.getUuid()); + + // response.last should exist and have a valid uuid + UsergridEntity lastEntity = response.last(); + assertNotNull(lastEntity); + assertNotNull("last entity is not null and has uuid", lastEntity.getUuid()); + } +} diff --git a/src/test/java/org/apache/usergrid/client/EntityTestCase.java b/src/test/java/org/apache/usergrid/client/EntityTestCase.java new file mode 100644 index 0000000..42c3054 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/EntityTestCase.java @@ -0,0 +1,676 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.TextNode; +import org.apache.usergrid.java.client.UsergridEnums.UsergridDirection; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +public class EntityTestCase { + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + Usergrid.authenticateApp(new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET)); + } + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void testEntityCreationSuccess() { + String collectionName = "ect" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + HashMap map = new HashMap<>(); + map.put("name",new TextNode(entityName)); + map.put("color",new TextNode("red")); + map.put("shape",new TextNode("square")); + + UsergridEntity entity = new UsergridEntity(collectionName,null,map); + UsergridResponse response = entity.save(); + assertNull(response.getResponseError()); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The returned entity is null!", eLookUp); + assertEquals("entities has the correct type", eLookUp.getType(),collectionName); + assertEquals("entities has the correct name", eLookUp.getName(),entityName); + assertEquals("entities has the correct color", eLookUp.getStringProperty("color"),"red"); + assertEquals("entities has the correct shape", eLookUp.getStringProperty("shape"),"square"); + } + + @Test + public void testDuplicateEntityNameFailure() { + String collectionName = "testDuplicateEntityNameFailure" + System.currentTimeMillis(); + + UsergridEntity entity = new UsergridEntity(collectionName,"test3"); + UsergridResponse response = Usergrid.POST(entity); + assertNull("First entity create should have succeeded.", response.getResponseError()); + + response = Usergrid.POST(entity); + assertNotNull("Second entity create should not succeed!", response.getResponseError()); + } + + @Test + public void testEntityLookupByName() { + String collectionName = "testEntityLookupByName" + System.currentTimeMillis(); + String entityName = "testEntity4"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + UsergridEntity eLookup = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The returned entity is null!", eLookup); + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + } + + @Test + public void testEntityLookupByUUID() { + String collectionName = "testEntityLookupByUUID" + System.currentTimeMillis(); + String entityName = "testEntity5"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + assertNotNull(entity.getUuid()); + + UsergridEntity eLookup = Usergrid.GET(collectionName, entity.getUuid()).first(); + assertNotNull("The returned entity is null!", eLookup); + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + } + + @Test + public void testEntityLookupByQuery() { + String collectionName = "testEntityLookupByQuery" + System.currentTimeMillis(); + String entityName = "testEntity6"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.putProperty("color","red"); + entity.putProperty("shape","square"); + entity.save(); + + SDKTestUtils.indexSleep(); + + UsergridQuery query = new UsergridQuery(collectionName).eq("color", "red"); + UsergridEntity eLookup = Usergrid.GET(query).first(); + + assertNotNull("The entity was not returned on lookup", eLookup); + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + + query = new UsergridQuery(collectionName).eq("name", entityName); + eLookup = Usergrid.GET(query).first(); + + assertNotNull("The entity was not returned on lookup", eLookup); + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + + query = new UsergridQuery(collectionName).eq("shape", "square"); + eLookup = Usergrid.GET(query).first(); + + assertNotNull("The entity was not returned on lookup", eLookup); + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + + query = new UsergridQuery(collectionName).eq("shape", "circle"); + eLookup = Usergrid.GET(query).first(); + + assertNull("The entity was not expected to be returned on lookup", eLookup); + } + + @Test + public void testEntityUpdate() { + String collectionName = "testEntityLookupByUUID" + System.currentTimeMillis(); + String entityName = "testEntity7"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.putProperty("color","red"); + entity.putProperty("shape","square"); + entity.putProperty("orientation","up"); + entity.save(); + + SDKTestUtils.sleep(1000); + + UsergridQuery query = new UsergridQuery(collectionName).eq("orientation", "up"); + UsergridEntity eLookup = Usergrid.GET(query).first(); + assertNotNull(eLookup); + + assertEquals("The returned entity does not have the same UUID when querying by field", entity.getUuid(),eLookup.getUuid()); + + entity.putProperty("orientation", "down"); + entity.save(); + assertNotNull(entity.getUuid()); + + eLookup = Usergrid.GET(collectionName, entity.getUuid()).first(); + assertNotNull(eLookup); + + assertEquals("The returned entity does not have the same UUID", entity.getUuid(),eLookup.getUuid()); + assertEquals("The field was not updated!", eLookup.getStringProperty("orientation"),"down"); + + SDKTestUtils.sleep(1000); + + query = new UsergridQuery(collectionName).eq("orientation", "up"); + eLookup = Usergrid.GET(query).first(); + + assertNull("The entity was returned for old value!", eLookup); + } + + @Test + public void testEntityDelete() { + String collectionName = "testEntityDelete" + System.currentTimeMillis(); + String entityName = "testEntity8"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.putProperty("color","red"); + entity.putProperty("shape","square"); + entity.putProperty("orientation","up"); + entity.save(); + + SDKTestUtils.indexSleep(); + + assertNotNull(entity.getUuid()); + assertNotNull(entity.getName()); + + UsergridQuery query = new UsergridQuery(collectionName).eq("orientation", "up"); + UsergridEntity eLookup = Usergrid.GET(query).first(); + + assertNotNull("The returned entity was null!", eLookup); + assertEquals("The returned entity does not have the same UUID when querying by field", entity.getUuid(),eLookup.getUuid()); + + Usergrid.DELETE(entity); + + eLookup = Usergrid.GET(collectionName, entity.getUuid()).first(); + assertNull("The entity was not expected to be returned by UUID", eLookup); + + eLookup = Usergrid.GET(collectionName, entity.getName()).first(); + assertNull("The entity was not expected to be returned by getName", eLookup); + + query = new UsergridQuery(collectionName).eq("color", "red"); + eLookup = Usergrid.GET(query).first(); + assertNull("The entity was not expected to be returned", eLookup); + + query = new UsergridQuery(collectionName).eq("shape", "square"); + eLookup = Usergrid.GET(query).first(); + assertNull("The entity was not expected to be returned", eLookup); + + query = new UsergridQuery(collectionName).eq("orientation", "up"); + eLookup = Usergrid.GET(query).first(); + assertNull("The entity was not expected to be returned", eLookup); + } + + @Test + public void testEntityPutPropertyAndSave() { + String collectionName = "testEntityPutProperty" + System.currentTimeMillis(); + String entityName = "testEntity9"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.putProperty("color","red"); + entity.putProperty("shape","square"); + entity.putProperty("orientation","up"); + entity.putProperty("sides", 4); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + + //Check if the property was added correctly + assertNotNull("The entity returned is not null.", eLookUp); + assertEquals("The entity putProperty() was successful ", eLookUp.getStringProperty("orientation"),"up"); + assertEquals("The entity putProperty() was successful ", eLookUp.getIntegerProperty("sides"), new Integer(4)); + + //Overwrite the property if it exists. + entity.putProperty("orientation", "horizontal"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The returned entity was null!", eLookUp); + assertEquals("The entity putProperty() was successful ", eLookUp.getStringProperty("orientation"),"horizontal"); + + //should not be able to set the name key (name is immutable) + entity.putProperty("name","entityNew"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The returned entity was null!", eLookUp); + assertEquals("The entity putProperty() was successful ", eLookUp.getName(),"testEntity9"); + } + + @Test + public void testEntityPutProperties() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity9"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.putProperty("color","black"); + entity.putProperty("orientation","up"); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertEquals("The entity putProperty() was successful ", eLookUp.getStringProperty("orientation"),"up"); + assertEquals("overwrite existing property", eLookUp.getStringProperty("color"),"black"); + } + + @Test + public void testEntityRemovePropertiesAndSave() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + + String entityName = "testEntity9"; + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entity = SDKTestUtils.createEntity(collectionName, entityName, fields); + Map properties = new HashMap<>(); + properties.put("shape", "square"); + properties.put("orientation", "up"); + properties.put("color", "black"); + entity.putProperties(properties); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, "testEntity9").first(); + assertNotNull("The entity returned is not null.", eLookUp); + + String[] removeProperties = {"shape", "color"}; + entity.removeProperties(Arrays.asList(removeProperties)); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, "testEntity9").first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertTrue("overwrite existing property", eLookUp.getStringProperty("color") == null); + assertTrue("overwrite existing property", eLookUp.getStringProperty("shape") == null); + + } + + @Test + public void testEntityRemoveProperty() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + + String entityName = "testEntity11"; + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entity = SDKTestUtils.createEntity(collectionName, entityName, fields); + Map properties = new HashMap<>(); + properties.put("shape", "square"); + properties.put("orientation", "up"); + properties.put("color", "black"); + entity.putProperties(properties); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, "testEntity11").first(); + assertNotNull("The entity returned is not null.", eLookUp); + + entity.removeProperty("color"); + entity.removeProperty("shape"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, "testEntity11").first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertTrue("overwrite existing property", eLookUp.getStringProperty("color") == null); + assertTrue("overwrite existing property", eLookUp.getStringProperty("shape") == null); + + } + + @Test + public void testEntityAppendInArray() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + ArrayList lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + lenArr.add(4); + entity.insert("lenArray", lenArr); + entity.save(); + + lenArr = new ArrayList<>(); + lenArr.add(6); + lenArr.add(7); + entity.append("lenArray", lenArr); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + ArrayNode toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(1).add(2).add(3).add(4).add(6).add(7); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + } + + @Test + public void testEntityPrependInArray() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + ArrayList lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + lenArr.add(4); + entity.putProperty("lenArray", lenArr); + entity.save(); + + lenArr = new ArrayList<>(); + lenArr.add(6); + lenArr.add(7); + + entity.insert("lenArray", lenArr, 0); + entity.save(); + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + ArrayNode toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(6).add(7).add(1).add(2).add(3).add(4); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + } + + @Test + public void testEntityPopInArray() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + ArrayList lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + entity.putProperty("lenArray", lenArr); + entity.save(); + + // should remove the last value of an existing array + entity.pop("lenArray"); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + ArrayNode toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(1).add(2); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + + // value should remain unchanged if it is not an array + entity.putProperty("foo", "test1"); + entity.save(); + + entity.pop("foo"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertEquals("foo should equal test1.", eLookUp.getStringProperty("foo"), "test1"); + + //should gracefully handle empty arrays + ArrayList lenArr2 = new ArrayList<>(); + entity.putProperty("foo", lenArr2); + entity.save(); + entity.pop("foo"); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("foo"),toCompare); + } + + @Test + public void testEntityShiftInArray() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + //should remove the last value of an existing array + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + ArrayList lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + entity.putProperty("lenArray", lenArr); + entity.save(); + + entity.shift("lenArray"); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + ArrayNode toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(2).add(3); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + + //value should remain unchanged if it is not an array + entity.putProperty("foo", "test1"); + entity.shift("foo"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertEquals("The entity returned is not null.", eLookUp.getStringProperty("foo"), "test1"); + + //should gracefully handle empty arrays + ArrayList lenArr2 = new ArrayList<>(); + entity.putProperty("foo", lenArr2); + entity.shift("foo"); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("foo"), new ArrayNode(JsonNodeFactory.instance)); + } + + @Test + public void testEntityInsertInArray() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityName = "testEntity1"; + + //should set properties for a given object, overwriting properties that exist and creating those that don\'t + UsergridEntity entity = new UsergridEntity(collectionName,entityName); + entity.save(); + + ArrayList lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + lenArr.add(4); + entity.putProperty("lenArray", lenArr); + entity.save(); + + ArrayList lenArr2 = new ArrayList<>(); + lenArr2.add(6); + lenArr2.add(7); + + entity.insert("lenArray", lenArr2, 6); + entity.save(); + + UsergridEntity eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + ArrayNode toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(1).add(2).add(3).add(4).add(6).add(7); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + + //should merge an array of values into an existing array at the specified index + lenArr = new ArrayList<>(); + lenArr.add(1); + lenArr.add(2); + lenArr.add(3); + lenArr.add(4); + + entity.putProperty("lenArray", lenArr); + entity.save(); + + lenArr2 = new ArrayList<>(); + lenArr2.add(5); + lenArr2.add(6); + lenArr2.add(7); + lenArr2.add(8); + + entity.insert("lenArray", lenArr2, 2); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add(1).add(2).add(5).add(6).add(7).add(8).add(3).add(4); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("lenArray"),toCompare); + + //should convert an existing value into an array when inserting a second value + entity.putProperty("foo", "test"); + entity.insert("foo", "test1", 1); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add("test").add("test1"); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("foo"),toCompare); + + //should create a new array when a property does not exist + entity.insert("foo1", "test2", 1); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add("test2"); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("foo1"),toCompare); + + //should gracefully handle index out of positive range + entity.putProperty("ArrayIndex", "test1"); + entity.insert("ArrayIndex", "test2", 1000); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add("test1").add("test2"); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("ArrayIndex"),toCompare); + + //should gracefully handle index out of negative range + entity.insert("ArrayIndex", "test3", -1000); + entity.save(); + + eLookUp = Usergrid.GET(collectionName, entityName).first(); + assertNotNull("The entity returned is not null.", eLookUp); + + toCompare = new ArrayNode(JsonNodeFactory.instance); + toCompare.add("test3").add("test1").add("test2"); + assertEquals("The two arrays should be equal.", eLookUp.getJsonNodeProperty("ArrayIndex"),toCompare); + } + + @Test + public void testEntityConnectDisconnectGetConnections() { + String collectionName = "testEntityProperties" + System.currentTimeMillis(); + String entityOneName = "testEntity1"; + String entityTwoName = "testEntity2"; + + UsergridEntity entityOne = new UsergridEntity(collectionName,entityOneName); + entityOne.putProperty("color","red"); + entityOne.putProperty("shape","square"); + entityOne.save(); + + UsergridEntity entityTwo = new UsergridEntity(collectionName,entityTwoName); + entityTwo.putProperty("color","green"); + entityTwo.putProperty("shape","circle"); + entityTwo.save(); + + assertNotNull(entityOne.getUuid()); + assertNotNull(entityTwo.getUuid()); + assertNotNull(entityOne.getName()); + assertNotNull(entityTwo.getName()); + assertNotNull(entityOne.uuidOrName()); + assertNotNull(entityTwo.uuidOrName()); + + //should connect entities by passing a target UsergridEntity object as a parameter + entityOne.connect("likes", entityTwo); + entityOne.save(); + + UsergridEntity eLookUpConnectedEntity = entityOne.getConnections(UsergridDirection.OUT, "likes").first(); + assertNotNull("The connected entity returned is not null.", eLookUpConnectedEntity); + + assertEquals("The entity name should be equals.", eLookUpConnectedEntity.getName(),entityTwoName); + + eLookUpConnectedEntity = entityTwo.getConnections(UsergridDirection.IN, "likes").first(); + assertNotNull("The connected entity returned is not null.", eLookUpConnectedEntity); + assertEquals("The entity name should be equals.", eLookUpConnectedEntity.getName(),entityOneName); + + entityOne.disconnect("likes", entityTwo); + entityOne.save(); + + eLookUpConnectedEntity = entityTwo.getConnections(UsergridDirection.IN, "likes").first(); + assertNull("The entity returned is not null.", eLookUpConnectedEntity); + + //should connect entities by passing target uuid as a parameter + Usergrid.connect(entityOne.getType(),entityOne.getUuid(),"visited",entityTwo.getUuid()); + entityOne.save(); + + eLookUpConnectedEntity = entityOne.getConnections(UsergridDirection.OUT, "visited").first(); + assertNotNull("The connected entity returned is not null.", eLookUpConnectedEntity); + assertEquals("The entity name should be equals.", eLookUpConnectedEntity.getName(),entityTwoName); + + Usergrid.disconnect(entityOne.getType(),entityOne.getUuid(),"visited",entityTwo.getUuid()); + entityOne.save(); + + eLookUpConnectedEntity = entityOne.getConnections(UsergridDirection.OUT, "visited").first(); + assertNull("The entity returned is not null.", eLookUpConnectedEntity); + + //should connect entities by passing target type and name as parameters + Usergrid.connect(entityOne.getType(),entityOne.getUuid(),"revisit",entityTwo.getType(),entityTwo.getName()); + entityOne.save(); + + eLookUpConnectedEntity = entityOne.getConnections(UsergridDirection.OUT, "revisit").first(); + assertNotNull("The connected entity returned is not null.", eLookUpConnectedEntity); + assertEquals("The entity name should be equals.", eLookUpConnectedEntity.getName(),entityTwoName); + + Usergrid.disconnect(entityOne.getType(),entityOne.getUuid(),"revisit",entityTwo.getType(),entityTwo.getName()); + entityOne.save(); + + eLookUpConnectedEntity = entityOne.getConnections(UsergridDirection.OUT, "revisit").first(); + assertNull("The entity returned is not null.", eLookUpConnectedEntity); + } +} diff --git a/src/test/java/org/apache/usergrid/client/QueryTestCase.java b/src/test/java/org/apache/usergrid/client/QueryTestCase.java new file mode 100644 index 0000000..f013134 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/QueryTestCase.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.DoubleNode; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +public class QueryTestCase { + + public static final String COLLECTION = "shapes"; + + public static float distFrom(float lat1, float lng1, float lat2, float lng2) { + double earthRadius = 6371000; //meters + double dLat = Math.toRadians(lat2 - lat1); + double dLng = Math.toRadians(lng2 - lng1); + double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return (float) (earthRadius * c); + } + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + Usergrid.authenticateApp(new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET)); + } + + @After + public void after() { + Usergrid.reset(); + } + + /** + * Test a basic set of queries where there is inclusion and exclusion based on + * two fields + */ + @Test + public void testBasicQuery() { + + UsergridQuery qDelete = new UsergridQuery(COLLECTION); + Usergrid.DELETE(qDelete); + + Map entityMapByUUID = SDKTestUtils.createColorShapes(COLLECTION); + Map entityMapByName = new HashMap<>(entityMapByUUID.size()); + + for (Map.Entry uuidEntity : entityMapByUUID.entrySet()) { + entityMapByName.put(uuidEntity.getValue().getName(), uuidEntity.getValue()); + } + + SDKTestUtils.indexSleep(); + + Map fields = new HashMap<>(7); + fields.put("red", "square"); + fields.put("blue", "circle"); + fields.put("yellow", "triangle"); + + for (Map.Entry entry : fields.entrySet()) { + UsergridEntity targetEntity = entityMapByName.get(entry.getKey() + entry.getValue()); + + UsergridResponse response = Usergrid.GET(new UsergridQuery(COLLECTION).eq("color", entry.getKey())); + assertNotNull("entities returned should not be null.", response.getEntities()); + assertTrue("query for " + entry.getKey() + " shape should return 1, not: " + response.getEntities().size(), response.getEntities().size() == 1); + + UsergridEntity responseEntity = response.first(); + assertNotNull("first entity should not be null.", responseEntity); + assertEquals("query for " + entry.getKey() + " shape should the right UUID", responseEntity.getUuid(),targetEntity.getUuid()); + } + Usergrid.DELETE(qDelete); + } + + /** + * Test that geolocation is working as expected with different ranges and radius + * also test that results are sorted ascending by distance from the specified point + */ + @Test + public void testGeoQuery() { + + String collectionName = "sdkTestLocation"; + + UsergridQuery deleteQuery = new UsergridQuery(collectionName); + Usergrid.DELETE(deleteQuery); + + ArrayList entities = new ArrayList<>(); + UsergridEntity apigeeOffice = new UsergridEntity(collectionName,"Apigee Office"); + apigeeOffice.setLocation(37.334115, -121.894340); + entities.add(apigeeOffice); + + UsergridEntity amicis = new UsergridEntity(collectionName,"Amicis"); + amicis.setLocation(37.335616, -121.894168); + entities.add(amicis); + + UsergridEntity sanPedroMarket = new UsergridEntity(collectionName,"SanPedroMarket"); + sanPedroMarket.setLocation(37.336499, -121.894356); + entities.add(sanPedroMarket); + + UsergridEntity saintJamesPark = new UsergridEntity(collectionName,"saintJamesPark"); + saintJamesPark.setLocation(37.339079, -121.891422); + entities.add(saintJamesPark); + + UsergridEntity sanJoseNews = new UsergridEntity(collectionName,"sanJoseNews"); + sanJoseNews.setLocation(37.337812, -121.890784); + entities.add(sanJoseNews); + + UsergridEntity deAnza = new UsergridEntity(collectionName,"deAnza"); + deAnza.setLocation(37.334370, -121.895081); + entities.add(deAnza); + + Usergrid.POST(entities); + + SDKTestUtils.indexSleep(); + + float centerLat = 37.334110f; + float centerLon = -121.894340f; + + // Test a large distance + UsergridResponse queryResponse = Usergrid.GET(new UsergridQuery(collectionName).locationWithin(611.00000, centerLat, centerLon)); + assertNotNull(queryResponse.getEntities()); + + float lastDistanceFrom = 0; + for (UsergridEntity entity : queryResponse.getEntities()) { + + JsonNode locationNode = entity.getEntityProperty("location"); + assertNotNull("location node should not be null", locationNode); + + DoubleNode lat = (DoubleNode) locationNode.get("latitude"); + DoubleNode lon = (DoubleNode) locationNode.get("longitude"); + + float distanceFrom = distFrom(centerLat, centerLon, lat.floatValue(), lon.floatValue()); + System.out.println("Entity " + entity.getName() + " is " + distanceFrom + " away"); + + assertTrue("Entity " + entity.getName() + " was included but is not within specified distance (" + distanceFrom + ")", distanceFrom <= 611.0); + + if (lastDistanceFrom != 0) { + assertTrue("GEO results are not sorted by distance ascending: expected " + lastDistanceFrom + " <= " + distanceFrom, lastDistanceFrom <= distanceFrom); + } + + lastDistanceFrom = distanceFrom; + } + + // Test a small distance + queryResponse = Usergrid.GET(new UsergridQuery(collectionName).locationWithin(150, centerLat, centerLon)); + assertNotNull(queryResponse.getEntities()); + + lastDistanceFrom = 0; + for (UsergridEntity entity : queryResponse.getEntities()) { + + JsonNode locationNode = entity.getEntityProperty("location"); + assertNotNull("location node should not be null", locationNode); + + DoubleNode lat = (DoubleNode) locationNode.get("latitude"); + DoubleNode lon = (DoubleNode) locationNode.get("longitude"); + + float distanceFrom = distFrom(centerLat, centerLon, lat.floatValue(), lon.floatValue()); + System.out.println("Entity " + entity.getName() + " is " + distanceFrom + " away"); + + assertTrue("Entity " + entity.getName() + " was included but is not within specified distance (" + distanceFrom + ")", distanceFrom <= 150); + + if (lastDistanceFrom != 0) { + assertTrue("GEO results are not sorted by distance ascending: expected " + lastDistanceFrom + " <= " + distanceFrom, lastDistanceFrom <= distanceFrom); + } + + lastDistanceFrom = distanceFrom; + } + + Usergrid.DELETE(deleteQuery); + } +} diff --git a/src/test/java/org/apache/usergrid/client/SDKTestConfiguration.java b/src/test/java/org/apache/usergrid/client/SDKTestConfiguration.java new file mode 100644 index 0000000..e92e7be --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/SDKTestConfiguration.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridAuthMode; + +public class SDKTestConfiguration { + public static final String APP_CLIENT_ID = "b3U6THNcevskEeOQZLcUROUUVA"; //"YXA6_j0WsfFCEeWKoy6txsCOfA" ; + public static final String APP_CLIENT_SECRET = "b3U6RZHYznP28xieBzQPackFPmmnevU"; //"YXA6jg8x4wjq1AAyQBKtn4bRd1l0gJ8"; // + + public static final String APP_UserName = "javaSDK"; //"test";// //"b3U66ne33W4OEeWXmAIj6QFb-Q"; + public static final String APP_Password = "Apigee123"; //"test";//"b3U6PxbpQiTrXKCWu0n1CjK1uTZXuG4"; + public static final String USERGRID_URL = "https://api.usergrid.com/"; + public static final String ORG_NAME = "rwalsh"; + public static final String APP_NAME = "sdk.demo"; + + public static UsergridAuthMode authFallBack = UsergridAuthMode.APP; + +// public static final String APP_CLIENT_ID = "YXA61n2kpFffEeWs9QLknKqhHw"; +// public static final String APP_CLIENT_SECRET = "YXA69_aRW1IHLgMTUUYSitsGwOLY8uQ"; +// public static final String USERGRID_URL = "https://fhirsandbox-prod.apigee.net/appservices"; +// public static final String ORG_NAME = "usergrid"; +// public static final String APP_NAME = "sandbox"; +} diff --git a/src/test/java/org/apache/usergrid/client/SDKTestUtils.java b/src/test/java/org/apache/usergrid/client/SDKTestUtils.java new file mode 100644 index 0000000..fc5a039 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/SDKTestUtils.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.response.UsergridResponse; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class SDKTestUtils { + + + public static Map createColorShapes(String collection) { + + Map> entityMap = new HashMap<>(7); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + fields.put("shape", "square"); + + entityMap.put("redsquare", fields); + + fields = new HashMap<>(3); + fields.put("color", "blue"); + fields.put("shape", "circle"); + + entityMap.put("bluecircle", fields); + + fields = new HashMap<>(3); + fields.put("color", "yellow"); + fields.put("shape", "triangle"); + + entityMap.put("yellowtriangle", fields); + + return createEntities(collection, entityMap); + } + + public static Map createEntities(final String collection, + final Map> entities) { + + Map entityMap = new HashMap<>(); + + for (Map.Entry> entity : entities.entrySet()) { + + UsergridEntity e = createEntity(collection, entity.getKey(), entity.getValue()); + entityMap.put(e.getUuid(), e); + } + + return entityMap; + } + + public static UsergridEntity createEntity(final String collection, + final String name, + final Map fields) { + + UsergridEntity e = new UsergridEntity(collection, name); + + if( fields != null ) { + for (Map.Entry field : fields.entrySet()) { + e.putProperty(field.getKey(), field.getValue()); + } + } + + UsergridResponse r = Usergrid.getInstance().POST(e); + + if (r.getResponseError() != null) { + assertTrue("UUID should not be null", e.getUuid() != null); + if( fields != null ) { + for (Map.Entry field : fields.entrySet()) { + assertEquals("attempted to set a property which did not persist on the entity", e.getStringProperty(field.getKey()),field.getValue()); + } + } + } + + return r.first(); + } + + public static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ignore) { + ignore.printStackTrace(); + } + } + + public static void indexSleep() { + sleep(1000); + } +} diff --git a/src/test/java/org/apache/usergrid/client/UsergridClientAuthTestCase.java b/src/test/java/org/apache/usergrid/client/UsergridClientAuthTestCase.java new file mode 100644 index 0000000..82ca3c9 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/UsergridClientAuthTestCase.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.UsergridEnums; +import org.apache.usergrid.java.client.UsergridRequest; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Test; + +import java.util.List; + +public class UsergridClientAuthTestCase { + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void clientAppInit() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + Usergrid.authenticateApp(new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET)); + + //should fall back to using no authentication when currentUser is not authenticated and authFallback is set to NONE + UsergridClient client = Usergrid.getInstance(); +// client.config.authMode = UsergridEnums.UsergridAuthMode.NONE; + + String[] segments = {client.getOrgId(), client.getAppId(), "users"}; + UsergridRequest request = new UsergridRequest(UsergridEnums.UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, + client.getBaseUrl(), null, null, null, null, client.authForRequests(), segments); + client.sendRequest(request); + } + + @Test + public void clientUserInit() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL); + Usergrid.authenticateUser(new UsergridUserAuth(SDKTestConfiguration.APP_UserName, SDKTestConfiguration.APP_Password)); + UsergridResponse getResponse = Usergrid.GET("user","eb8145ea-e171-11e5-a5e5-2bc0953f9fe6"); + if( getResponse.getEntities() != null ) { + UsergridEntity entity = getResponse.first(); + if( entity instanceof UsergridUser) { + UsergridUser user = (UsergridUser) entity; + System.out.print(user.toString()); + } + List users = getResponse.users(); + if( users != null ) { + System.out.print(users.get(0).toString()); + } + } + + } +} diff --git a/src/test/java/org/apache/usergrid/client/UsergridInitTestCase.java b/src/test/java/org/apache/usergrid/client/UsergridInitTestCase.java new file mode 100644 index 0000000..980a3e7 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/UsergridInitTestCase.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.junit.After; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class UsergridInitTestCase { + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void testInitAppUsergrid() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL); + Usergrid.authenticateApp(new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET)); + assertTrue("usergrid should be an instance of usergrid client", Usergrid.getInstance().getClass() == UsergridClient.class); + } + + @Test + public void testInitUserUsergrid() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL); + Usergrid.authenticateUser(new UsergridUserAuth(SDKTestConfiguration.APP_UserName, SDKTestConfiguration.APP_Password)); + assertTrue("usergrid should be an instance of usergrid client", Usergrid.getInstance().getClass() == UsergridClient.class); + } +} diff --git a/src/test/java/org/apache/usergrid/client/UsergridResponseErrorTestCase.java b/src/test/java/org/apache/usergrid/client/UsergridResponseErrorTestCase.java new file mode 100644 index 0000000..3533805 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/UsergridResponseErrorTestCase.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +public class UsergridResponseErrorTestCase { + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, SDKTestConfiguration.authFallBack); + UsergridAppAuth appAuth = new UsergridAppAuth(SDKTestConfiguration.APP_CLIENT_ID, SDKTestConfiguration.APP_CLIENT_SECRET); + Usergrid.authenticateApp(appAuth); + } + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void testEntityCreationSuccess() { + String collectionName = "ect" + System.currentTimeMillis(); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + fields.put("shape", "square"); + + SDKTestUtils.createEntity(collectionName, "testEntity1", fields); + UsergridResponse eLookUp = Usergrid.GET(collectionName, "testEntity1"); + assertNull("The returned entity is null!", eLookUp.getResponseError()); + + UsergridResponse response = Usergrid.GET(collectionName, "testEntityThatShouldNotExist"); + assertFalse("Response returned should not be ok.",response.ok()); + assertTrue("StatusCode equals than 404", response.getStatusCode() == 404); + assertNotNull("The returned entity is null!", response.getResponseError()); + } +} diff --git a/src/test/java/org/apache/usergrid/client/UsergridResponseTestCase.java b/src/test/java/org/apache/usergrid/client/UsergridResponseTestCase.java new file mode 100644 index 0000000..e158d85 --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/UsergridResponseTestCase.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridEnums; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class UsergridResponseTestCase { + + @Before + public void before() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL, UsergridEnums.UsergridAuthMode.USER); + Usergrid.authenticateUser(new UsergridUserAuth(SDKTestConfiguration.APP_UserName, SDKTestConfiguration.APP_Password)); + } + + @After + public void after() { + Usergrid.reset(); + } + + @Test + public void testLogoutUser() { + String collectionName = "ect" + System.currentTimeMillis(); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + fields.put("shape", "square"); + + SDKTestUtils.createEntity(collectionName, "testEntity1", fields); + UsergridResponse response = Usergrid.GET(collectionName, "testEntity1"); + Object instanceObj = response.getStatusCode(); + assertTrue("The returned statusCode is and object of integer", instanceObj instanceof Integer); + instanceObj = response.ok(); + assertTrue("The returned statusCode is and object of boolean", instanceObj instanceof Boolean); + + UsergridResponse resp = Usergrid.logoutUser(SDKTestConfiguration.APP_UserName,null); + + response = Usergrid.GET(collectionName, "testEntity1"); + assertNotNull("The response should throw an error",response.getResponseError()); + } + + @Test + public void testLogoutCurrentUser() { + String collectionName = "ect" + System.currentTimeMillis(); + + Map fields = new HashMap<>(3); + fields.put("color", "red"); + fields.put("shape", "square"); + + SDKTestUtils.createEntity(collectionName, "testEntity12", fields); + UsergridResponse response = Usergrid.GET(collectionName, "testEntity12"); + assertNull("The response should not throw an error",response.getResponseError()); + + Usergrid.logoutCurrentUser(); + response = Usergrid.GET(collectionName, "testEntity1"); + assertNotNull("The response should throw an error",response.getResponseError()); + } + +} diff --git a/src/test/java/org/apache/usergrid/client/UsergridTestCase.java b/src/test/java/org/apache/usergrid/client/UsergridTestCase.java new file mode 100644 index 0000000..5e1ab3a --- /dev/null +++ b/src/test/java/org/apache/usergrid/client/UsergridTestCase.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.client; + +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.junit.Before; +import org.junit.Test; + +public class UsergridTestCase { + + @Test + public void initialize() { + Usergrid.initSharedInstance(SDKTestConfiguration.ORG_NAME, SDKTestConfiguration.APP_NAME, SDKTestConfiguration.USERGRID_URL); + } +} diff --git a/usergrid-java-client-2.1.0.jar b/usergrid-java-client-2.1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..fa90a59506b15b276b763d3c3514722b2e7f88cf GIT binary patch literal 1992232 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

|nq0kV`N1cH8Jrm?WU2%an<;o1<%Txb|V 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

wPvlg=AL7Z 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

5)@~pku?FSuk0hNT$hE_Ek-+F_T8g znV?Tlu9za#mH0*_nL*1?sV_fx(UZ_FWR;`c@k0`deUda^rT7*Ub%j@2I78r6!r{=N zO|fEN*Fwra$8&iuQr3sGQA$n;FkIrsh&Ja(+UZF}elj+-sK0E(B22`%P{sGEi+%SG zQ~kx3t4WdBpYpX62E=DgUxh5aC0}VE(nq2q$efhdjc5DKBT4TSBxNP5WFygY}D(E>Pce@Una#X#A7DPYmBln|huUY$6Fy~D0*b|F|0}Q4%%C4r| zFtUcB3dF{oeCg+<>P8#t6>n(Sr?jpaNUoK!nMq5Opf`=N1sPD|2$IbxhRY{tGqnV` zjHfSpM@Q_otA9^vEzT8GwH+Va1&1RgVJ;sEF4o&rRmE=2k#?P7&2 zVnjYBl(zV3?}_>sG=2t?x%7610rkd_a&5d?Xe`JiRacUg2701KxPsP-I&_)t2E6k*Tj2Vt=BHOhZ+e)#s-BDnw zY8Ic<3>q4%^|JbOIsGrBZ2Iw-+@?5R;OT%@(^R<3cGc4*g~i^OVqePW5xqlt2C^tu z=;^U2LtuUB)@x_Y5Cet&?)6~+Bu=scbF~41ro139cZ@y!AEafgNO4JT;_u2)z@IJC z^|fY3abl7AUNMBDOxIV*z*S^cck20Bxe###e;*49E1jqdS*#t7mHb@#5hZe=DmDKB zC#^dra{Uo;U2z(nel<2QqY7G*gR5g61}oI@5757I-hO$?f!>mf*W}b)gcJv$Ot6F$ zgq@tgWp7|=lOQri_Q>mQUke3N4bPHyS}dGP6j_k@YYP)pT%9Dl5&fy#wrk^X3Ou7R zL-RAhU&T=W-~!u1GEc+|Y3Clfy(+@}`%-vL6uZ&5;Cykd$B}XcpoE6LhZUGGouP}$ zpdQMkByt1pJkcojn+~D#NH6`wxdaenUO?!^Fr{$x16y8PxF8MW=Zj{T&;C{eFcQ_$ z~>Qf?zSFH`8Tks*VR}5naL584!WJ4E9m&w4oBwz2K zbhm7{FC8Y(9b)m%gxD8Kp1<$&k$!SW-z%Z8rFGhXum^EBI9^Ry1*G7Qg!21dIf!>j zzG$=)mcsYhRGP6`C|yT5yp>qJWv2oF6sFkj{-au~jB20$Rr~NAdeMpUippuBs=Z6g zfwBap2X5*3~@W05$B->FN25D^_`o^9lEuXeak^)kR!QA0`?~a>sq0_ zp3FJS3vFZ0dh?5hh7z8eZAMqcI4pm)~v2jA}W*A5P?J>6x5enA@w&Q z5>pByL1@*ufNzr+L*ep;b#O;2GkI#4(ckpV0sX5Nb+B431NLJiUD|O^eGQu$cWqKf zzDJB~oB)T1F?hfcON4i?Pinc7Nj8qOkr?utD04I#dGeo>K~d(!@;x#dG?6AIk_EBg zaW<>~odpTXqi-HT#yf+=%{noGmS|Ou)Q`#s(gFLz1F%yrC21^^A4Y=8Z(s!YcO+Q; z5Ey^~b^}pNsIk^LcPKIv#}JIxG+5o*I7-aN1#h+=_NO(#!9Q@ic-k7t^nt)L=JU`V z%NNUjV>c1N1I39Odx(L}91L|idrUTW+Ma@i4Nvb;<(R3flyk=(BX^`y z?+HZV6xHnrW^cm;`jr#=w=w8eFHtN}R6Zg}QKi&9puw%TVd+ZpcXW=|9dSD-F+|t6 z?!+zPK+bW8ZfHYS6ty#&{cfc5N*CnrzEP5)_Ao5s;PW`yXwyE8n(vNeEPRv~qT5!M zC$uBf6Oki@0Q0fMO;UWa6fSRhb+7dc8^B5g^zSDq+A!iEC+Rub|R1NqAF$BE1_nO;QF1bLkCGvR#G3$8=z6xx7pJ>FmtvZ>1Phe8p zMQ-C!gslP9I2b`GczfczkjS2<0*=v{HNieRzt|Cx`Lf$g{%vO_~xVo8a5B z)L-$9p?7AS6s>Fi%8W%2ag#nO*@+Uhq~b_7S=WRaIR;HxRXA%y?it!)#LVuk1)V=+ zYh@fD9wm?L5X<;Lb?g%=lJS!ieK4jIeZjLHdX}f48ir(J^?XZ)OLeq>;!loq&`Qu# zrEnhd3oVR`c{cp|PJk!506R_YCdb>F?L*-tO_Y%J zXwJlUDvM_;D;p!`uO4SRg>M-^_cW-6H>S=rf(J0|j!`5&rc#oiz2 zSK3=?mHawNCfS-zgrS2&89&k9WX11>GbxSsQPJH9ZCVY5RdeoK<1#4_&E08d0DeFo zoZu<})t5$)MJsrvoMPh(=S!#A1@;c5-E&QXx#w8D5u+ zch|WCqqgiT>j*-upPp>VBwTZcNX3X;dA8p{nKsHxfiuSw*o-?A^`^-4Pr3&Ox4TI* zs`;4ihn*+8SY5vMP9a9u3oi9#$0*rvbW^{9jQJKxwHo{6bBg%5sX`iitX`X_x&QT65pkuJkt`=bmAU=4Leh zgFv6?W^C#Z)U(A0%ON#xpY)y?K!>;+cPQkeO`yKNCBfoBnY`<9OM&thx9jc6O3Q6N z#O?{ZNZo)Z+>T3cI3!jN>`)?0j!Rg8_r-C3P!&&FN)z25cGu;}JMn1Rjepb6I}sy0 zlBL>9X+%)*sRy=Rn7l{JL}IZ0yscNa_uT7GuS!DQ?)zhXV5Fy;c+I}V@~z^2&d!$% z`J%dOh@pB(ToQkza%<~=$`@QE?K3(m{@26<c{9RSTGpBBX#U7CGz+UE z`Lsi^`Ozv}Fm-x?|K=42B|f831!sjP*_G^CKa(Ue4kI8UD*%If*Z{W4Oli)0yz47! z+#13jxi%P0HVmCEc2X;GFZz4{O5uDXoa=RS(T`y}q77^J%@Fp4{Gtbo-se!V-=jTc z^a5&NscUH{zrwrxE%ElQ;ufqP2&eIcdzDFyAGj$yu@f?S=ljA4k*K(QoBGpkn{f?9wyg@G8U*@n$%As)M)$SdAVU%xB;_P{T(y?1{pU9 z_r#eFbO{IYN!l_Hw@28|xx>*8y*d!KOaOL}*H^I^dIAH#ZF)?Ixm4jk_~WAQE4iV5 z@xI0c-8cWG-}CUFL^lqNwow#05YU3+|9^XzoSCbogXw?lT_K5c%1er9qkU|0-Vq_j z$pR!qB=a27uxNVu2jwMDBGN2&rh5#{9+vrX);Q@#H!|a}?M?^c_?Z0uh)13%I8>*C zEEAtUjmy7JI8XlW`2GF@Q5nS@bDB@NKU9<$5y`={w^#XRq3Z-Qcx6 zw_9j?(??Qe>a=NhrCLBf=rb)G|6Z~KtNLz-#;Sf*|ExE5^IG=+eC>@tdA3QD-n=<% zjY8X9Io8>|rv-@+I4GKL-(+6vT&t8|wwk;%f`_kfF&Mqcb>N0%cUg^_WvA$r_<6fJ=_rG&M`PMSD=B=rP)u zHOXqB`=*5g7ggf+M2oiAo~p5icq@XDxeaYCdRT*K#y2&zG|8K%TqV{n*vm26l`%z7 z1G91xFa6SEQ`zCoXV8Voc}zQ38LC!)p47^<%WoQH*^V#*iwg$c3I*W-$;=@Vk7P)$ zgxW#k6%$t*R+O!h2B48vl7x_y&_JW)#Yg*z>wXAtif)yBQ)L9I!jS%pHO4U+H_T?E z!q`x8jUIJ+LqWnE(OB-y*Z5;NObW+5C@GG0i4!eF!!1@)cIGRH#mZ?cn{DEAX;fVy zz~mT7u9iTGLtWT`zEDh(Iq@nAcmkWOa$A5r6;bO+3MS;994-34ID3aE(Y9?_bgi^)W2J4| zwr$(CZQHhO+qRu6&7b?8+uHx_w|92o6=q@1>g;2TJ|dz=ydGzAoNV9i`1E}LV(qUE zpaRtaYW{I-b>8H@0?BgzY+bv0nR34{DcN|ygyw;R>*lRPxmXmnnl@t0#X>y=rwjoX z6R>K>l{J^%-%jXl-Uzj+i8{k|GtmB&(<{`ck$r0>mo5EIAb*!b5^_Em#@SE4TI~9IbDr?LWoEUA;cuG4I(-vgxTy2j?5wCb~w?rLnOHOW!(9W3W zCds$^1*!v_ncx@hN>Y1jAtgo?Zzhgqy-?LD#zKD`HMFTm_G71cTo4O-9hk?iHekM{ zBRQ6N$ET%3CI#@m!0w3*y)h9YAA)oj8sHim_@E_psa;>*Yn$K_!g9|CaVc5DJZ}f7 zd?qBX<5m@c3E`%Cgun0dpg}`(x|`Aa)+o0sW*B|{!J!xIgXFVr~`OO!}&h>lBtNVrUIn1$%O0`0s3loPTeRe7(jI|bn^JKXQ{ zPbtjV?eVqz%oo!Bt0nBu_V>%i!t^J;h=IoJp9vdlJxiK@UTI`3M2++ejqDx%QwdqB z;I4{G$X_<}3^zviqW!VIMZk4e>k*8=Wl`7R3iFk#lr^54JS?8QY?Knep1WBR#Ef4aC_FnoZrYwRJ+8lV9Immm zJx{(2exZaKX*=%0&|D8{X?Nm+cCv3SjZCIanA?%Fwhslxh@9=T!q=!6ifEgvgv^NhYQHw*L^`uUBE5uZezvrN~~} z|A{|vXHVx)Un;+zj()n{9lnlc(wgGCoA}K9hj~OH?jQYOjn4sT8cQvv2Z6X#sWQvC!_#DN76$A_SK(JF_z>{J`qb zpEM?mSu_TG!gFYli-`*4ZzoyDhz1j4Wr5P~rPEy9G)7)K)eUA>)sm`biWZ#pv#uHsCJ%BGg2teM#5 z0~1mYja*7u$PZ$t+qq9^VnirGBk(5?O!&<`|0DBH zg`wflq-(!94()&*3e?3PYLg0M-&G8Grh$w|7NsZZ@xcoEK|?wr#1b?D zJZUD|BG#xf(u+9!;&6Ha$pIX|l!B-aI)Z1xFir}J6z3(EdT{+g!JH2Vp+v9{8~XW{m1bFd)sWIA@h_FfsMnXdGwg; zRkaRJQZ`;BfiC0tezAgnQ%=V)vx}q0Tl*!Ced04Y7O0N6L1PMS%*Y4fcm8|vx#hvP zgW^sbk|-PtH%{y8M10*)b@1TSyfC-mQbZH9eM!09B+N) zK~Y5%1`sB@JtFIAYU8#2CXy77XTE>LR_BVs#FE=uDcUg`J~0TH;i8W~)3qYX%5K$fild z#8);w$)i8%sE6(}$T0=kXSB>G^vQ)b6Jp41}>&QM^iaN zQyA0r@(8F2SDWFNTJ=QpG+N#7ld^y4s+UbD?_#WXu%JV(CJ)@V)-fcm6(gl9N4qE8 ztlg|c7L5*TOvl0;!t7b+=5fP@tBe)si|)SSg2Ao-+II(PykJ@1SfA}3xEYA7gzKhs zo-t^xi<@ID0wTAW94@S7g$4<}+SANrwKNNtMCuP)@#)hdX&}n+Da0Av zBx7Z?h&JU(JvC?qdrMeLM-*N;0ZPUTPF^-0j$>hpIw0;V^B9nQcETuHj@Hq&ti@(D zV@b!K@}m68(qm{#ODW`41A$aqxc@ywKZoAJ9O4Wo$AHpsNLc#Br4%Jc{$RL>vM2ea zdAWaM$08kPl-1=+xlpck(Rh*h zrSro(_GeIZcgy$*POu5kx+^3FJ*6w1Z>;(2t{vrrLlb9J&AFXv(JZWTRIf*^(o-vc z$uSTTfsWb(JiIP)Q3V+ntdObFGRXoz{7L_6`O_VKesA=BPB5oeP%zq7H=3QvLWbGw zlrtR*L$t0xug4YqtycqR!x|ZiD;N=U^|`MF8luJF3X8uOOJA0c?su4q7HDbu*_^s0 z;nZKTJA!x$uJU|O4Dq;JT>ByYKgiDYEP_yh=T?NcZsQVwuOoX)wO-d5iAc9$%?wkq zqlTpqy{w)z<703+uF>9I1F?MtZ(a#8y5cy)8>ch1db{!=gx&OQZs_$G3X} z=2If4kUHtj*mI(b5Tr8EyNSymMU5z`%uSZKlsjcg3L$puw8h&%Gv1D)a_DzF{$}wB z`30%nU)+lM*ab!L|!6TmgM*0=C=qQYmm9lsF1af;i4LkUBvyOU`Cq zQH{!+%~)bno~t3M>{&^GgEg)z7U$QL z>{AyC)!1{)A`pC{Rw{8+_@7#Ew8Z;dA8B|u_ffuIwq&s)gg zf`M#dC0o9(sFKI;oM)N2rhHsl%L?jdxRh?Xk?c^o&aiO-=mvH!8El!oHm&}&J&Hj| zv%dz}6yLE9zzG@3Fv*R#r(eD%`iSS6tqmu6cgp`n~)z^j^DhQ?`<7gR`SXs49OG zS9bCYRp6Jlk~VtFO^sU zZc=Euj5V}&0qEZAfp&t`XHWe4g{a|t#NhAGRIt~O#s?S)*Gvd?`wqSU2U=;O{r4<@gr4UUharFe@)M`O0OBxP#}9uen?4762xe}|AcPcVvTf>Ag%H(X_?1FvqS52%78IOUk6 zoRs*M=%kjS!z+U$Y%;eJ&%aEzL-}9tE%HWsmhwgpwl>xdM*KF0ZvVNyM9E9pEbzj4Ww1K! zw--W-K?1!27uGE-H~yv;0&7CxS5hx5E+4eZutZGI6^Ra5)ENXX6GbA2!D743fYW!z z2Kd8myO!q0VY5AX>HYnBMBz)0gE^|p7Qm={SeHJm1^8^c!wYT!GG6Pr%1#dDu5nuo z_6Fs^)UyCHpuOY<&&L6!;N=6y2qfS~t+lg;otYKJ%Xk5i3@)QN1D!*!dIauHImE6v z`}9G)G`XxPg9Wpl8NQpE;|xBw^Z{~{ecPLK2e;VYEOGT&cH^E0#<}fec!~wS&4uup zee*a}y~9~jT#U(GnFYA5 zu+P5iWC_PksfwsgVaf1kVwroupB$?NneaZlqyD?!H6%lRWsu1-otD!Uv>*B1LrdB1P0&c9BhJ;goXTEdyd3|C~Ut*IsbI>G1cF7;Vfzhn98rljiqjjB14**ZLh}r{=~`wlHVm454#Oj@@RzX&y82I4HYNg^ z^2#Eee=gUhSRthnKRAoSzv3+aR-|@LMh=cbuKyTXnA!ZVnMIVGl*ErOQ>Il$;jpPi z6Ye?=rI64@!a3rYMFrQEf-+td#BWKsATV4;^jdabUtDDL zxq0SzF#vsU06uK$gsZPRB%iK=V#c#M$TLKi54AMjVGyr{e1gf9r4soTghblBR@c(J z+Jj`kT8do!75qvA^{h$yC{UGx)a1%>h&Y1B(w#8*IHSxYqF#8PoK6aao*ee{`qGz) zJjoPd561Z_={2L15flviL}B>LaCOYxzyJAhxl1>_IzOmL=)bxy{iHMf7gR*v=zo5k z#W2)6mC_kkHn)4|R+;wAge+ru)Vh;VmB zPC-v2l*?e}=E-rrZZj6|C$Ay;1|>v|J>1*hAI`4Ty1!mt(0kFYh2aNMgAwHdX;Fs6 zGUeyZnli)mIi|_C*qX3aHo}-QRWihivdu@dB}M20AkEX3Y~==s{FcENn773IZ1r8m z@aQ$j#r>))%_c6ELMZ0PFey-&>MYB2RV9KA%Dr+UTP=)*c6FN{bf=sq4A2*xiwrQ8 zg{>G`4hzaFTgjJMe=8SN>_K$hUl_4p{B5SnQky7M{1cEVVJQgyG2HMRH6lEmY;8P8 z#-+wn_%R&fRb{kVk(POp`b2JE5q(2Y+l3#_>!H^6UdoXUVuX#QR;CU$y8`#kztk8$ zpEuW>X@P`8iDneT!+}3*vkqLLp2(o&QgxVm{nn`^qM`fZW448O3Z_blah=ZVx!@3e zVKrht&86v7>Au|)sdieAO1eB*5hOa@9?a%vTCL~=abI7izOI$>8G64k7ohE@up9KTmm( z-n+{q62@kIY;SPXO=(+s4feoDc7dY7V*~SS1FiQLSKPUVbT-3OeP6jiGnsiNh8QCT zlZzSDSV#ZKW`rxy!g2!zE@xMVZ+&x~#ynk3&W?QB=~z%maqa>Q6c3BZ4ApfZ;;Zzm z@47f0+;6%nX^>Qhn66YNum&+2&^4x0C4LuoHr^BVE}0*UqpjQprZ!{PYgI_>IjZ#R zpaI&WmIv%MJz0;N#+(22+9MEkehh(vO)hj)=7 z!pSuTyECBAz8BED z``UK=b!OTKPAUMtC45%#K&RvOXWF7Zd_J;eNMWR?4{xe=~Jg|4O>o zM_a{zEa2#3iO}&^lFHC0dNyl;d5Q23(0P}<7Pv23T-rT&R3U$`*rUG}zk37xvv@aH z{IE=a;LH?|e`^hX{CWTD;&rrl)6=&!QZTc&_}}HLXz^ojissEM)sRtJ^f3HcuNq+H z4(<;CkZ(n`&S+IfmbmZKz-E?W>B2AuGIa9=_^}%q(9?@W zd^eCi;o-J@(v|snveWYgVvF8{G_9{ZB0@Gun=yz!IdWD3jp;C`KqdCytH=K{ck#BJjhlzR@+mS$W;aL#gSzwo$qn;h(F?0t#T zvX)E9_<*XZL&?-4p5JYr!YK{{>1W{aeA!NM6Gw|<-3|?H=5HOWcV$0ql-h3N!R9tq z6@03lb;75K2tTH~6bpFICNLu$RqI`` zb14^%Rf%t8Ku%Lg8$^mZ(O4}X=X^F!TFlM>Mri1wxk9{|=DRH9iEv{OSaQCD5FgQo zz-k{lQv67Rm@<>)jtR^|zWvY>{`h(^fYuhEMvDM?ByqmsGfI=Lvg2!5a^Z12e(;X8 zOHAg-Wa+#wd7`aWa+P#!XpUBYY@CU>Ql6plydVC$U^L&7KbK(4(v-CY)oAwzn5ta;I_auhV(Pv6=yGsa4Ps9q4B_t)u(~u4$7BiE zpaJPW8&R{gg^QijG%kwd+qOLh90<-;#Gc*JW0H9t&Md<)q51ap&?T>o+7;71(pG_d z5`}uK4zsZ+gf;sEZkTMc@f~>=bP^^CtV>7YMfm+@Jy=pc1PL=0Eqcz<91S|^+UW<3 zEJKi_4g(n+bZ6cJJ>dVpPf*!fFEv42F?y~ZDgk_*4a8Yq0iYmH5od$l#+Wz zok7)|QR^PDA2>xgJ?3!aPaq6p#pL(`Dw9Y909g`rNdere zPYl&g#=2o7GIn_kAqLoNSSM`y)LFw-R+*>LdsV-<`%w5&7u8GUN5|dXF7v>$H2jwImPZ+7P{uEHaFLf{}Ow0v_;f>bw|>k+&!RhpJIud}8qX=_I56 z)hvztzwc`{PL4+Z|6Wp2OJU(B0a8o?ut-*eQYbupXEtB%4pR_`Cpa(M03Ca{B(@qZ zOpHWqjs*9UqB}f?VfwTH_KSGr&Jc4$QFl1xdb{g~mpRGqnwr_s=>bd~u3`kCT?*mL zly+c4RBsP%Fv}cpgI>U(Hf>#vkieiWnTw&os5Wmc)}1U}v6vDbK?3!qx`YtSuQy5B3UFkX%Xn*^PVra>`N>hz73ceKF+MVW2c z1MIN{SA~dt#%(|eX7a_DF?t;%uL#K!odK`dt%^r_*y-EDJ_#tAnsg%MJDIh-T;^T8 zCm*`FKMOx!a$mLRky=pEPENfG3ouvsVY!<~am>@w!4o6t-yo1wbjHGRNQ|a$JV@HD zK)gaZQP>kpPV0iLFpT2o^yx*K#13%-zq7YaSj?<3^wFmdKm#Xb71W+u-Z}A)A`cWa z)A?i48Vxw;G;cfSN+?AOl9>Aeo|w?aWN3}ijUIe6z+q)d z-xnxTEGMg4gULK0Kw_;~d~ghGPU&!)jOSBlTppQo78jjNE@V}YWl;mOox5qIHt&VK z?WF&;>r~%Wn|4RdMk>B&0H_KVe$>*q#^tRvFoB|(J$UO z3!+zOu8Od-b(6yEPNDlgW<+@)j$c&k9%`1VD5rbwLE9FMCTa@Xs|Ez+W(Xe;gb!H-Gd|MnLu|4W-1$EQf*h@pw{1H|dU$BXg%;_3Rs zL*d26;{9gKUBY+!LpU($Xv`n5wP=odWnKl@

7A)f*p}N^VZ2ew9yEwe&-$YG`!a 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