org.apache.usergrid.services.DBServiceManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.usergrid.services.DBServiceManager.java

Source

/*
 * 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.services;

import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.apache.usergrid.batch.service.SchedulerService;
import org.apache.usergrid.locking.LockManager;
import org.apache.usergrid.mq.QueueManager;
import org.apache.usergrid.persistence.Entity;
import org.apache.usergrid.persistence.EntityManager;
import org.apache.usergrid.persistence.EntityRef;
import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.entities.User;
import org.apache.usergrid.services.ServiceParameter.IdParameter;
import org.apache.usergrid.services.applications.ApplicationsService;
import org.apache.usergrid.services.exceptions.UndefinedServiceEntityTypeException;
import org.apache.usergrid.services.users.UsersService;
import org.apache.usergrid.utils.ListUtils;

import org.apache.commons.lang.StringUtils;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import static org.apache.usergrid.persistence.SimpleEntityRef.ref;
import static org.apache.usergrid.utils.InflectionUtils.pluralize;

public class DBServiceManager {

    private static final Logger logger = LoggerFactory.getLogger(DBServiceManager.class);

    /** A pointer that signals we couldn't find a class */
    private static final Class<Service> NOTFOUNDPOINTER = Service.class;

    // because one typo can ruin your whole day
    public static final String ENTITY = "entity";
    public static final String ENTITY_SUFFIX = "." + ENTITY;
    public static final String COLLECTION = "collection";
    public static final String COLLECTION_SUFFIX = "." + COLLECTION;
    public static final String OSS_PACKAGE_PREFIX = "org.apache.usergrid.services";
    public static final String COM_PACKAGE_PREFIX = "com.usergrid.services";
    public static final String SERVICE_PACKAGE_PREFIXES = "usergrid.service.packages";

    public static final String APPLICATION_REQUESTS = "user.requests";
    public static final String APPLICATION_REQUESTS_PER = APPLICATION_REQUESTS + ".";
    public static final String IMPL = "Impl";

    private User user;

    private UUID userId;

    private EntityManager em;

    private ServiceManagerFactory smf;
    private QueueManager qm;

    private Properties properties;

    // search for commercial packages first for SaaS version
    public static String[] package_prefixes = { OSS_PACKAGE_PREFIX };

    public DBServiceManager() {
    }

    public DBServiceManager init(ServiceManagerFactory smf, EntityManager em, Properties properties,
            QueueManager qm) {
        this.smf = smf;
        this.em = em;
        this.qm = qm;
        this.properties = properties;

        // additional logging to help debug https://issues.apache.org/jira/browse/USERGRID-1291
        if (em == null) {
            logger.error("EntityManager is null");
        }
        if (qm == null) {
            logger.error("QueueManager is null");
        }

        //        if ( em != null ) {
        //            try {
        //                user = em.getApplication().getUser();
        //                if(user == null){
        //                    Exception e = new RuntimeException("user id {"+em.getUserId()+"} is returning null");
        //                    logger.error("Failed to get user",e);
        //                    throw e;
        //                }
        //                userId = user.getUuid();
        //            }
        //            catch ( Exception e ) {
        //                logger.error( "ServiceManager init failure", e );
        //                throw new RuntimeException( e );
        //            }
        //        }
        //        if ( properties != null ) {
        //            String packages = properties.getProperty( SERVICE_PACKAGE_PREFIXES );
        //            if ( !StringUtils.isEmpty( packages ) ) {
        //                setServicePackagePrefixes( packages );
        //            }
        //        }
        return this;
    }

    //    public UserContext getUserContext() {
    //        return smf.getUserContext();
    //    }

    private void setServicePackagePrefixes(String packages) {
        List<String> packagePrefixes = new ArrayList<String>();
        Collections.addAll(packagePrefixes, package_prefixes);

        String[] prefixes = packages.split(";");
        for (String prefix : prefixes) {
            if (!packagePrefixes.contains(prefix)) {
                packagePrefixes.add(prefix);
            }
        }
        package_prefixes = packagePrefixes.toArray(new String[packagePrefixes.size()]);
    }

    public EntityManager getEntityManager() {
        return em;
    }

    public UUID getUserId() {
        return user.getUuid();
    }

    /** Return true if our current userId is the managment Id */
    public boolean isMangementUser() {
        return smf.getManagementAppId().equals(getUserId());
    }

    public EntityRef getUserRef() {
        return ref(User.ENTITY_TYPE, userId);
    }

    public User getUser() {
        return user;
    }

    public Service getEntityService(String entityType) {
        String serviceType = "/" + pluralize(entityType);
        return getService(serviceType);
    }

    public Entity importEntity(ServiceRequest request, Entity entity) throws Exception {
        Service service = getEntityService(entity.getType());
        if (service != null) {
            return service.importEntity(request, entity);
        }
        return entity;
    }

    public Entity writeEntity(ServiceRequest request, Entity entity) throws Exception {
        Service service = getEntityService(entity.getType());
        if (service != null) {
            return service.writeEntity(request, entity);
        }
        return entity;
    }

    public Entity updateEntity(ServiceRequest request, EntityRef ref, ServicePayload payload) throws Exception {
        Service service = getEntityService(ref.getType());
        if (service != null) {
            return service.updateEntity(request, ref, payload);
        }
        return null;
    }

    public Service getService(String serviceType) {
        return getService(serviceType, true);
    }

    public Service getService(String serviceType, boolean fallback) {

        if (serviceType == null) {
            return null;
        }

        if (logger.isTraceEnabled()) {
            logger.trace("Looking up service pattern: {}", serviceType);
        }

        ServiceInfo info = ServiceInfo.getServiceInfo(serviceType);

        if (info == null) {
            return null;
        }

        Service service = getServiceInstance(info);

        if (service != null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Returning service instance: {}", service.getClass());
            }
        }

        /*
           * if ((service == null) && fallback) { for (String pattern :
         * info.getPatterns()) { service = getService(pattern, false); if
         * (service != null) { break; } } }
         */

        if (service == null) {
            logger.info("Service {} not found", serviceType);
        }

        return service;
    }

    private static LoadingCache<ServiceInfo, Class<Service>> serviceClassCache = CacheBuilder.newBuilder()
            .maximumSize(100).expireAfterAccess(5, TimeUnit.MINUTES)
            .build(new CacheLoader<ServiceInfo, Class<Service>>() {
                public Class<Service> load(ServiceInfo key) { // no checked exception
                    return findClass(key);
                }
            });

    /** For the service info find the class that this maps */
    private static Class<Service> findClass(ServiceInfo info) {
        Class<Service> cls = null;

        String cname = null;

        for (String pattern : info.getPatterns()) {
            for (String prefix : package_prefixes) {

                cname = prefix.concat(".").concat(ServiceInfo.getClassName(pattern));

                cls = findClass(cname);

                if (cls != null) {
                    return cls;
                }
            }
        }

        //We didn't find anything, return the not found pointer
        return NOTFOUNDPOINTER;
    }

    @SuppressWarnings("unchecked")
    private static Class<Service> findClass(String classname) {

        Class<Service> cls;
        try {
            if (logger.isTraceEnabled()) {
                logger.trace("Attempting to instantiate service class {}", classname);
            }
            cls = (Class<Service>) Class.forName(classname);
            if (cls.isInterface()) {
                cls = (Class<Service>) Class.forName(classname.concat(IMPL));
            }
            if ((cls != null) && !Modifier.isAbstract(cls.getModifiers())) {
                return cls;
            }
        } catch (ClassNotFoundException e1) {
            if (logger.isTraceEnabled()) {
                logger.trace("Could not find class", e1);
            }
        }
        return null;
    }

    private Class<Service> findServiceClass(ServiceInfo info) {
        Class<Service> cls = null;

        try {
            cls = serviceClassCache.get(info);
        } catch (ExecutionException e) {
            //shouldn't happen, just to be safe
            throw new RuntimeException(e);
        }

        //Makes me feel dirty on the inside, but neccessary for the guava cache non null
        if (cls == NOTFOUNDPOINTER) {
            return null;
        }

        return cls;
    }

    private Service getServiceInstance(ServiceInfo info) {

        Class<Service> cls = findServiceClass(info);
        if (cls != null) {
            Service s = null;
            try {
                s = cls.newInstance();
            } catch (Exception e) {
                logger.error("cannot instantiate {}", cls.getName(), e);
            }
            if (s instanceof AbstractService) {
                AbstractService as = ((AbstractService) s);
                //                as.setServiceManager( this );
                as.init(info);
            }
            if (s != null) {
                if (s.getEntityType() == null) {
                    throw new UndefinedServiceEntityTypeException();
                }
            }
            return s;
        }

        return null;
    }

    //    public ServiceRequest newRequest( ServiceAction action, List<ServiceParameter> parameters ) throws Exception {
    //        return newRequest( action, false, parameters, null, true, true );
    //    }
    //
    //
    //    public ServiceRequest newRequest( ServiceAction action, List<ServiceParameter> parameters, ServicePayload payload )
    //            throws Exception {
    //        return newRequest( action, false, parameters, payload, true, true );
    //    }

    //    private ServiceRequest getUserRequest( ServiceAction action, boolean returnsTree,
    //                                                  List<ServiceParameter> parameters, ServicePayload payload )
    //            throws Exception {
    //
    //        String serviceName = pluralize( User.ENTITY_TYPE );
    //        ListUtils.requeue( parameters, new IdParameter( userId ) );
    //        return new ServiceRequest( this, action, serviceName, parameters, payload, returnsTree );
    //    }

    static UsersService appService = new UsersService();

    //    public ServiceRequest newRequest( ServiceAction action, boolean returnsTree, List<ServiceParameter> parameters,
    //                                      ServicePayload payload, boolean returnsInboundConnections,
    //                                      boolean returnsOutboundConnections ) throws Exception {
    //
    //        if ( em != null ) {
    //            if ( action != null ) {
    //                em.incrementAggregateCounters( null, null, null,
    //                        APPLICATION_REQUESTS_PER.concat( action.toString().toLowerCase() ), 1 );
    //            }
    //        }
    //
    //        if ( !ServiceParameter.moreParameters( parameters ) ) {
    //            return getUserRequest( action, returnsTree, parameters, payload );
    //        }
    //
    //        if ( !ServiceParameter.firstParameterIsName( parameters ) ) {
    //            return null;
    //        }
    //
    //        String nameParam = ServiceParameter.firstParameter( parameters ).getName();
    //        if ( appService.hasEntityCommand( nameParam ) || appService.hasEntityDictionary( nameParam ) ) {
    //            return getUserRequest( action, returnsTree, parameters, payload );
    //        }
    //
    //        // special-case for Notifications. todo: generalize
    //        if ( action == ServiceAction.POST &&
    //                ServiceParameter.lastParameterIsName( parameters ) &&
    //                "notifications".equals( parameters.get( parameters.size() - 1 ).getName() ) ) {
    ////            return new ServiceRequest( this, action, "notifications", parameters, payload, returnsTree );
    //        }
    //
    //        String serviceName = pluralize( ServiceParameter.dequeueParameter( parameters ).getName() );
    ////        return new ServiceRequest( this, action, serviceName, parameters, payload, returnsTree,
    ////            returnsInboundConnections, returnsOutboundConnections );
    //    }

    //    public ServiceRequest newRequest( ServiceAction action, boolean returnsTree, List<ServiceParameter> parameters,
    //                                      ServicePayload payload ) throws Exception {
    //        return newRequest( action, returnsTree, parameters, payload, true, true );
    //    }

    public void notifyExecutionEventListeners(ServiceAction action, ServiceRequest request, ServiceResults results,
            ServicePayload payload) {
        smf.notifyExecutionEventListeners(action, request, results, payload);
    }

    public void notifyCollectionEventListeners(String path, ServiceResults results) {
        smf.notifyCollectionEventListeners(path, results);
    }

    public SchedulerService getSchedulerService() {
        return smf.getSchedulerService();
    }

    public LockManager getLockManager() {
        return smf.getLockManager();
    }

    public QueueManager getQueueManager() {
        return qm;
    }

    public Properties getProperties() {
        return properties;
    }
}