usergrid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From toddn...@apache.org
Subject [49/50] [abbrv] usergrid git commit: Merge branch '2.1-release' of https://git-wip-us.apache.org/repos/asf/usergrid
Date Fri, 30 Oct 2015 23:33:23 GMT
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/master
Commit: b422364e20c14a657de076b793bc6b7c1160a556
Parents: 9d3cf5b eb2756b
Author: Todd Nine <tnine@apigee.com>
Authored: Fri Oct 30 16:32:23 2015 -0600
Committer: Todd Nine <tnine@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
----------------------------------------------------------------------


Mime
View raw message