/* * * * 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.corepersistence.service; import com.google.common.base.Optional; import com.google.inject.Inject; import org.apache.usergrid.corepersistence.asyncevents.AsyncEventService; import org.apache.usergrid.corepersistence.asyncevents.EventBuilder; import org.apache.usergrid.corepersistence.index.CollectionSettings; import org.apache.usergrid.corepersistence.index.CollectionSettingsFactory; import org.apache.usergrid.corepersistence.index.CollectionSettingsScopeImpl; import org.apache.usergrid.corepersistence.rx.impl.AllEntityIdsObservable; import org.apache.usergrid.corepersistence.util.CpNamingUtils; import org.apache.usergrid.persistence.Schema; import org.apache.usergrid.persistence.actorsystem.ActorSystemFig; import org.apache.usergrid.persistence.collection.EntityCollectionManager; import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory; import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope; import org.apache.usergrid.persistence.core.scope.ApplicationScope; import org.apache.usergrid.persistence.graph.GraphManager; import org.apache.usergrid.persistence.graph.GraphManagerFactory; import org.apache.usergrid.persistence.map.MapManager; import org.apache.usergrid.persistence.map.MapManagerFactory; import org.apache.usergrid.persistence.map.MapScope; import org.apache.usergrid.persistence.model.entity.Id; import org.apache.usergrid.persistence.model.entity.SimpleId; import org.apache.usergrid.utils.InflectionUtils; import rx.Observable; import java.util.ArrayList; import java.util.Map; import static org.apache.usergrid.corepersistence.util.CpNamingUtils.createGraphOperationTimestamp; import static org.apache.usergrid.persistence.Schema.TYPE_APPLICATION; /** * implementation of application operations */ public class ApplicationServiceImpl implements ApplicationService{ private final AllEntityIdsObservable allEntityIdsObservable; private final EntityCollectionManagerFactory entityCollectionManagerFactory; private final AsyncEventService asyncEventService; private final EventBuilder eventBuilder; private final MapManagerFactory mapManagerFactory; private final GraphManagerFactory graphManagerFactory; private final CollectionSettingsFactory collectionSettingsFactory; private final ActorSystemFig actorSystemFig; @Inject public ApplicationServiceImpl(AllEntityIdsObservable allEntityIdsObservable, EntityCollectionManagerFactory entityCollectionManagerFactory, AsyncEventService asyncEventService, EventBuilder eventBuilder, MapManagerFactory mapManagerFactory, GraphManagerFactory graphManagerFactory, CollectionSettingsFactory collectionSettingsFactory, ActorSystemFig actorSystemFig ){ this.allEntityIdsObservable = allEntityIdsObservable; this.entityCollectionManagerFactory = entityCollectionManagerFactory; this.asyncEventService = asyncEventService; this.eventBuilder = eventBuilder; this.mapManagerFactory = mapManagerFactory; this.graphManagerFactory = graphManagerFactory; this.collectionSettingsFactory = collectionSettingsFactory; this.actorSystemFig = actorSystemFig; } @Override public Observable<Id> deleteAllEntities(final ApplicationScope applicationScope, final int limit) { if (applicationScope.getApplication().getUuid().equals(CpNamingUtils.MANAGEMENT_APPLICATION_ID)) { throw new IllegalArgumentException("Can't delete from management app"); } //EventBuilder eventBuilder = injector.getInstance(EventBuilder.class); Observable appObservable = Observable.just(applicationScope); EntityCollectionManager entityCollectionManager = entityCollectionManagerFactory.createCollectionManager(applicationScope); GraphManager graphManager = graphManagerFactory.createEdgeManager(applicationScope); MapManager mapManager = getMapManagerForTypes(applicationScope); Observable<Id> countObservable = allEntityIdsObservable.getEntities(appObservable) .map(entityIdScope -> ((EntityIdScope) entityIdScope).getId()) .filter(id -> { final String type = InflectionUtils.pluralize(((Id) id).getType()); return ! (type.equals(Schema.COLLECTION_USERS) || type.equals(Schema.COLLECTION_GROUPS) || type.equals(InflectionUtils.pluralize( Schema.TYPE_APPLICATION)) || type.equals(Schema.COLLECTION_ROLES)); })//skip application entity and users and groups and roles ; if(limit>0){ countObservable = countObservable.limit(limit); } countObservable = countObservable.map(id -> { entityCollectionManager.mark((Id) id, null ) .mergeWith(graphManager.markNode((Id) id, createGraphOperationTimestamp())).toBlocking().last(); return id; }) .doOnNext(id -> deleteAsync(mapManager, applicationScope, (Id) id)); return countObservable; } /** * 4. Delete all entity documents out of elasticsearch. * 5. Compact Graph so that it deletes the marked values. * 6. Delete entity from cassandra using the map manager. **/ private Id deleteAsync(MapManager mapManager, ApplicationScope applicationScope, Id entityId ) { try { //Step 4 && 5 if ( !skipIndexingForType( entityId.getType(), applicationScope ) ) { asyncEventService.queueEntityDelete(applicationScope, entityId); } //Step 6 //delete from our UUID index mapManager.delete(entityId.getUuid().toString()); return entityId; }catch (Exception e){ throw new RuntimeException(e); } } private boolean skipIndexingForType( String type, ApplicationScope applicationScope ) { boolean skipIndexing = false; String collectionName = Schema.defaultCollectionName( type ); CollectionSettings collectionSettings = collectionSettingsFactory .getInstance( new CollectionSettingsScopeImpl(applicationScope.getApplication(), collectionName)); Optional<Map<String, Object>> collectionIndexingSchema = collectionSettings.getCollectionSettings( collectionName ); if ( collectionIndexingSchema.isPresent()) { Map jsonMapData = collectionIndexingSchema.get(); final ArrayList fields = (ArrayList) jsonMapData.get( "fields" ); if ( fields.size() == 1 && fields.get(0).equals("none")) { skipIndexing = true; } } return skipIndexing; } /** * Get the map manager for uuid mapping */ private MapManager getMapManagerForTypes( ApplicationScope applicationScope) { Id mapOwner = new SimpleId( applicationScope.getApplication().getUuid(), TYPE_APPLICATION ); final MapScope ms = CpNamingUtils.getEntityTypeMapScope(mapOwner); MapManager mm = mapManagerFactory.createMapManager(ms); return mm; } }