Moves system endpoints into the system package

Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/7a4f36ab
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/7a4f36ab
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/7a4f36ab

Branch: refs/heads/USERGRID-909
Commit: 7a4f36ab9c0e504133f80f4d0ad8a70d115ee4f4
Parents: 3b43624
Author: Todd Nine <tn...@apigee.com>
Authored: Tue Oct 27 09:46:06 2015 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Tue Oct 27 09:46:06 2015 -0600

----------------------------------------------------------------------
 .../usergrid/rest/ApplicationsResource.java     | 178 ----------
 .../usergrid/rest/ConnectionResource.java       | 199 -----------
 .../apache/usergrid/rest/DatabaseResource.java  |  98 ------
 .../org/apache/usergrid/rest/IndexResource.java | 328 ------------------
 .../apache/usergrid/rest/MigrateResource.java   | 268 ---------------
 .../apache/usergrid/rest/SystemResource.java    | 108 ------
 .../rest/system/ApplicationsResource.java       | 178 ++++++++++
 .../rest/system/ConnectionResource.java         | 202 +++++++++++
 .../usergrid/rest/system/DatabaseResource.java  | 100 ++++++
 .../usergrid/rest/system/IndexResource.java     | 331 +++++++++++++++++++
 .../usergrid/rest/system/MigrateResource.java   | 270 +++++++++++++++
 .../usergrid/rest/system/SystemResource.java    | 108 ++++++
 12 files changed, 1189 insertions(+), 1179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/ApplicationsResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/ApplicationsResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/ApplicationsResource.java
deleted file mode 100644
index 55cf0f6..0000000
--- 
a/stack/rest/src/main/java/org/apache/usergrid/rest/ApplicationsResource.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *
- *  * 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;
-
-import com.sun.jersey.api.json.JSONWithPadding;
-import org.apache.usergrid.corepersistence.service.StatusService;
-import org.apache.usergrid.persistence.Entity;
-import org.apache.usergrid.persistence.EntityManager;
-import org.apache.usergrid.persistence.core.util.StringUtils;
-import org.apache.usergrid.persistence.model.util.UUIDGenerator;
-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.LinkedHashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Classy class class.
- */
-@Component
-@Scope( "singleton" )
-@Produces( {
-    MediaType.APPLICATION_JSON, "application/javascript", 
"application/x-javascript", "text/ecmascript",
-    "application/ecmascript", "text/jscript"
-} )
-public class ApplicationsResource extends AbstractContextResource {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(ApplicationsResource.class);
-
-
-    public ApplicationsResource() {
-
-        logger.info( "ApplicationsResource initialized" );
-    } {
-
-    }
-
-    @RequireSystemAccess
-    @DELETE
-    @Path( "{applicationId}" )
-    public JSONWithPadding clearApplication( @Context UriInfo ui,
-                                             @PathParam("applicationId") UUID 
applicationId,
-                                             @QueryParam( 
"confirmApplicationName" ) String confirmApplicationName,
-                                             @QueryParam( "limit" ) int limit,
-                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
-        throws Exception {
-
-        if(confirmApplicationName == null){
-            throw new IllegalArgumentException("please make add a QueryString 
for confirmApplicationName");
-        }
-
-        final UUID jobId = UUIDGenerator.newTimeUUID();
-
-        final EntityManager em =  emf.getEntityManager(applicationId);
-        final String name =  em.getApplication().getApplicationName();
-        if(!name.toLowerCase().equals(confirmApplicationName.toLowerCase())){
-            throw new IllegalArgumentException("confirmApplicationName: " + 
confirmApplicationName + " does not equal " + name);
-        }
-        final StatusService statusService = 
injector.getInstance(StatusService.class);
-
-        final ApiResponse response = createApiResponse();
-
-        response.setAction( "clear application" );
-
-        logger.info("clearing up application");
-
-
-        final Thread delete = new Thread() {
-
-            @Override
-            public void run() {
-                final AtomicInteger itemsDeleted = new AtomicInteger(0);
-                try {
-                    management.deleteAllEntities(applicationId, limit)
-                        .map(id -> itemsDeleted.incrementAndGet())
-                        .doOnNext(count -> {
-                            if( count % 100 == 0 ){
-                                Map<String,Object> map = new LinkedHashMap<>();
-                                map.put("count",itemsDeleted.intValue());
-                                final StatusService statusService = 
injector.getInstance(StatusService.class);
-                                statusService.setStatus(applicationId, jobId, 
StatusService.Status.INPROGRESS,map)
-                                    .subscribe();//do not want to throw this 
exception
-                            }
-                        })
-                        .doOnCompleted(() -> {
-                            Map<String, Object> map = new LinkedHashMap<>();
-                            map.put("count", itemsDeleted.intValue());
-                            final StatusService statusService = 
injector.getInstance(StatusService.class);
-                            statusService.setStatus(applicationId, jobId, 
StatusService.Status.COMPLETE, map)
-                                .toBlocking().lastOrDefault(null);//want to 
rethrow this exception
-                        })
-                        .toBlocking().lastOrDefault(null);//expecting 
exception to be caught if job fails
-
-                } catch ( Exception e ) {
-                    Map<String,Object> map = new LinkedHashMap<>();
-                    map.put("exception",e);
-                    try {
-                        statusService.setStatus(applicationId, jobId, 
StatusService.Status.FAILED, map).toBlocking().lastOrDefault(null);//leave as 
subscribe if fails retry
-                    }catch (Exception subE){
-                        logger.error("failed to update status "+jobId,subE);
-                    }
-                    logger.error( "Failed to delete appid:"+applicationId + " 
jobid:"+jobId+" count:"+itemsDeleted, e );
-                }
-            }
-        };
-
-        delete.setName("Delete for app : " + applicationId + " job: " + jobId);
-        delete.setDaemon(true);
-        delete.start();
-
-        try {
-            //should throw exception if can't start
-            statusService.setStatus(applicationId, jobId, 
StatusService.Status.STARTED, new 
LinkedHashMap<>()).toBlocking().lastOrDefault(null);
-        }catch (Exception e){
-            logger.error("failed to set status for " + jobId, e);
-        }
-        Map<String,Object> data = new HashMap<>();
-        data.put("jobId",jobId);
-        data.put("status",StatusService.Status.STARTED);
-        response.setData(data);
-        response.setSuccess();
-        return new JSONWithPadding( response, callback );
-    }
-
-    @RequireSystemAccess
-    @GET
-    @Path( "{applicationId}/job/{jobId}" )
-    public JSONWithPadding getStatus( @Context UriInfo ui,
-                                             @PathParam("applicationId") UUID 
applicationId,
-                                            @PathParam("jobId") UUID jobId,
-                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback ) throws Exception{
-        final StatusService statusService = 
injector.getInstance(StatusService.class);
-
-        final ApiResponse response = createApiResponse();
-
-        response.setAction( "clear application" );
-
-        StatusService.JobStatus jobStatus = 
statusService.getStatus(applicationId, jobId).toBlocking().lastOrDefault(null);
-
-        Map<String,Object> data = new HashMap<>();
-        data.put("jobId",jobId);
-        data.put( "status", jobStatus.getStatus().toString() );
-        data.put( "metadata", jobStatus.getData() );
-        response.setData(data);
-        response.setSuccess();
-
-        return new JSONWithPadding( response, callback );
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/ConnectionResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/ConnectionResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/ConnectionResource.java
deleted file mode 100644
index dfa4781..0000000
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/ConnectionResource.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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;
-
-
-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.security.annotations.RequireSystemAccess;
-
-import com.google.common.base.Preconditions;
-import com.sun.jersey.api.json.JSONWithPadding;
-
-import rx.Observable;
-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 )
-        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 )
-        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 ) {
-
-        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 );
-        } ).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){
-
-        final ApiResponse response = createApiResponse();
-
-        response.setAction( "de-dup connections" );
-        response.setProperty( "status", jobStatus );
-        response.setSuccess();
-
-        return new JSONWithPadding( response, callback );
-    }
-}
-
-
-

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/DatabaseResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/DatabaseResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/DatabaseResource.java
deleted file mode 100644
index a8c5fee..0000000
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/DatabaseResource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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;
-
-
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.PUT;
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Scope;
-import org.springframework.stereotype.Component;
-
-import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
-
-import com.sun.jersey.api.json.JSONWithPadding;
-
-
-@Component
-@Scope( "singleton" )
-@Produces( {
-    MediaType.APPLICATION_JSON, "application/javascript", 
"application/x-javascript", "text/ecmascript",
-    "application/ecmascript", "text/jscript"
-} )
-public class DatabaseResource extends AbstractContextResource {
-
-    private static final Logger logger = LoggerFactory.getLogger( 
DatabaseResource.class );
-
-
-    public DatabaseResource() {
-        logger.info( "DatabaseResource initialized" );
-    }
-
-
-    @RequireSystemAccess
-    @PUT
-    @Path( "setup" )
-    public JSONWithPadding runDatabaseSetup( @Context UriInfo ui,
-                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
-        throws Exception {
-
-        ApiResponse response = createApiResponse();
-        response.setAction( "cassandra setup" );
-
-        logger.info( "Setting up Cassandra" );
-
-
-        emf.setup();
-
-
-        response.setSuccess();
-
-        return new JSONWithPadding( response, callback );
-    }
-
-
-    @RequireSystemAccess
-    @PUT
-    @Path( "bootstrap" )
-    public JSONWithPadding runSystemSetup( @Context UriInfo ui,
-                                           @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
-        throws Exception {
-
-        ApiResponse response = createApiResponse();
-        response.setAction( "cassandra setup" );
-
-        logger.info( "Setting up Cassandra" );
-
-
-        emf.boostrap();
-        management.setup();
-
-        response.setSuccess();
-
-        return new JSONWithPadding( response, callback );
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/IndexResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/IndexResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/IndexResource.java
deleted file mode 100644
index a4a56bc..0000000
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/IndexResource.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- *
- *  * 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;
-
-
-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.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 )
-        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 )
-        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 );
-    }
-
-    @RequireSystemAccess
-    @PUT
-    @Path( "rebuild" )
-    public JSONWithPadding 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,
-                                              @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,
-                                              @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,
-                                               @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,
-                                              @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(
-        @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,
-                                                      @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,
-                                     @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 );
-    }
-
-
-    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,
-                                                            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 ) {
-
-
-        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 );
-    }
-}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/MigrateResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/MigrateResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/MigrateResource.java
deleted file mode 100644
index 7410927..0000000
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/MigrateResource.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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;
-
-
-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 
org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
-import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
-import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
-
-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;
-
-
-@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,
-                                        @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 );
-    }
-
-    @RequireSystemAccess
-    @PUT
-    @Path( "run/{pluginName}" )
-    public JSONWithPadding 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 );
-    }
-
-    @RequireSystemAccess
-    @PUT
-    @Path( "set" )
-    public JSONWithPadding 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 );
-    }
-
-
-    @RequireSystemAccess
-    @GET
-    @Path( "status" )
-    public JSONWithPadding 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 );
-    }
-
-
-    @RequireSystemAccess
-    @GET
-    @Path( "count" )
-    public JSONWithPadding 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 );
-    }
-
-
-    /**
-     * 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/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/SystemResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/SystemResource.java 
b/stack/rest/src/main/java/org/apache/usergrid/rest/SystemResource.java
deleted file mode 100644
index aaee596..0000000
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/SystemResource.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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;
-
-
-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.context.annotation.Scope;
-import org.springframework.stereotype.Component;
-
-import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
-
-import com.sun.jersey.api.json.JSONWithPadding;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-
-
-@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 )
-        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 );
-    }
-
-
-
-    @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( "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/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/system/ApplicationsResource.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/main/java/org/apache/usergrid/rest/system/ApplicationsResource.java
 
b/stack/rest/src/main/java/org/apache/usergrid/rest/system/ApplicationsResource.java
new file mode 100644
index 0000000..82088f9
--- /dev/null
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/system/ApplicationsResource.java
@@ -0,0 +1,178 @@
+/*
+ *
+ *  * 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.sun.jersey.api.json.JSONWithPadding;
+import org.apache.usergrid.corepersistence.service.StatusService;
+import org.apache.usergrid.persistence.EntityManager;
+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.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.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Classy class class.
+ */
+@Component
+@Scope( "singleton" )
+@Produces( {
+    MediaType.APPLICATION_JSON, "application/javascript", 
"application/x-javascript", "text/ecmascript",
+    "application/ecmascript", "text/jscript"
+} )
+public class ApplicationsResource extends AbstractContextResource {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(ApplicationsResource.class);
+
+
+    public ApplicationsResource() {
+
+        logger.info( "ApplicationsResource initialized" );
+    } {
+
+    }
+
+    @RequireSystemAccess
+    @DELETE
+    @Path( "{applicationId}" )
+    public JSONWithPadding clearApplication( @Context UriInfo ui,
+                                             @PathParam("applicationId") UUID 
applicationId,
+                                             @QueryParam( 
"confirmApplicationName" ) String confirmApplicationName,
+                                             @QueryParam( "limit" ) int limit,
+                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
+        throws Exception {
+
+        if(confirmApplicationName == null){
+            throw new IllegalArgumentException("please make add a QueryString 
for confirmApplicationName");
+        }
+
+        final UUID jobId = UUIDGenerator.newTimeUUID();
+
+        final EntityManager em =  emf.getEntityManager(applicationId);
+        final String name =  em.getApplication().getApplicationName();
+        if(!name.toLowerCase().equals(confirmApplicationName.toLowerCase())){
+            throw new IllegalArgumentException("confirmApplicationName: " + 
confirmApplicationName + " does not equal " + name);
+        }
+        final StatusService statusService = 
injector.getInstance(StatusService.class);
+
+        final ApiResponse response = createApiResponse();
+
+        response.setAction( "clear application" );
+
+        logger.info("clearing up application");
+
+
+        final Thread delete = new Thread() {
+
+            @Override
+            public void run() {
+                final AtomicInteger itemsDeleted = new AtomicInteger(0);
+                try {
+                    management.deleteAllEntities(applicationId, limit)
+                        .map(id -> itemsDeleted.incrementAndGet())
+                        .doOnNext(count -> {
+                            if( count % 100 == 0 ){
+                                Map<String,Object> map = new LinkedHashMap<>();
+                                map.put("count",itemsDeleted.intValue());
+                                final StatusService statusService = 
injector.getInstance(StatusService.class);
+                                statusService.setStatus(applicationId, jobId, 
StatusService.Status.INPROGRESS,map)
+                                    .subscribe();//do not want to throw this 
exception
+                            }
+                        })
+                        .doOnCompleted(() -> {
+                            Map<String, Object> map = new LinkedHashMap<>();
+                            map.put("count", itemsDeleted.intValue());
+                            final StatusService statusService = 
injector.getInstance(StatusService.class);
+                            statusService.setStatus(applicationId, jobId, 
StatusService.Status.COMPLETE, map)
+                                .toBlocking().lastOrDefault(null);//want to 
rethrow this exception
+                        })
+                        .toBlocking().lastOrDefault(null);//expecting 
exception to be caught if job fails
+
+                } catch ( Exception e ) {
+                    Map<String,Object> map = new LinkedHashMap<>();
+                    map.put("exception",e);
+                    try {
+                        statusService.setStatus(applicationId, jobId, 
StatusService.Status.FAILED, map).toBlocking().lastOrDefault(null);//leave as 
subscribe if fails retry
+                    }catch (Exception subE){
+                        logger.error("failed to update status "+jobId,subE);
+                    }
+                    logger.error( "Failed to delete appid:"+applicationId + " 
jobid:"+jobId+" count:"+itemsDeleted, e );
+                }
+            }
+        };
+
+        delete.setName("Delete for app : " + applicationId + " job: " + jobId);
+        delete.setDaemon(true);
+        delete.start();
+
+        try {
+            //should throw exception if can't start
+            statusService.setStatus(applicationId, jobId, 
StatusService.Status.STARTED, new 
LinkedHashMap<>()).toBlocking().lastOrDefault(null);
+        }catch (Exception e){
+            logger.error("failed to set status for " + jobId, e);
+        }
+        Map<String,Object> data = new HashMap<>();
+        data.put("jobId",jobId);
+        data.put("status",StatusService.Status.STARTED);
+        response.setData(data);
+        response.setSuccess();
+        return new JSONWithPadding( response, callback );
+    }
+
+    @RequireSystemAccess
+    @GET
+    @Path( "{applicationId}/job/{jobId}" )
+    public JSONWithPadding getStatus( @Context UriInfo ui,
+                                             @PathParam("applicationId") UUID 
applicationId,
+                                            @PathParam("jobId") UUID jobId,
+                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback ) throws Exception{
+        final StatusService statusService = 
injector.getInstance(StatusService.class);
+
+        final ApiResponse response = createApiResponse();
+
+        response.setAction( "clear application" );
+
+        StatusService.JobStatus jobStatus = 
statusService.getStatus(applicationId, jobId).toBlocking().lastOrDefault(null);
+
+        Map<String,Object> data = new HashMap<>();
+        data.put("jobId",jobId);
+        data.put( "status", jobStatus.getStatus().toString() );
+        data.put( "metadata", jobStatus.getData() );
+        response.setData(data);
+        response.setSuccess();
+
+        return new JSONWithPadding( response, callback );
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
----------------------------------------------------------------------
diff --git 
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
new file mode 100644
index 0000000..6e683ed
--- /dev/null
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/system/ConnectionResource.java
@@ -0,0 +1,202 @@
+/*
+ * 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.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 )
+        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 )
+        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 ) {
+
+        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 );
+        } ).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){
+
+        final ApiResponse response = createApiResponse();
+
+        response.setAction( "de-dup connections" );
+        response.setProperty( "status", jobStatus );
+        response.setSuccess();
+
+        return new JSONWithPadding( response, callback );
+    }
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
----------------------------------------------------------------------
diff --git 
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
new file mode 100644
index 0000000..42a63ca
--- /dev/null
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/system/DatabaseResource.java
@@ -0,0 +1,100 @@
+/*
+ * 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.PUT;
+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.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;
+
+
+@Component
+@Scope( "singleton" )
+@Produces( {
+    MediaType.APPLICATION_JSON, "application/javascript", 
"application/x-javascript", "text/ecmascript",
+    "application/ecmascript", "text/jscript"
+} )
+public class DatabaseResource extends AbstractContextResource {
+
+    private static final Logger logger = LoggerFactory.getLogger( 
DatabaseResource.class );
+
+
+    public DatabaseResource() {
+        logger.info( "DatabaseResource initialized" );
+    }
+
+
+    @RequireSystemAccess
+    @PUT
+    @Path( "setup" )
+    public JSONWithPadding runDatabaseSetup( @Context UriInfo ui,
+                                             @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
+        throws Exception {
+
+        ApiResponse response = createApiResponse();
+        response.setAction( "cassandra setup" );
+
+        logger.info( "Setting up Cassandra" );
+
+
+        emf.setup();
+
+
+        response.setSuccess();
+
+        return new JSONWithPadding( response, callback );
+    }
+
+
+    @RequireSystemAccess
+    @PUT
+    @Path( "bootstrap" )
+    public JSONWithPadding runSystemSetup( @Context UriInfo ui,
+                                           @QueryParam( "callback" ) 
@DefaultValue( "callback" ) String callback )
+        throws Exception {
+
+        ApiResponse response = createApiResponse();
+        response.setAction( "cassandra setup" );
+
+        logger.info( "Setting up Cassandra" );
+
+
+        emf.boostrap();
+        management.setup();
+
+        response.setSuccess();
+
+        return new JSONWithPadding( response, callback );
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/usergrid/blob/7a4f36ab/stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
----------------------------------------------------------------------
diff --git 
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
new file mode 100644
index 0000000..8e2946c
--- /dev/null
+++ 
b/stack/rest/src/main/java/org/apache/usergrid/rest/system/IndexResource.java
@@ -0,0 +1,331 @@
+/*
+ *
+ *  * 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.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 )
+        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 )
+        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 );
+    }
+
+    @RequireSystemAccess
+    @PUT
+    @Path( "rebuild" )
+    public JSONWithPadding 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,
+                                              @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,
+                                              @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,
+                                               @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,
+                                              @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(
+        @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,
+                                                      @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,
+                                     @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 );
+    }
+
+
+    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,
+                                                            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 ) {
+
+
+        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 );
+    }
+}

Reply via email to