You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2015/11/02 23:56:36 UTC
[45/50] [abbrv] usergrid git commit: Merge branch '2.1-release' of
https://git-wip-us.apache.org/repos/asf/usergrid
Merge branch '2.1-release' of https://git-wip-us.apache.org/repos/asf/usergrid
# Conflicts:
# stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/AmazonAsyncEventService.java
# stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/EventBuilderImpl.java
# stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/InMemoryAsyncEventService.java
# stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexProcessorFig.java
# stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
# stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
# stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
# stack/rest/src/main/java/org/apache/usergrid/rest/system/MigrateResource.java
# stack/rest/src/main/java/org/apache/usergrid/rest/system/SystemResource.java
# stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/b422364e
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/b422364e
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/b422364e
Branch: refs/heads/USERGRID-909
Commit: b422364e20c14a657de076b793bc6b7c1160a556
Parents: 9d3cf5b eb2756b
Author: Todd Nine <tn...@apigee.com>
Authored: Fri Oct 30 16:32:23 2015 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Fri Oct 30 16:32:23 2015 -0600
----------------------------------------------------------------------
.../corepersistence/CpEntityManagerFactory.java | 7 +-
.../corepersistence/CpRelationManager.java | 16 +-
.../asyncevents/AmazonAsyncEventService.java | 99 +--
.../asyncevents/AsyncEventService.java | 5 +
.../asyncevents/EventBuilder.java | 25 +-
.../asyncevents/EventBuilderImpl.java | 60 +-
.../index/IndexProcessorFig.java | 15 +-
.../corepersistence/index/IndexServiceImpl.java | 5 +-
.../pipeline/read/FilterResult.java | 7 +
.../read/traverse/AbstractReadGraphFilter.java | 136 +++-
.../read/traverse/EdgeCursorSerializer.java | 8 +-
.../read/traverse/EntityLoadVerifyFilter.java | 24 +-
.../traverse/ReadGraphCollectionFilter.java | 11 +-
.../ReadGraphConnectionByTypeFilter.java | 11 +-
.../traverse/ReadGraphConnectionFilter.java | 11 +-
.../results/ObservableQueryExecutor.java | 7 +
.../service/StatusServiceImpl.java | 3 +-
.../usergrid/persistence/CredentialsInfo.java | 46 ++
.../persistence/ObservableIterator.java | 83 ---
.../index/AsyncIndexServiceTest.java | 3 +-
.../corepersistence/index/IndexServiceTest.java | 12 +-
.../pipeline/cursor/CursorTest.java | 24 +-
.../service/ConnectionServiceImplTest.java | 5 +-
.../persistence/ApplicationServiceIT.java | 4 +-
.../persistence/core/astyanax/CassandraFig.java | 2 +-
.../core/astyanax/MultiRowColumnIterator.java | 46 +-
.../persistence/core/rx/ObservableIterator.java | 2 +-
.../usergrid/persistence/graph/GraphFig.java | 4 +-
.../persistence/graph/GraphManager.java | 14 +-
.../usergrid/persistence/graph/MarkedEdge.java | 15 +-
.../persistence/graph/guice/GraphModule.java | 11 +-
.../graph/impl/GraphManagerImpl.java | 90 ++-
.../graph/impl/SimpleMarkedEdge.java | 62 +-
.../impl/stage/NodeDeleteListenerImpl.java | 27 +-
.../impl/EdgeSerializationImpl.java | 17 +-
.../impl/shard/AsyncTaskExecutor.java | 34 +
.../graph/serialization/impl/shard/Shard.java | 15 +
.../impl/shard/ShardEntryGroup.java | 13 +-
.../impl/shard/ShardGroupCompaction.java | 4 -
.../impl/shard/ShardGroupDeletion.java | 78 +++
.../impl/shard/impl/AsyncTaskExecutorImpl.java | 53 ++
.../shard/impl/NodeShardAllocationImpl.java | 81 ++-
.../shard/impl/ShardGroupColumnIterator.java | 72 +-
.../shard/impl/ShardGroupCompactionImpl.java | 10 +-
.../impl/shard/impl/ShardGroupDeletionImpl.java | 230 +++++++
.../impl/shard/impl/ShardsColumnIterator.java | 10 +
.../persistence/graph/GraphManagerIT.java | 76 +--
.../persistence/graph/GraphManagerLoadTest.java | 10 +-
.../graph/GraphManagerShardConsistencyIT.java | 382 ++++++++---
.../graph/GraphManagerStressTest.java | 16 +-
.../impl/shard/ShardEntryGroupTest.java | 14 +
.../impl/shard/ShardGroupCompactionTest.java | 30 +-
.../shard/impl/ShardGroupDeletionImplTest.java | 341 +++++++++
stack/corepersistence/pom.xml | 2 +-
.../persistence/index/CandidateResult.java | 11 +-
.../persistence/index/EntityIndexBatch.java | 2 +-
.../usergrid/persistence/index/IndexFig.java | 6 +
.../index/impl/DeIndexOperation.java | 5 +
.../index/impl/EsEntityIndexBatchImpl.java | 34 +-
.../index/impl/EsEntityIndexImpl.java | 188 +++--
.../persistence/index/impl/IndexingUtils.java | 2 +-
.../persistence/index/impl/EntityIndexTest.java | 14 +-
.../usergrid/persistence/queue/QueueFig.java | 2 +-
.../org/apache/usergrid/rest/IndexResource.java | 350 ----------
.../apache/usergrid/rest/MigrateResource.java | 275 --------
.../apache/usergrid/rest/SystemResource.java | 111 ---
.../rest/applications/ApplicationResource.java | 50 ++
.../rest/applications/users/UserResource.java | 134 +++-
.../organizations/OrganizationsResource.java | 33 +
.../rest/system/ConnectionResource.java | 216 ++++++
.../usergrid/rest/system/DatabaseResource.java | 2 +
.../usergrid/rest/system/IndexResource.java | 353 ++++++++++
.../usergrid/rest/system/MigrateResource.java | 277 ++++++++
.../usergrid/rest/system/SystemResource.java | 121 ++++
.../collection/users/UserResourceIT.java | 117 ++++
stack/scripts/create_test_data.py | 222 ++++++
stack/scripts/migrate_entity_data.py | 18 +-
stack/scripts/multitenant_migrate.py | 683 +++++++++++++++++++
.../management/AppInfoMigrationPlugin.java | 5 +-
.../usergrid/management/ManagementService.java | 14 +-
.../cassandra/ManagementServiceImpl.java | 43 +-
81 files changed, 4231 insertions(+), 1445 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/AmazonAsyncEventService.java
----------------------------------------------------------------------
diff --cc stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/AmazonAsyncEventService.java
index 14fbdaa,6b9abbc..e5c25fb
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/AmazonAsyncEventService.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/asyncevents/AmazonAsyncEventService.java
@@@ -315,25 -316,34 +315,31 @@@ public class AmazonAsyncEventService im
boolean validateEmptySets = true;
Observable<IndexOperationMessage> indexoperationObservable;
//merge each operation to a master observable;
- if (event instanceof EdgeDeleteEvent) {
- indexoperationObservable = handleEdgeDelete(message);
- } else if (event instanceof EdgeIndexEvent) {
- indexoperationObservable = handleEdgeIndex(message);
- } else if (event instanceof EntityDeleteEvent) {
- indexoperationObservable = handleEntityDelete(message);
- } else if (event instanceof EntityIndexEvent) {
- indexoperationObservable = handleEntityIndexUpdate(message);
- } else if (event instanceof InitializeApplicationIndexEvent) {
+ if ( event instanceof EdgeDeleteEvent ) {
+ indexoperationObservable = handleEdgeDelete( message );
+ }
+ else if ( event instanceof EdgeIndexEvent ) {
+ indexoperationObservable = handleEdgeIndex( message );
+ }
+ else if ( event instanceof EntityDeleteEvent ) {
+ indexoperationObservable = handleEntityDelete( message );
+ validateEmptySets = false; // do not check this one for an empty set b/c it can be empty
+
+ }
+ else if ( event instanceof EntityIndexEvent ) {
+ indexoperationObservable = handleEntityIndexUpdate( message );
+ }
+ else if ( event instanceof InitializeApplicationIndexEvent ) {
//does not return observable
- handleInitializeApplicationIndex( event, message );
- indexoperationObservable = Observable.just( new IndexOperationMessage() );
+ handleInitializeApplicationIndex(event, message);
+ indexoperationObservable = Observable.just(new IndexOperationMessage());
validateEmptySets = false; //do not check this one for an empty set b/c it will be empty.
- }
- else if ( event instanceof ElasticsearchIndexEvent ) {
- handleIndexOperation( ( ElasticsearchIndexEvent ) event );
- indexoperationObservable = Observable.just( new IndexOperationMessage() );
+ } else if (event instanceof ElasticsearchIndexEvent) {
+ handleIndexOperation((ElasticsearchIndexEvent) event);
+ indexoperationObservable = Observable.just(new IndexOperationMessage());
validateEmptySets = false; //do not check this one for an empty set b/c it will be empty.
- }
-
- else {
- throw new Exception( "Unknown EventType" );//TODO: print json instead
+ } else {
+ throw new Exception("Unknown EventType");//TODO: print json instead
}
//collect all of the
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexProcessorFig.java
----------------------------------------------------------------------
diff --cc stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexProcessorFig.java
index 69d5e18,9d02717..c991b36
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexProcessorFig.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexProcessorFig.java
@@@ -70,10 -72,19 +72,19 @@@ public interface IndexProcessorFig exte
int getIndexQueueVisibilityTimeout();
/**
+ * The number of worker threads used when handing off messages from the SQS thread
+ */
+ @Default( "20" )
+ @Key( EVENT_CONCURRENCY_FACTOR )
+ int getEventConcurrencyFactor();
+
+
+
+ /**
* The number of worker threads used to read index write requests from the queue.
*/
- @Default( "8" )
- @Key( ELASTICSEARCH_WORKER_COUNT )
+ @Default("16")
+ @Key(ELASTICSEARCH_WORKER_COUNT)
int getWorkerCount();
/**
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexServiceImpl.java
----------------------------------------------------------------------
diff --cc stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexServiceImpl.java
index 7efe8e4,b2a1a2a..301a7ae
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexServiceImpl.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/index/IndexServiceImpl.java
@@@ -218,10 -219,10 +219,10 @@@ public class IndexServiceImpl implement
//collect results into a single batch
.collect( () -> ei.createBatch(), ( batch, candidateResult ) -> {
logger.debug( "Deindexing on edge {} for entity {} added to batch",searchEdge , entityId );
- batch.deindex( searchEdge, candidateResult );
+ batch.deindex( candidateResult );
} )
//return the future from the batch execution
- .flatMap( batch ->Observable.just(batch.build()) );
+ .map( batch ->batch.build() );
return ObservableTimer.time(batches, indexTimer);
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/core/src/test/java/org/apache/usergrid/persistence/ApplicationServiceIT.java
----------------------------------------------------------------------
diff --cc stack/core/src/test/java/org/apache/usergrid/persistence/ApplicationServiceIT.java
index f8079e5,658d3eb..9ad90eb
--- a/stack/core/src/test/java/org/apache/usergrid/persistence/ApplicationServiceIT.java
+++ b/stack/core/src/test/java/org/apache/usergrid/persistence/ApplicationServiceIT.java
@@@ -85,15 -87,10 +86,16 @@@ public class ApplicationServiceIT exten
, Long.MAX_VALUE, SearchByEdgeType.Order.DESCENDING,
Optional.<Edge>absent() );
- Iterator<Edge> results = graphManager.loadEdgesFromSource(simpleSearchByEdgeType).toBlocking().getIterator();
+ Iterator<MarkedEdge>
+ results = graphManager.loadEdgesFromSource(simpleSearchByEdgeType).toBlocking().getIterator();
if(results.hasNext()){
- Assert.fail("should be empty");
+ int i = 0;
+
+ while(results.hasNext()){
+ results.next();
+ i++;
+ }
+ Assert.fail("should be empty but has "+i);
}else{
Results searchCollection = entityManager.searchCollection(entityManager.getApplication(), "tests", Query.all());
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/corepersistence/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
----------------------------------------------------------------------
diff --cc stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
index 1ffcd02,a8fb751..a49e217
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexBatchImpl.java
@@@ -117,7 -136,13 +136,12 @@@ public class EsEntityIndexBatchImpl imp
return deindex( searchEdge, entity.getId(), entity.getVersion() );
}
+ @Override
+ public EntityIndexBatch deindex( final CandidateResult entity ) {
+
+ return deindexWithDocId(entity.getDocId());
+ }
-
@Override
public IndexOperationMessage build() {
return container;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
index e830876,162565f..769b836
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
@@@ -17,7 -17,9 +17,8 @@@
package org.apache.usergrid.rest.applications;
+ import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sun.jersey.api.json.JSONWithPadding;
-import com.sun.jersey.api.view.Viewable;
+import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
import org.apache.amber.oauth2.common.error.OAuthError;
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.message.OAuthResponse;
@@@ -47,9 -48,9 +48,10 @@@ import org.apache.usergrid.rest.excepti
import org.apache.usergrid.rest.exceptions.RedirectionException;
import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
import org.apache.usergrid.security.oauth.AccessInfo;
import org.apache.usergrid.security.oauth.ClientCredentialsInfo;
+import org.glassfish.jersey.server.mvc.Viewable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
@@@ -601,6 -601,54 +603,54 @@@ public class ApplicationResource extend
if(value==null){
throw new EntityNotFoundException("apigeeMobileConfig not found, it is possibly not enabled for your config.");
}
- return new JSONWithPadding( value, callback );
+ return value;
}
+
+ // Specifically require superuser access as this is setting app properties directly (only way to currently do this
+ // with Apigee's apigeeMobileConfig
+ @RequireOrganizationAccess
+ @POST
+ @Path("apm/apigeeMobileConfig")
+ @Consumes(APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
- public JSONWithPadding setAPMConfig( @Context UriInfo ui,
- @QueryParam("callback") @DefaultValue("callback") String callback,
- Map<String, Object> json) throws Exception {
++ public String setAPMConfig( @Context UriInfo ui,
++ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback,
++ Map<String, Object> json ) throws Exception {
+
+ if(json == null || json.size() < 1){
+ logger.error("Param {} cannot be null for POST apm/apigeeMobileConfig", APIGEE_MOBILE_APM_CONFIG_JSON_KEY);
+ throw new IllegalArgumentException("Request body cannot be empty and must include apigeeMobileConfig params");
+ }
+
+ final String requestAppUUID = (String) json.get("applicationUUID");
+ if(!requestAppUUID.equalsIgnoreCase(applicationId.toString())){
+ logger.error("Provided application UUID {} does not match actual application UUID {}",
+ requestAppUUID,
+ applicationId.toString());
+ throw new IllegalArgumentException(
+ String.format("Provided application UUID %s does not match actual application UUID %s",
+ requestAppUUID,
+ applicationId.toString())
+ );
+ }
+
+ final String apmConfig = new ObjectMapper().writeValueAsString(json);
+ if(logger.isDebugEnabled()){
+ logger.debug("Received request to set apigeeMobileConfig properties with: {}", apmConfig);
+ }
+
+
+ EntityManager em = emf.getEntityManager( applicationId );
+ em.setProperty(new SimpleEntityRef(Application.ENTITY_TYPE, applicationId),
+ APIGEE_MOBILE_APM_CONFIG_JSON_KEY,
+ apmConfig
+ );
+
+ logger.info("Successfully set apigeeMobileConfig properties with: {}", apmConfig);
+
- return new JSONWithPadding(apmConfig, callback);
++ return apmConfig;
+
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
index b84fc08,fb2962e..130658cd
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UserResource.java
@@@ -17,38 -17,63 +17,63 @@@
package org.apache.usergrid.rest.applications.users;
--import com.fasterxml.jackson.databind.JsonNode;
--import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
- import net.tanesha.recaptcha.ReCaptchaImpl;
- import net.tanesha.recaptcha.ReCaptchaResponse;
+ import java.util.Map;
+ import java.util.UUID;
+
+ import javax.ws.rs.Consumes;
+ import javax.ws.rs.DefaultValue;
+ import javax.ws.rs.FormParam;
+ import javax.ws.rs.GET;
+ import javax.ws.rs.POST;
+ import javax.ws.rs.PUT;
+ import javax.ws.rs.Path;
+ import javax.ws.rs.PathParam;
+ import javax.ws.rs.Produces;
+ import javax.ws.rs.QueryParam;
+ import javax.ws.rs.core.Context;
+ import javax.ws.rs.core.MediaType;
+ import javax.ws.rs.core.PathSegment;
+ import javax.ws.rs.core.Response;
+ import javax.ws.rs.core.UriInfo;
+
++import org.glassfish.jersey.server.mvc.Viewable;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.springframework.context.annotation.Scope;
+ import org.springframework.stereotype.Component;
+
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.message.OAuthResponse;
import org.apache.commons.lang.StringUtils;
+
import org.apache.usergrid.management.ActivationState;
+ import org.apache.usergrid.persistence.CredentialsInfo;
import org.apache.usergrid.persistence.EntityManager;
-import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.persistence.entities.User;
+import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.rest.AbstractContextResource;
import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.applications.ServiceResource;
import org.apache.usergrid.rest.exceptions.RedirectionException;
import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
import org.apache.usergrid.security.oauth.AccessInfo;
import org.apache.usergrid.security.tokens.exceptions.TokenException;
- import org.glassfish.jersey.server.mvc.Viewable;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.context.annotation.Scope;
- import org.springframework.stereotype.Component;
- import javax.ws.rs.*;
- import javax.ws.rs.core.*;
- import java.util.Map;
- import java.util.UUID;
-import com.sun.jersey.api.json.JSONWithPadding;
-import com.sun.jersey.api.view.Viewable;
++import com.fasterxml.jackson.databind.JsonNode;
++import com.fasterxml.jackson.databind.ObjectMapper;
++import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
- import static javax.servlet.http.HttpServletResponse.*;
- import static org.apache.usergrid.security.shiro.utils.SubjectUtils.*;
+ import net.tanesha.recaptcha.ReCaptchaImpl;
+ import net.tanesha.recaptcha.ReCaptchaResponse;
+
+ import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+ import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
+ import static javax.servlet.http.HttpServletResponse.SC_OK;
+
+ import static org.apache.usergrid.security.shiro.utils.SubjectUtils.getSubjectUserId;
+ import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isApplicationAdmin;
+ import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isApplicationUser;
import static org.apache.usergrid.utils.ConversionUtils.string;
@@@ -143,9 -164,84 +168,84 @@@ public class UserResource extends Servi
management.setAppUserPassword( getApplicationId(), targetUserId, oldPassword, newPassword );
}
- return new JSONWithPadding( response, callback );
+ return response;
}
+ @GET
+ @RequireSystemAccess
+ @Path("credentials")
- public JSONWithPadding getUserCredentials(@QueryParam("callback") @DefaultValue("callback") String callback )
++ public ApiResponse getUserCredentials(@QueryParam("callback") @DefaultValue("callback") String callback )
+ throws Exception {
+
+ logger.info( "UserResource.getUserCredentials" );
+
+
+ final ApiResponse response = createApiResponse();
+ response.setAction( "get user credentials" );
+
+ final UUID applicationId = getApplicationId();
+ final UUID targetUserId = getUserUuid();
+
+ if ( applicationId == null ) {
+ response.setError( "Application not found" );
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+ if ( targetUserId == null ) {
+ response.setError( "User not found" );
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+ final CredentialsInfo credentialsInfo = management.getAppUserCredentialsInfo( applicationId, targetUserId );
+
+
+ response.setProperty( "credentials", credentialsInfo );
+
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+
+ @PUT
+ @RequireSystemAccess
+ @Path("credentials")
- public JSONWithPadding setUserCredentials( @Context UriInfo ui, Map<String, Object> json,
++ public ApiResponse setUserCredentials( @Context UriInfo ui, Map<String, Object> json,
+ @QueryParam("callback") @DefaultValue("callback") String callback )
+ throws Exception {
+
+ logger.info( "UserResource.setUserCredentials" );
+
+ if ( json == null ) {
+ return null;
+ }
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "set user credentials" );
+ Map<String, Object> credentialsJson = ( Map<String, Object> ) json.get( "credentials" );
+
+
+ if ( credentialsJson == null ) {
+ throw new IllegalArgumentException( "credentials sub object is required" );
+ }
+
+ final CredentialsInfo credentials = CredentialsInfo.fromJson( credentialsJson );
+
+ UUID applicationId = getApplicationId();
+ UUID targetUserId = getUserUuid();
+
+ if ( targetUserId == null ) {
+ response.setError( "User not found" );
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+ management.setAppUserCredentialsInfo( applicationId, targetUserId, credentials );
+
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
@POST
@Path("password")
@@@ -202,9 -292,7 +302,9 @@@
@POST
@Path("sendpin")
- public JSONWithPadding postSendPin( @Context UriInfo ui,
+ @JSONP
- @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ @Produces({ MediaType.APPLICATION_JSON, "application/javascript"})
+ public ApiResponse postSendPin( @Context UriInfo ui,
@QueryParam("callback") @DefaultValue("callback") String callback )
throws Exception {
return sendPin( ui, callback );
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
index 28d8c87,ac07aaa..f48168e
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
@@@ -17,34 -17,29 +17,40 @@@
package org.apache.usergrid.rest.management.organizations;
-import java.util.*;
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriInfo;
+import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
+import com.google.common.base.Preconditions;
+import org.apache.commons.lang.StringUtils;
+import org.apache.usergrid.management.ApplicationCreator;
+import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.management.OrganizationOwnerInfo;
+import org.apache.usergrid.management.exceptions.ManagementException;
+import org.apache.usergrid.persistence.index.query.Identifier;
+import org.apache.usergrid.rest.AbstractContextResource;
+import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.RootResource;
import org.apache.usergrid.rest.management.ManagementResource;
+import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
++
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
-import org.apache.usergrid.management.ApplicationCreator;
-import org.apache.usergrid.management.OrganizationInfo;
-import org.apache.usergrid.management.OrganizationOwnerInfo;
-import org.apache.usergrid.management.exceptions.ManagementException;
-import org.apache.usergrid.rest.AbstractContextResource;
-import org.apache.usergrid.rest.ApiResponse;
-import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
-import org.apache.commons.lang.StringUtils;
-import com.google.common.base.Preconditions;
-import com.sun.jersey.api.json.JSONWithPadding;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
++
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
+import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isPermittedAccessToOrganization;
@Component( "org.apache.usergrid.rest.management.organizations.OrganizationsResource" )
@@@ -67,7 -62,34 +73,34 @@@ public class OrganizationsResource exte
public OrganizationsResource() {
}
+
+ @GET
+ @RequireSystemAccess
- public JSONWithPadding getAllOrganizations() throws Exception{
++ public ApiResponse getAllOrganizations() throws Exception{
+
+ ApiResponse response = createApiResponse();
+ List<OrganizationInfo> orgs = management.getOrganizations(null, 10000);
+ List<Object> jsonOrgList = new ArrayList<>();
+
+ for(OrganizationInfo org: orgs){
+
+
+ Map<String, Object> jsonOrg = new HashMap<>();
+ Map<String, UUID> apps = management.getApplicationsForOrganization(org.getUuid()).inverse();
+
+ jsonOrg.put("name", org.getName());
+ jsonOrg.put("uuid", org.getUuid());
+ jsonOrg.put("properties", org.getProperties());
+ jsonOrg.put("applications", apps);
+ jsonOrgList.add(jsonOrg);
+ }
+
+ response.setProperty("organizations", jsonOrgList);
- return new JSONWithPadding(response);
++
++ return response;
+ }
+
@Path(RootResource.ORGANIZATION_ID_PATH)
- @RequireOrganizationAccess
public OrganizationResource getOrganizationById( @Context UriInfo ui,
@PathParam( "organizationId" ) String organizationIdStr )
throws Exception {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
index 0000000,14b79f3..ff2a739
mode 000000,100644..100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
@@@ -1,0 -1,218 +1,216 @@@
+ /*
+ * 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.rest.system;
+
+
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.UUID;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.atomic.AtomicLong;
+
+ import javax.ws.rs.DefaultValue;
+ import javax.ws.rs.GET;
+ import javax.ws.rs.POST;
+ import javax.ws.rs.Path;
+ import javax.ws.rs.PathParam;
+ import javax.ws.rs.Produces;
+ import javax.ws.rs.QueryParam;
+ import javax.ws.rs.core.MediaType;
+
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.springframework.context.annotation.Scope;
+ import org.springframework.stereotype.Component;
+
+ import org.apache.usergrid.corepersistence.service.ConnectionService;
+ import org.apache.usergrid.corepersistence.service.ConnectionServiceImpl;
+ import org.apache.usergrid.corepersistence.service.StatusService;
+ import org.apache.usergrid.corepersistence.util.CpNamingUtils;
+ import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+ import org.apache.usergrid.persistence.index.query.Identifier;
+ import org.apache.usergrid.persistence.index.utils.UUIDUtils;
+ import org.apache.usergrid.persistence.model.util.UUIDGenerator;
+ import org.apache.usergrid.rest.AbstractContextResource;
+ import org.apache.usergrid.rest.ApiResponse;
+ import org.apache.usergrid.rest.RootResource;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
+
+ import com.google.common.base.Preconditions;
-import com.sun.jersey.api.json.JSONWithPadding;
+
+ import rx.Observable;
-import rx.functions.Action1;
+ import rx.schedulers.Schedulers;
+
+
+ /**
+ * system/index/otherstuff
+ */
+ @Component
+ @Scope( "singleton" )
+ @Produces( {
+ MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
+ "application/ecmascript", "text/jscript"
+ } )
+ public class ConnectionResource extends AbstractContextResource {
+
+ private static final Logger logger = LoggerFactory.getLogger( ConnectionResource.class );
+
+ public ConnectionResource() {
+ super();
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path( "dedup/" + RootResource.APPLICATION_ID_PATH )
- public JSONWithPadding rebuildIndexesPost( @PathParam( "applicationId" ) String applicationIdStr,
- @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++ public ApiResponse rebuildIndexesPost( @PathParam( "applicationId" ) String applicationIdStr,
++ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+
+ logger.info( "Rebuilding all applications" );
+
+ final UUID applicationId = UUIDUtils.tryGetUUID( applicationIdStr );
+
+ Preconditions.checkNotNull( applicationId, "applicationId must be specified" );
+
+ return executeAndCreateResponse( applicationId, callback );
+ }
+
+
+ @RequireSystemAccess
+ @GET
+ @Path( "dedup/{jobId: " + Identifier.UUID_REX + "}" )
- public JSONWithPadding rebuildIndexesGet( @PathParam( "jobId" ) String jobId,
- @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++ public ApiResponse rebuildIndexesGet( @PathParam( "jobId" ) String jobId,
++ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+ logger.info( "Getting status for index jobs" );
+
+ Preconditions.checkNotNull( jobId, "query param jobId must not be null" );
+
+
+ final UUID jobUUID = UUIDUtils.tryGetUUID( jobId );
+
+ final StatusService.JobStatus
+ job = getStatusService().getStatus( CpNamingUtils.MANAGEMENT_APPLICATION_ID, jobUUID ).toBlocking().lastOrDefault(
+ null );
+
+ Preconditions.checkNotNull( job, "job with id '" + jobId + "' does not exist" );
+
+
+ return createResult( job, callback );
+ }
+
+
+ private ConnectionService getConnectionService() {
+ return injector.getInstance( ConnectionServiceImpl.class );
+ }
+
+
+ private StatusService getStatusService() {
+ return injector.getInstance( StatusService.class );
+ }
+
+
+
+ /**
+ * Execute the request and return the response.
+ */
- private JSONWithPadding executeAndCreateResponse( final UUID applicationId, final String callback ) {
++ private ApiResponse executeAndCreateResponse( final UUID applicationId, final String callback ) {
+
+ final Observable<ApplicationScope> applicationScopeObservable =
+ Observable.just( CpNamingUtils.getApplicationScope( applicationId ) );
+
+ final UUID jobId = UUIDGenerator.newTimeUUID();
+
+ final StatusService statusService = getStatusService();
+ final ConnectionService connectionService = getConnectionService();
+
+ final AtomicLong count = new AtomicLong( 0 );
+
+ //start de duping and run in the background
+ connectionService.deDupeConnections( applicationScopeObservable ).buffer( 10, TimeUnit.SECONDS, 1000 )
+ .doOnNext(buffer -> {
+
+
+ final long runningTotal = count.addAndGet(buffer.size());
+
+ final Map<String, Object> status = new HashMap<String, Object>() {{
+ put("countProcessed", runningTotal);
+ put("updatedTimestamp", System.currentTimeMillis());
+ }};
+
+ statusService.setStatus(CpNamingUtils.MANAGEMENT_APPLICATION_ID, jobId,
+ StatusService.Status.INPROGRESS, status).toBlocking().lastOrDefault(null);
+ }).doOnSubscribe(() -> {
+
+ statusService.setStatus(CpNamingUtils.MANAGEMENT_APPLICATION_ID,
+ jobId, StatusService.Status.STARTED, new HashMap<>()).toBlocking().lastOrDefault(null);
+
+ }).doOnCompleted(() -> {
+
+ final long runningTotal = count.get();
+
+ final Map<String, Object> status = new HashMap<String, Object>() {{
+ put("countProcessed", runningTotal);
+ put("updatedTimestamp", System.currentTimeMillis());
+ }};
+
+ statusService.setStatus(CpNamingUtils.MANAGEMENT_APPLICATION_ID,
+ jobId, StatusService.Status.COMPLETE, status).toBlocking().lastOrDefault(null);
+
+ }).doOnError( (throwable) -> {
+ logger.error("Error deduping connections", throwable);
+
+ final Map<String, Object> status = new HashMap<String, Object>() {{
+ put("error", throwable.getMessage() );
+ }};
+
+ statusService.setStatus(CpNamingUtils.MANAGEMENT_APPLICATION_ID,
+ jobId, StatusService.Status.FAILED, status).toBlocking().lastOrDefault(null);;
+
+ } ).subscribeOn(Schedulers.newThread()).subscribe();
+
+
+ final StatusService.JobStatus status =
+ new StatusService.JobStatus( jobId, StatusService.Status.STARTED, new HashMap<>( ) );
+
+ return createResult( status, callback );
+ }
+
+
+ /**
+ * Create a response with the specified data.
+ * @param jobStatus
+ * @param callback
+ * @return
+ */
- private JSONWithPadding createResult(final StatusService.JobStatus jobStatus, final String callback){
++ private ApiResponse createResult(final StatusService.JobStatus jobStatus, final String callback){
+
+ final ApiResponse response = createApiResponse();
+
+ response.setAction( "de-dup connections" );
+ response.setProperty( "status", jobStatus );
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+ }
+
+
+
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
index b261c96,42a63ca..f3ce8b7
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
@@@ -34,8 -31,12 +34,10 @@@ import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
+ import org.apache.usergrid.rest.AbstractContextResource;
+ import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
-import com.sun.jersey.api.json.JSONWithPadding;
-
@Component
@Scope( "singleton" )
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
index 0000000,8e2946c..bbbe8b3
mode 000000,100644..100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
@@@ -1,0 -1,331 +1,353 @@@
+ /*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one or more
+ * * contributor license agreements. 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. For additional information regarding
+ * * copyright in this work, please see the NOTICE file in the top level
+ * * directory of this distribution.
+ *
+ */
+
+ package org.apache.usergrid.rest.system;
+
+
++import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
+ import com.google.common.base.Preconditions;
-import com.sun.jersey.api.json.JSONWithPadding;
+ import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder;
+ import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilderImpl;
+ import org.apache.usergrid.corepersistence.index.ReIndexService;
+ import org.apache.usergrid.persistence.EntityManager;
+ import org.apache.usergrid.persistence.index.utils.ConversionUtils;
+ import org.apache.usergrid.persistence.index.utils.UUIDUtils;
+ import org.apache.usergrid.rest.AbstractContextResource;
+ import org.apache.usergrid.rest.ApiResponse;
+ import org.apache.usergrid.rest.RootResource;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.springframework.context.annotation.Scope;
+ import org.springframework.stereotype.Component;
+
+ import javax.ws.rs.*;
+ import javax.ws.rs.core.Context;
+ import javax.ws.rs.core.MediaType;
+ import javax.ws.rs.core.UriInfo;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.UUID;
+
+
+ /**
+ * system/index/otherstuff
+ */
+ @Component
+ @Scope( "singleton" )
+ @Produces( {
+ MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
+ "application/ecmascript", "text/jscript"
+ } )
+ public class IndexResource extends AbstractContextResource {
+
+ private static final Logger logger = LoggerFactory.getLogger( IndexResource.class );
+ private static final String UPDATED_FIELD = "updated";
+
+
+
+ public IndexResource() {
+ super();
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path( "rebuild" )
- public JSONWithPadding rebuildIndexesPost( @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++ public ApiResponse rebuildIndexesPost( @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+
+ logger.info("Rebuilding all applications");
+
+ final ReIndexRequestBuilder request = createRequest();
+
+ return executeAndCreateResponse( request, callback );
+ }
+
+ @RequireSystemAccess
+ @GET
+ @Path( "rebuild/{jobId}" )
- public JSONWithPadding rebuildIndexesGet(@PathParam( "jobId" ) String jobId, @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++ @JSONP
++ @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
++ public ApiResponse rebuildIndexesGet(
++ @PathParam( "jobId" ) String jobId,
++ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++
++
+ throws Exception {
+ logger.info("Getting status for index jobs");
+
+ Preconditions
+ .checkNotNull(jobId, "query param jobId must not be null" );
+
+
+ ReIndexService.ReIndexStatus status = getReIndexService().getStatus(jobId);
+
+ final ApiResponse response = createApiResponse();
+
+ response.setAction( "rebuild indexes" );
+ response.setProperty( "jobId", status.getJobId() );
+ response.setProperty( "status", status.getStatus() );
+ response.setProperty( "lastUpdatedEpoch", status.getLastUpdated() );
+ response.setProperty( "numberQueued", status.getNumberProcessed() );
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "rebuild" )
- public JSONWithPadding rebuildIndexesPut( final Map<String, Object> payload,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildIndexesPut( final Map<String, Object> payload,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+
+ logger.info( "Resuming rebuilding all applications" );
+ final ReIndexRequestBuilder request = createRequest();
+
+ return executeResumeAndCreateResponse( payload, request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path( "rebuild/" + RootResource.APPLICATION_ID_PATH )
- public JSONWithPadding rebuildIndexesPut( @PathParam( "applicationId" ) String applicationIdStr,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildIndexesPut( @PathParam( "applicationId" ) String applicationIdStr,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback,
+ @QueryParam( "delay" ) @DefaultValue( "10" ) final long delay )
+
+ throws Exception {
+
+
+ logger.info( "Rebuilding application {}", applicationIdStr );
+
+
+ final UUID appId = UUIDUtils.tryExtractUUID( applicationIdStr );
+
+ final ReIndexRequestBuilder request = createRequest().withApplicationId( appId );
+
+ return executeAndCreateResponse( request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "rebuild/" + RootResource.APPLICATION_ID_PATH )
- public JSONWithPadding rebuildIndexesPut( final Map<String, Object> payload,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildIndexesPut( final Map<String, Object> payload,
+ @PathParam( "applicationId" ) String applicationIdStr,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback,
+ @QueryParam( "delay" ) @DefaultValue( "10" ) final long delay )
+
+ throws Exception {
+
+ logger.info( "Resuming rebuilding application {}", applicationIdStr );
+
+ final UUID appId = UUIDUtils.tryExtractUUID( applicationIdStr );
+
+ final ReIndexRequestBuilder request = createRequest().withApplicationId( appId );
+
+ return executeResumeAndCreateResponse( payload, request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path( "rebuild/" + RootResource.APPLICATION_ID_PATH + "/{collectionName}" )
- public JSONWithPadding rebuildIndexesPost( @PathParam( "applicationId" ) final String applicationIdStr,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildIndexesPost( @PathParam( "applicationId" ) final String applicationIdStr,
+ @PathParam( "collectionName" ) final String collectionName,
+ @QueryParam( "reverse" ) @DefaultValue( "false" ) final Boolean reverse,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+
+ logger.info( "Rebuilding collection {} in application {}", collectionName, applicationIdStr );
+
+ final UUID appId = UUIDUtils.tryExtractUUID( applicationIdStr );
+
+ final ReIndexRequestBuilder request =
+ createRequest().withApplicationId( appId ).withCollection( collectionName );
+
+ return executeAndCreateResponse( request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "rebuild/" + RootResource.APPLICATION_ID_PATH + "/{collectionName}" )
- public JSONWithPadding rebuildIndexesPut( final Map<String, Object> payload,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildIndexesPut( final Map<String, Object> payload,
+ @PathParam( "applicationId" ) final String applicationIdStr,
+ @PathParam( "collectionName" ) final String collectionName,
+ @QueryParam( "reverse" ) @DefaultValue( "false" ) final Boolean reverse,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ logger.info( "Resuming rebuilding collection {} in application {}", collectionName, applicationIdStr );
+
+ final UUID appId = UUIDUtils.tryExtractUUID( applicationIdStr );
+
+ final ReIndexRequestBuilder request =
+ createRequest().withApplicationId( appId ).withCollection( collectionName );
+
+ return executeResumeAndCreateResponse( payload, request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path( "rebuild/management" )
- public JSONWithPadding rebuildInternalIndexesPost(
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildInternalIndexesPost(
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback ) throws Exception {
+
+
+ final UUID managementAppId = emf.getManagementAppId();
+
+ logger.info( "Rebuilding management application with id {} ", managementAppId );
+ final ReIndexRequestBuilder request = createRequest().withApplicationId( managementAppId );
+
+ return executeAndCreateResponse( request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "rebuild/management" )
- public JSONWithPadding rebuildInternalIndexesPut( final Map<String, Object> payload,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse rebuildInternalIndexesPut( final Map<String, Object> payload,
+ @QueryParam( "callback" ) @DefaultValue( "callback" )
+ String callback ) throws Exception {
+
+
+ final UUID managementAppId = emf.getManagementAppId();
+
+ logger.info( "Resuming rebuilding management application with id {} ", managementAppId );
+ final ReIndexRequestBuilder request = createRequest().withApplicationId( managementAppId );
+
+ return executeResumeAndCreateResponse( payload, request, callback );
+ }
+
+
+ @RequireSystemAccess
+ @POST
+ @Path(RootResource.APPLICATION_ID_PATH)
- public JSONWithPadding addIndex( @Context UriInfo ui,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse addIndex( @Context UriInfo ui,
+ @PathParam( "applicationId" ) final String applicationIdStr,
+ Map<String, Object> config,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ Preconditions
+ .checkNotNull( config, "Payload for config is null, please pass {replicas:int, shards:int} in body" );
+
+ ApiResponse response = createApiResponse();
+
+ if ( !config.containsKey( "replicas" ) || !config.containsKey( "shards" ) ||
+ !( config.get( "replicas" ) instanceof Integer ) || !( config.get( "shards" ) instanceof Integer ) ) {
+ throw new IllegalArgumentException( "body must contains 'replicas' of type int and 'shards' of type int" );
+ }
+
+ if ( !config.containsKey( "indexSuffix" ) ) {
+ throw new IllegalArgumentException( "Please add an indexSuffix to your post" );
+ }
+ final UUID appId = UUIDUtils.tryExtractUUID( applicationIdStr );
+
+ if(appId == null){
+ throw new IllegalArgumentException("app id was not parsed");
+ }
+
+ EntityManager em = emf.getEntityManager(appId);
+ em.addIndex(config.get("indexSuffix").toString(), (int) config.get("shards"),
+ (int) config.get("replicas"), (String) config.get("writeConsistency"));
+ response.setAction( "Add index to alias" );
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+ private ReIndexService getReIndexService() {
+ return injector.getInstance( ReIndexService.class );
+ }
+
+
+ private ReIndexRequestBuilder createRequest() {
+ //TODO: wire this up through spring, and in the future guice.
+ return new ReIndexRequestBuilderImpl();
+ }
+
+
- private JSONWithPadding executeResumeAndCreateResponse( final Map<String, Object> payload,
++ private ApiResponse executeResumeAndCreateResponse( final Map<String, Object> payload,
+ final ReIndexRequestBuilder request,
+ final String callback ) {
+
+ Map<String,Object> newPayload = payload;
+ if(newPayload == null || !payload.containsKey( UPDATED_FIELD )){
+ newPayload = new HashMap<>(1);
+ newPayload.put(UPDATED_FIELD,0);
+ }
+
+ Preconditions.checkArgument(newPayload.get(UPDATED_FIELD) instanceof Number,
+ "You must specified the field \"updated\" in the payload and it must be a timestamp" );
+
+ //add our updated timestamp to the request
+ if ( newPayload.containsKey( UPDATED_FIELD ) ) {
+ final long timestamp = ConversionUtils.getLong(newPayload.get(UPDATED_FIELD));
+ request.withStartTimestamp( timestamp );
+ }
+
+ return executeAndCreateResponse( request, callback );
+ }
+
+
+ /**
+ * Execute the request and return the response.
+ */
- private JSONWithPadding executeAndCreateResponse( final ReIndexRequestBuilder request, final String callback ) {
++ private ApiResponse executeAndCreateResponse( final ReIndexRequestBuilder request, final String callback ) {
+
+
+ final ReIndexService.ReIndexStatus status = getReIndexService().rebuildIndex( request );
+
+ final ApiResponse response = createApiResponse();
+
+ response.setAction( "rebuild indexes" );
+ response.setProperty( "jobId", status.getJobId() );
+ response.setProperty( "status", status.getStatus() );
+ response.setProperty( "lastUpdatedEpoch", status.getLastUpdated() );
+ response.setProperty( "numberQueued", status.getNumberProcessed() );
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/system/MigrateResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/system/MigrateResource.java
index 0000000,c5a6dbc..7a6100b
mode 000000,100644..100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/system/MigrateResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/system/MigrateResource.java
@@@ -1,0 -1,270 +1,277 @@@
+ /*
+ * 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.rest.system;
+
+
-import java.util.Map;
-import java.util.Set;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriInfo;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Scope;
-import org.springframework.stereotype.Component;
-
++import com.fasterxml.jackson.databind.node.JsonNodeFactory;
++import com.fasterxml.jackson.databind.node.ObjectNode;
++import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
++import com.google.common.base.Preconditions;
++import com.google.inject.Injector;
+ import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
+ import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
+ import org.apache.usergrid.rest.AbstractContextResource;
+ import org.apache.usergrid.rest.ApiResponse;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.context.annotation.Scope;
++import org.springframework.stereotype.Component;
+
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.base.Preconditions;
-import com.google.inject.Injector;
-import com.sun.jersey.api.json.JSONWithPadding;
++import javax.ws.rs.*;
++import javax.ws.rs.core.Context;
++import javax.ws.rs.core.MediaType;
++import javax.ws.rs.core.UriInfo;
++import java.util.Map;
++import java.util.Set;
+
+
+ @Component
+ @Scope( "singleton" )
+ @Produces( {
+ MediaType.APPLICATION_JSON,
+ "application/javascript",
+ "application/x-javascript",
+ "text/ecmascript",
+ "application/ecmascript",
+ "text/jscript"
+ } )
+ public class MigrateResource extends AbstractContextResource {
+
+ private static final Logger logger = LoggerFactory.getLogger( MigrateResource.class );
+
+ public MigrateResource() {
+ logger.info( "SystemResource initialized" );
+ }
+
+ @Autowired
+ private Injector guiceInjector;
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "run" )
- public JSONWithPadding migrateData( @Context UriInfo ui,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse migrateData( @Context UriInfo ui,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "Migrate Data" );
+ //TODO make this use the task scheduler
+
+
+ final Thread migrate = new Thread() {
+
+ @Override
+ public void run() {
+
+ logger.info( "Migrating Schema" );
+
+ try {
+ getMigrationManager().migrate();
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to migrate data", e );
+ }
+
+ logger.info( "Migrating Data" );
+
+ try {
+ getDataMigrationManager().migrate();
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to migrate data", e );
+ }
+ }
+ };
+
+ migrate.setName( "Index migrate data formats" );
+ migrate.setDaemon( true );
+ migrate.start();
+
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "run/{pluginName}" )
- public JSONWithPadding migrateData(@PathParam("pluginName") String pluginName , @Context UriInfo ui,
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse migrateData(@PathParam("pluginName") String pluginName , @Context UriInfo ui,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ if(!getDataMigrationManager().pluginExists(pluginName)){
+ throw new IllegalArgumentException("Plugin doesn't exits name:"+pluginName);
+ }
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "Migrate Data: "+ pluginName );
+ //TODO make this use the task scheduler
+
+
+
+
+ final Thread migrate = new Thread() {
+
+ @Override
+ public void run() {
+
+ logger.info( "Migrating Data for plugin: " + pluginName );
+
+ try {
+ getDataMigrationManager().migrate(pluginName);
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to migrate data for plugin: " + pluginName, e );
+ }
+ }
+ };
+
+ migrate.setName( "Index migrate data formats: "+pluginName );
+ migrate.setDaemon( true );
+ migrate.start();
+
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+ @RequireSystemAccess
+ @PUT
+ @Path( "set" )
- public JSONWithPadding setMigrationVersion(
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse setMigrationVersion(
+ @Context UriInfo ui, Map<String, Object> json,
+ @QueryParam( "callback" ) @DefaultValue( "" ) String callback )
+ throws Exception {
+
+ logger.debug( "setMigrationVersion" );
+
+ Preconditions.checkNotNull( json, "You must provide a json body" );
+ Preconditions.checkArgument( json.keySet().size() > 0, "You must specify at least one module and version" );
+
+ ApiResponse response = createApiResponse();
+ response.setAction("Set Migration Versions");
+
+ ObjectNode node = JsonNodeFactory.instance.objectNode();
+
+ final DataMigrationManager dataMigrationManager = getDataMigrationManager();
+ final Set<String> plugins = dataMigrationManager.getPluginNames();
+
+ /**
+ * Set the migration version for the plugins specified
+ */
+ for ( final String key : json.keySet() ) {
+
+ int version = ( int ) json.get( key );
+
+ dataMigrationManager.resetToVersion(key, version);
+ }
+
+
+ /**
+ * Echo back a response of the current versions for all plugins
+ */
+ for(final String pluginName: plugins){
+ node.put(pluginName, dataMigrationManager.getCurrentVersion(pluginName));
+ }
+
+
+ response.setData( node );
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+ @RequireSystemAccess
+ @GET
+ @Path( "status" )
- public JSONWithPadding migrateStatus(
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse migrateStatus(
+ @Context UriInfo ui,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "Migrate Schema indexes" );
+
+ ObjectNode node = JsonNodeFactory.instance.objectNode();
+
+
+
+ final DataMigrationManager dataMigrationManager = getDataMigrationManager();
+
+ final Set<String> plugins = dataMigrationManager.getPluginNames();
+
+ for(final String pluginName: plugins){
+ node.put( pluginName, dataMigrationManager.getCurrentVersion( pluginName ) );
+ }
+
+ response.setData( node );
+
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+ @RequireSystemAccess
+ @GET
+ @Path( "count" )
- public JSONWithPadding migrateCount(
++ @JSONP
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse migrateCount(
+ @Context UriInfo ui,
+ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "Current entity count in system" );
+
+ response.setProperty( "count", emf.performEntityCount() );
+
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+ /**
+ * Get the schema migration manager
+ */
+ private MigrationManager getMigrationManager() {
+ return guiceInjector.getInstance( MigrationManager.class );
+ }
+
+ /**
+ * Get the Data migration manager
+ */
+ private DataMigrationManager getDataMigrationManager() {
+ return guiceInjector.getInstance( DataMigrationManager.class );
+ }
+ }
+
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/main/java/org/apache/usergrid/rest/system/SystemResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/system/SystemResource.java
index 0000000,a5174e6..a83756d
mode 000000,100644..100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/system/SystemResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/system/SystemResource.java
@@@ -1,0 -1,108 +1,121 @@@
+ /*
+ * 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.rest.system;
+
+
+ import javax.ws.rs.DefaultValue;
+ import javax.ws.rs.GET;
+ import javax.ws.rs.Path;
+ import javax.ws.rs.Produces;
+ import javax.ws.rs.QueryParam;
+ import javax.ws.rs.core.Context;
+ import javax.ws.rs.core.MediaType;
+ import javax.ws.rs.core.UriInfo;
+
++import org.apache.usergrid.rest.system.ApplicationsResource;
++import org.apache.usergrid.rest.system.DatabaseResource;
++import org.apache.usergrid.rest.system.QueueSystemResource;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.springframework.context.annotation.Scope;
+ import org.springframework.stereotype.Component;
+
+ import org.apache.usergrid.rest.AbstractContextResource;
+ import org.apache.usergrid.rest.ApiResponse;
+ import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
+
-import com.sun.jersey.api.json.JSONWithPadding;
++import javax.ws.rs.*;
++import javax.ws.rs.core.Context;
++import javax.ws.rs.core.MediaType;
++import javax.ws.rs.core.UriInfo;
+
+
+ @Path( "/system" )
+ @Component
+ @Scope( "singleton" )
+ @Produces( {
+ MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
+ "application/ecmascript", "text/jscript"
+ } )
+ public class SystemResource extends AbstractContextResource {
+
+ private static final Logger logger = LoggerFactory.getLogger( SystemResource.class );
+
+
+ public SystemResource() {
+ logger.info( "SystemResource initialized" );
+ }
+
+
+ @RequireSystemAccess
+ @GET
++
+ @Path( "superuser/setup" )
- public JSONWithPadding getSetupSuperuser( @Context UriInfo ui,
- @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
++ @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
++ public ApiResponse getSetupSuperuser( @Context UriInfo ui,
++ @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback )
+ throws Exception {
+
+ ApiResponse response = createApiResponse();
+ response.setAction( "superuser setup" );
+
+ logger.info( "Setting up Superuser" );
+
+ try {
+ management.provisionSuperuser();
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to complete superuser setup", e );
+ }
+
+ response.setSuccess();
+
- return new JSONWithPadding( response, callback );
++ return response;
+ }
+
+
+
+ @Path( "migrate" )
+ public MigrateResource migrate() {
+ return getSubResource( MigrateResource.class );
+ }
+
+
+ @Path( "index" )
+ public IndexResource index() { return getSubResource( IndexResource.class ); }
+
+
+ @Path( "database" )
+ public DatabaseResource database() {
+ return getSubResource( DatabaseResource.class );
+ }
+
++ @Path( "queue" )
++ public QueueSystemResource queue() {
++ return getSubResource( QueueSystemResource.class );
++ }
++
+ @Path( "applications" )
+ public ApplicationsResource applications() {
+ return getSubResource( ApplicationsResource.class );
+ }
+
+
+ @Path( "connection" )
+ public ConnectionResource connection() { return getSubResource( ConnectionResource.class ); }
+
+ }
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
----------------------------------------------------------------------
diff --cc stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
index 0df2416,f258f94..eddf7ed
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
@@@ -18,6 -18,6 +18,10 @@@ package org.apache.usergrid.rest.applic
import com.fasterxml.jackson.databind.JsonNode;
++import com.sun.jersey.api.client.UniformInterfaceException;
++import com.sun.jersey.api.client.WebResource;
++import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
++
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@@ -27,6 -27,6 +31,8 @@@ import java.util.UUID
import org.apache.usergrid.rest.test.resource.AbstractRestIT;
import org.apache.usergrid.rest.test.resource.endpoints.CollectionEndpoint;
import org.apache.usergrid.rest.test.resource.model.*;
++
++import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
@@@ -36,10 -36,16 +42,14 @@@ import org.slf4j.LoggerFactory
import org.apache.usergrid.rest.applications.utils.UserRepo;
import org.apache.usergrid.utils.UUIDUtils;
-import com.sun.jersey.api.client.ClientResponse.Status;
-import com.sun.jersey.api.client.GenericType;
-import com.sun.jersey.api.client.UniformInterfaceException;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
-
++import javax.ws.rs.BadRequestException;
+import javax.ws.rs.ClientErrorException;
++import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
import java.io.IOException;
+ import javax.ws.rs.core.MediaType;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@@ -1129,4 -1109,105 +1139,111 @@@ public class UserResourceIT extends Abs
assertEquals(response.getResponse().getEntities().get(0).get("uuid").toString(), userId.toString());
}
+
+
+
+ @Test
+ public void testCredentialsTransfer() throws Exception {
+
+ usersResource.post(new User("test_1", "Test1 User", "test_1@test.com", "test123")); // client.setApiUrl(apiUrl);
+ refreshIndex();
+
+ //Entity appInfo = this.app().get().getResponse().getEntities().get(0);
+
+ Token token = this.app().token().post(new Token("test_1", "test123"));
+
+ assertNotNull(token.getAccessToken());
+
+ final String superUserName = this.clientSetup.getSuperuserName();
+ final String superUserPassword = this.clientSetup.getSuperuserPassword();
+
+
+ //get the credentials info
+ final CollectionEndpoint collection = userResource.entity("test_1").collection( "credentials" );
+
- final WebResource resource = collection.getResource();
++ final WebTarget resource = collection.getTarget();
++
++
++ final HttpAuthenticationFeature httpBasicAuth = HttpAuthenticationFeature.basicBuilder()
++ .credentials( superUserName, superUserPassword ).build();
+
- resource.addFilter( new HTTPBasicAuthFilter(superUserName, superUserPassword) );
+
++ final ApiResponse response = resource.register( httpBasicAuth ).request()
++ .accept( MediaType.APPLICATION_JSON ).get(
++ org.apache.usergrid.rest.test.resource.model.ApiResponse.class );
+
+
- final ApiResponse response = resource.type( MediaType.APPLICATION_JSON_TYPE)
- .accept( MediaType.APPLICATION_JSON ).get( org.apache.usergrid.rest.test.resource.model.ApiResponse.class );
+
+
+ //now get the credentials sub object
+
+ final Map<String, Object> credentials = ( Map<String, Object> ) response.getProperties().get( "credentials" );
+
+
+
+ //get out the hash and change it so we can validate
+ final String originalSecret = ( String ) credentials.get( "secret" );
+
+
+ //here we modify the hash a little, this way we can break password validation, then re-set it to ensure we're actually updating the credentials info correctly.
+ final String borkedSecret = originalSecret.substring( 0, originalSecret.length() -1 );
+
+ credentials.put( "secret", borkedSecret );
+
+ //now PUT it
+
+
+ final Map<String, Map<String, Object>> wrapper = new HashMap<>( );
+ wrapper.put( "credentials", credentials );
+
- final WebResource putResource = collection.getResource();
++ final WebTarget putResource = collection.getTarget();
+
- putResource.addFilter( new HTTPBasicAuthFilter(superUserName, superUserPassword) );
+
+
- putResource.type( MediaType.APPLICATION_JSON_TYPE)
- .accept( MediaType.APPLICATION_JSON ).put(
- org.apache.usergrid.rest.test.resource.model.ApiResponse.class, wrapper );
++ putResource.register( httpBasicAuth ).request()
++ .accept( MediaType.APPLICATION_JSON )
++ .put( javax.ws.rs.client.Entity.json(wrapper), org.apache.usergrid.rest.test.resource.model.ApiResponse.class );
+
+
+ //now try to get a password, it should fail because the hash is no longer correct
+
+ int status = 0;
+
+ // bad access token
+ try {
+ this.app().token().post(new Token("test_1", "test123"));
+ fail("Should have thrown an exception");
- } catch (UniformInterfaceException uie) {
++ } catch (BadRequestException uie) {
+ status = uie.getResponse().getStatus();
- log.info("Error Response Body: " + uie.getResponse().getEntity(String.class));
++ log.info("Error Response Body: {}" , uie.getResponse().getEntity());
+ }
+
- assertEquals(Status.BAD_REQUEST.getStatusCode(), status);
++ assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), status);
+
+
+ //now put the correct one
+
+
+ credentials.put( "secret", originalSecret );
+
+
- final WebResource putResource2 = collection.getResource();
++ final WebTarget putResource2 = collection.getTarget();
++
++
++
++ putResource2.register( httpBasicAuth ).request()
++ .accept( MediaType.APPLICATION_JSON )
++ .put( javax.ws.rs.client.Entity.json( wrapper ),
++ org.apache.usergrid.rest.test.resource.model.ApiResponse.class );
+
- putResource2.addFilter( new HTTPBasicAuthFilter( superUserName, superUserPassword ) );
+
+
- putResource2.type( MediaType.APPLICATION_JSON_TYPE)
- .accept( MediaType.APPLICATION_JSON ).put(
- org.apache.usergrid.rest.test.resource.model.ApiResponse.class, wrapper );
+
+
+ //now auth, should be good
+ final Token nextToken = this.app().token().post(new Token("test_1", "test123"));
+
+ assertNotNull( nextToken.getAccessToken() );
+
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/b422364e/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
----------------------------------------------------------------------