/*
* 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.tools;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.usergrid.persistence.Entity;
import org.apache.usergrid.persistence.EntityManager;
import org.apache.usergrid.persistence.Query;
import org.apache.usergrid.persistence.Results;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.UUID;
/**
* Iterate through all data in a list of apps and get each or update entity.
*/
public class Repersist extends ToolBase {
static final Logger logger = LoggerFactory.getLogger( Repersist.class );
int count = 0;
@Override
@SuppressWarnings("static-access")
public Options createOptions() {
Options options = super.createOptions();
Option appsOpton = new Option("apps", true,
"Comma-separated list of apps to re-persisted in {appName}/{orgName} format");
appsOpton.setRequired(true);
options.addOption( appsOpton );
options.addOption("wait", true,
"Time in milliseconds to wait between entity re-persist");
options.addOption("update", false,
"Tool will update each and every entity in the listed apps");
return options;
}
@Override
public void runTool( CommandLine line ) throws Exception {
startSpring();
setVerbose( line );
String appsLine = line.getOptionValue("apps");
String[] orgApps = appsLine.split(",");
long wait = 100;
try {
wait = Long.parseLong(line.getOptionValue("wait"));
} catch( Exception e ) {
logger.error("Incorrect or missing wait time, using default: " + wait);
}
boolean update = line.hasOption("update");
for ( String orgApp : orgApps ) {
String[] orgAppParts = orgApp.split("/");
String org = orgAppParts[0];
String app = orgAppParts[1];
repersist( org, org + "/" + app, update, wait );
}
}
private void repersist( String organizationName, String applicationName, boolean update, long wait )
throws Exception {
logger.info( "\n\nRepersisting {}/{}\n", organizationName, applicationName );
UUID applicationId = emf.lookupApplication( applicationName );
if (applicationId == null) {
throw new RuntimeException( "Cannot find application " + applicationName );
}
final EntityManager em = emf.getEntityManager( applicationId );
organizationName = em.getApplication().getOrganizationName();
Map<String, Object> collectionMetadata = em.getApplicationCollectionMetadata();
for ( String collectionName : collectionMetadata.keySet() ) {
Query query = new Query();
query.setLimit( MAX_ENTITY_FETCH );
Results results = em.searchCollection( em.getApplicationRef(), collectionName, query );
while (results.size() > 0) {
for (Entity entity : results.getEntities()) {
if ( update ) {
// TODO: can we do this without updating the update of each entity?
em.update(entity);
}
count++;
if ( count % 1000 == 0 ) {
logger.info("Processed {} entities", count);
}
Thread.sleep( wait );
}
if (results.getCursor() == null) {
break;
}
query.setCursor( results.getCursor() );
results = em.searchCollection( em.getApplicationRef(), collectionName, query );
}
logger.info("Completed app {}/{} collection {}. Persisted {} entities",
organizationName, applicationName, collectionName, count);
}
}
}