<commit_before>/*
 * Copyright 2014 The Apache Software Foundation.
 *
 * Licensed 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.corepersistence;


import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import org.apache.commons.lang.StringUtils;
import org.apache.usergrid.corepersistence.asyncevents.AsyncEventService;
import org.apache.usergrid.corepersistence.index.CollectionSettingsCacheFactory;
import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder;
import org.apache.usergrid.corepersistence.index.ReIndexService;
import org.apache.usergrid.corepersistence.service.CollectionService;
import org.apache.usergrid.corepersistence.service.ConnectionService;
import org.apache.usergrid.corepersistence.util.CpNamingUtils;
import org.apache.usergrid.exception.ConflictException;
import org.apache.usergrid.locking.LockManager;
import org.apache.usergrid.persistence.*;
import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.cassandra.CounterUtils;
import org.apache.usergrid.persistence.cassandra.Setup;
import org.apache.usergrid.persistence.collection.EntityCollectionManager;
import org.apache.usergrid.persistence.collection.exception.CollectionRuntimeException;
import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope;
import org.apache.usergrid.persistence.collection.uniquevalues.AkkaFig;
import org.apache.usergrid.persistence.collection.uniquevalues.UniqueValuesService;
import org.apache.usergrid.persistence.core.metrics.MetricsFactory;
import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
import org.apache.usergrid.persistence.core.util.Health;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
import org.apache.usergrid.persistence.exceptions.DuplicateUniquePropertyExistsException;
import org.apache.usergrid.persistence.exceptions.EntityNotFoundException;
import org.apache.usergrid.persistence.graph.*;
import org.apache.usergrid.persistence.graph.impl.SimpleSearchByEdgeType;
import org.apache.usergrid.persistence.index.EntityIndex;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.entity.SimpleId;
import org.apache.usergrid.persistence.model.util.UUIDGenerator;
import org.apache.usergrid.utils.UUIDUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import rx.Observable;

import java.util.*;

import static java.lang.String.CASE_INSENSITIVE_ORDER;
import static org.apache.usergrid.persistence.Schema.PROPERTY_NAME;
import static org.apache.usergrid.persistence.Schema.TYPE_APPLICATION;


/**
 * Implement good-old Usergrid EntityManagerFactory with the new-fangled Core Persistence API.
 * This is where we keep track of applications and system properties.
 */
public class CpEntityManagerFactory implements EntityManagerFactory, ApplicationContextAware {

    private static final Logger logger = LoggerFactory.getLogger( CpEntityManagerFactory.class );
    private final EntityManagerFig entityManagerFig;

    private ApplicationContext applicationContext;

    private Setup setup = null;

    EntityManager managementAppEntityManager = null;

    // cache of already instantiated entity managers
    private final String ENTITY_MANAGER_CACHE_SIZE = "entity.manager.cache.size";
    private final LoadingCache<UUID, EntityManager> entityManagers;

    private final ApplicationIdCache applicationIdCache;

    Application managementApp = null;

    private ManagerCache managerCache;

    private CassandraService cassandraService;
    private CounterUtils counterUtils;
    private Injector injector;
    private final ReIndexService reIndexService;
    private final MetricsFactory metricsFactory;
    private final AsyncEventService indexService;
    private final CollectionService collectionService;
    private final ConnectionService connectionService;
    private final GraphManagerFactory graphManagerFactory;
    private final CollectionSettingsCacheFactory collectionSettingsCacheFactory;
    private UniqueValuesService uniqueValuesService;
    private final LockManager lockManager;

    public static final String MANAGEMENT_APP_INIT_MAXRETRIES= "management.app.init.max-retries";
    public static final String MANAGEMENT_APP_INIT_INTERVAL = "management.app.init.interval";


    public CpEntityManagerFactory(
        final CassandraService cassandraService, final CounterUtils counterUtils, final Injector injector ) {

        this.cassandraService = cassandraService;
        this.counterUtils = counterUtils;
        this.injector = injector;
        this.reIndexService = injector.getInstance(ReIndexService.class);
        this.entityManagerFig = injector.getInstance(EntityManagerFig.class);
        this.managerCache = injector.getInstance( ManagerCache.class );
        this.metricsFactory = injector.getInstance( MetricsFactory.class );
        this.indexService = injector.getInstance( AsyncEventService.class );
        this.graphManagerFactory = injector.getInstance( GraphManagerFactory.class );
        this.collectionService = injector.getInstance( CollectionService.class );
        this.connectionService = injector.getInstance( ConnectionService.class );

        this.collectionSettingsCacheFactory = injector.getInstance( CollectionSettingsCacheFactory.class );

        AkkaFig akkaFig = injector.getInstance( AkkaFig.class );

        // this line always needs to be last due to the temporary cicular dependency until spring is removed
        this.applicationIdCache = injector.getInstance(ApplicationIdCacheFactory.class).getInstance(
            getManagementEntityManager() );

        if ( akkaFig.getAkkaEnabled() ) {
            try {
                this.uniqueValuesService = injector.getInstance( UniqueValuesService.class );
                this.uniqueValuesService.start();
            } catch (Throwable t) {
                logger.error("Error starting Akka", t);
                throw t;
            }
        }
        this.lockManager = injector.getInstance( LockManager.class );

        Properties properties = cassandraService.getProperties();

        entityManagers = createEntityManagerCache( properties );

        checkManagementApp( properties );
    }


    private LoadingCache<UUID, EntityManager> createEntityManagerCache(Properties properties) {

        int entityManagerCacheSize = 100;
        try {
            entityManagerCacheSize = Integer.parseInt( properties.getProperty( ENTITY_MANAGER_CACHE_SIZE, "100" ));
        } catch ( Exception e ) {
            logger.error("Error parsing " + ENTITY_MANAGER_CACHE_SIZE + ". Will use " + entityManagerCacheSize, e );
        }

        return CacheBuilder.newBuilder()
            .maximumSize(entityManagerCacheSize)
            .build(new CacheLoader<UUID, EntityManager>() {

                public EntityManager load( UUID appId ) { // no checked exception

                    // create new entity manager and pre-fetch its application
                    EntityManager entityManager = _getEntityManager( appId );
                    Application app = null;
                    Throwable throwable = null;
                    try {
                        app = entityManager.getApplication();
                    } catch (Throwable t) {
                        throwable = t;
                    }<commit_msg>Fix merge problem and ensure entityManagers is created before use<commit_after>/*
 * Copyright 2014 The Apache Software Foundation.
 *
 * Licensed 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.corepersistence;


import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import org.apache.commons.lang.StringUtils;
import org.apache.usergrid.corepersistence.asyncevents.AsyncEventService;
import org.apache.usergrid.corepersistence.index.CollectionSettingsCacheFactory;
import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder;
import org.apache.usergrid.corepersistence.index.ReIndexService;
import org.apache.usergrid.corepersistence.service.CollectionService;
import org.apache.usergrid.corepersistence.service.ConnectionService;
import org.apache.usergrid.corepersistence.util.CpNamingUtils;
import org.apache.usergrid.exception.ConflictException;
import org.apache.usergrid.locking.LockManager;
import org.apache.usergrid.persistence.*;
import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.cassandra.CounterUtils;
import org.apache.usergrid.persistence.cassandra.Setup;
import org.apache.usergrid.persistence.collection.EntityCollectionManager;
import org.apache.usergrid.persistence.collection.exception.CollectionRuntimeException;
import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope;
import org.apache.usergrid.persistence.collection.uniquevalues.AkkaFig;
import org.apache.usergrid.persistence.collection.uniquevalues.UniqueValuesService;
import org.apache.usergrid.persistence.core.metrics.MetricsFactory;
import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
import org.apache.usergrid.persistence.core.util.Health;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
import org.apache.usergrid.persistence.exceptions.DuplicateUniquePropertyExistsException;
import org.apache.usergrid.persistence.exceptions.EntityNotFoundException;
import org.apache.usergrid.persistence.graph.*;
import org.apache.usergrid.persistence.graph.impl.SimpleSearchByEdgeType;
import org.apache.usergrid.persistence.index.EntityIndex;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.entity.SimpleId;
import org.apache.usergrid.persistence.model.util.UUIDGenerator;
import org.apache.usergrid.utils.UUIDUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import rx.Observable;

import java.util.*;

import static java.lang.String.CASE_INSENSITIVE_ORDER;
import static org.apache.usergrid.persistence.Schema.PROPERTY_NAME;
import static org.apache.usergrid.persistence.Schema.TYPE_APPLICATION;


/**
 * Implement good-old Usergrid EntityManagerFactory with the new-fangled Core Persistence API.
 * This is where we keep track of applications and system properties.
 */
public class CpEntityManagerFactory implements EntityManagerFactory, ApplicationContextAware {

    private static final Logger logger = LoggerFactory.getLogger( CpEntityManagerFactory.class );
    private final EntityManagerFig entityManagerFig;

    private ApplicationContext applicationContext;

    private Setup setup = null;

    EntityManager managementAppEntityManager = null;

    // cache of already instantiated entity managers
    private final String ENTITY_MANAGER_CACHE_SIZE = "entity.manager.cache.size";
    private final LoadingCache<UUID, EntityManager> entityManagers;

    private final ApplicationIdCache applicationIdCache;

    Application managementApp = null;

    private ManagerCache managerCache;

    private CassandraService cassandraService;
    private CounterUtils counterUtils;
    private Injector injector;
    private final ReIndexService reIndexService;
    private final MetricsFactory metricsFactory;
    private final AsyncEventService indexService;
    private final CollectionService collectionService;
    private final ConnectionService connectionService;
    private final GraphManagerFactory graphManagerFactory;
    private final CollectionSettingsCacheFactory collectionSettingsCacheFactory;
    private UniqueValuesService uniqueValuesService;
    private final LockManager lockManager;

    public static final String MANAGEMENT_APP_INIT_MAXRETRIES= "management.app.init.max-retries";
    public static final String MANAGEMENT_APP_INIT_INTERVAL = "management.app.init.interval";


    public CpEntityManagerFactory(
        final CassandraService cassandraService, final CounterUtils counterUtils, final Injector injector ) {

        this.cassandraService = cassandraService;
        this.counterUtils = counterUtils;
        this.injector = injector;
        this.reIndexService = injector.getInstance(ReIndexService.class);
        this.entityManagerFig = injector.getInstance(EntityManagerFig.class);
        this.managerCache = injector.getInstance( ManagerCache.class );
        this.metricsFactory = injector.getInstance( MetricsFactory.class );
        this.indexService = injector.getInstance( AsyncEventService.class );
        this.graphManagerFactory = injector.getInstance( GraphManagerFactory.class );
        this.collectionService = injector.getInstance( CollectionService.class );
        this.connectionService = injector.getInstance( ConnectionService.class );
        this.collectionSettingsCacheFactory = injector.getInstance( CollectionSettingsCacheFactory.class );

        Properties properties = cassandraService.getProperties();
        this.entityManagers = createEntityManagerCache( properties );

        AkkaFig akkaFig = injector.getInstance( AkkaFig.class );


        logger.info("EntityManagerFactoring starting...");

        if ( akkaFig.getAkkaEnabled() ) {
            try {
                logger.info("Akka cluster starting...");
                this.uniqueValuesService = injector.getInstance( UniqueValuesService.class );
                this.uniqueValuesService.start();
            } catch (Throwable t) {
                logger.error("Error starting Akka", t);
                throw t;
            }
        }
        this.lockManager = injector.getInstance( LockManager.class );



        // this line always needs to be last due to the temporary cicular dependency until spring is removed
        this.applicationIdCache = injector.getInstance(ApplicationIdCacheFactory.class).getInstance(
            getManagementEntityManager() );

        checkManagementApp( properties );
    }


    private LoadingCache<UUID, EntityManager> createEntityManagerCache(Properties properties) {

        int entityManagerCacheSize = 100;
        try {
            entityManagerCacheSize = Integer.parseInt( properties.getProperty( ENTITY_MANAGER_CACHE_SIZE, "100" ));
        } catch ( Exception e ) {
            logger.error("Error parsing " + ENTITY_MANAGER_CACHE_SIZE + ". Will use " + entityManagerCacheSize, e );
        }

        return CacheBuilder.newBuilder()
            .maximumSize(entityManagerCacheSize)
            .build(new CacheLoader<UUID, EntityManager>() {

                public EntityManager load( UUID appId ) { // no checked exception

                    // create new entity manager and pre-fetch its application
                    EntityManager entityManager = _getEntityManager( appId );
                    Application app = null;
                    Throwable throwable = null;
                    try {
                        app = entityManager.getApplication();
                    } catch (Throwable t) {
                        throwable = t;
                    }
{'fraction_non_alphanumeric': 0.07600991183080735, 'fraction_numerical': 0.001844061545554083, 'mean_word_length': 4.104117647058824, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1378129', 'n_tokens_mistral': 4337, 'n_tokens_neox': 4271, 'n_words': 980}