com.sitewhere.mongodb.tenant.MongoTenantManagement.java Source code

Java tutorial

Introduction

Here is the source code for com.sitewhere.mongodb.tenant.MongoTenantManagement.java

Source

/*
 * Copyright (c) SiteWhere, LLC. All rights reserved. http://www.sitewhere.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package com.sitewhere.mongodb.tenant;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoTimeoutException;
import com.mongodb.WriteResult;
import com.sitewhere.core.SiteWherePersistence;
import com.sitewhere.mongodb.IUserManagementMongoClient;
import com.sitewhere.mongodb.MongoPersistence;
import com.sitewhere.mongodb.common.MongoSiteWhereEntity;
import com.sitewhere.rest.model.tenant.Tenant;
import com.sitewhere.rest.model.tenant.TenantGroup;
import com.sitewhere.rest.model.tenant.TenantGroupElement;
import com.sitewhere.server.lifecycle.LifecycleComponent;
import com.sitewhere.spi.SiteWhereException;
import com.sitewhere.spi.SiteWhereSystemException;
import com.sitewhere.spi.error.ErrorCode;
import com.sitewhere.spi.error.ErrorLevel;
import com.sitewhere.spi.search.ISearchCriteria;
import com.sitewhere.spi.search.ISearchResults;
import com.sitewhere.spi.search.user.ITenantSearchCriteria;
import com.sitewhere.spi.server.lifecycle.LifecycleComponentType;
import com.sitewhere.spi.tenant.ITenant;
import com.sitewhere.spi.tenant.ITenantGroup;
import com.sitewhere.spi.tenant.ITenantGroupElement;
import com.sitewhere.spi.tenant.ITenantManagement;
import com.sitewhere.spi.tenant.request.ITenantCreateRequest;
import com.sitewhere.spi.tenant.request.ITenantGroupCreateRequest;
import com.sitewhere.spi.tenant.request.ITenantGroupElementCreateRequest;

/**
 * Tenant management implementation that uses MongoDB for persistence.
 * 
 * @author dadams
 */
public class MongoTenantManagement extends LifecycleComponent implements ITenantManagement {

    /** Static logger instance */
    private static Logger LOGGER = Logger.getLogger(MongoTenantManagement.class);

    /** Injected with global SiteWhere Mongo client */
    private IUserManagementMongoClient mongoClient;

    public MongoTenantManagement() {
        super(LifecycleComponentType.DataStore);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.sitewhere.spi.server.lifecycle.ILifecycleComponent#start()
     */
    public void start() throws SiteWhereException {
        /** Ensure that expected indexes exist */
        ensureIndexes();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.sitewhere.spi.server.lifecycle.ILifecycleComponent#getLogger()
     */
    @Override
    public Logger getLogger() {
        return LOGGER;
    }

    /**
     * Ensure that expected collection indexes exist.
     * 
     * @throws SiteWhereException
     */
    protected void ensureIndexes() throws SiteWhereException {
        getMongoClient().getTenantsCollection().createIndex(new BasicDBObject(MongoTenant.PROP_ID, 1),
                new BasicDBObject("unique", true));
        getMongoClient().getTenantsCollection().createIndex(new BasicDBObject(MongoTenant.PROP_AUTH_TOKEN, 1),
                new BasicDBObject("unique", true));
        getMongoClient().getTenantGroupsCollection().createIndex(new BasicDBObject(MongoTenantGroup.PROP_TOKEN, 1),
                new BasicDBObject("unique", true));
        getMongoClient().getTenantGroupElementsCollection()
                .createIndex(new BasicDBObject(MongoTenantGroupElement.PROP_GROUP_TOKEN, 1)
                        .append(MongoTenantGroupElement.PROP_TENANT_ID, 1), new BasicDBObject("unique", true));
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.sitewhere.spi.server.lifecycle.ILifecycleComponent#stop()
     */
    public void stop() throws SiteWhereException {
        LOGGER.info("Mongo user management stopped.");
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#createTenant(com.sitewhere.spi
     * .tenant. request.ITenantCreateRequest)
     */
    @Override
    public ITenant createTenant(ITenantCreateRequest request) throws SiteWhereException {
        ITenant existing = getTenantById(request.getId());
        if (existing != null) {
            throw new SiteWhereSystemException(ErrorCode.DuplicateTenantId, ErrorLevel.ERROR);
        }

        // Use common logic so all backend implementations work the same.
        Tenant tenant = SiteWherePersistence.tenantCreateLogic(request);

        DBCollection tenants = getMongoClient().getTenantsCollection();
        DBObject created = MongoTenant.toDBObject(tenant);
        MongoPersistence.insert(tenants, created);

        return MongoTenant.fromDBObject(created);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#updateTenant(java.lang.String,
     * com.sitewhere.spi.tenant.request.ITenantCreateRequest)
     */
    @Override
    public ITenant updateTenant(String id, ITenantCreateRequest request) throws SiteWhereException {
        DBObject dbExisting = assertTenant(id);
        Tenant existing = MongoTenant.fromDBObject(dbExisting);

        // Use common update logic so that backend implemetations act the same
        // way.
        SiteWherePersistence.tenantUpdateLogic(request, existing);
        DBObject updated = MongoTenant.toDBObject(existing);

        BasicDBObject query = new BasicDBObject(MongoTenant.PROP_ID, id);
        DBCollection tenants = getMongoClient().getTenantsCollection();
        MongoPersistence.update(tenants, query, updated);

        return MongoTenant.fromDBObject(updated);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.sitewhere.spi.tenant.ITenantManagement#getTenantById(java.lang.
     * String)
     */
    @Override
    public ITenant getTenantById(String id) throws SiteWhereException {
        DBObject dbExisting = getTenantObjectById(id);
        if (dbExisting == null) {
            return null;
        }
        return MongoTenant.fromDBObject(dbExisting);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#getTenantByAuthenticationToken
     * (java.lang .String)
     */
    @Override
    public ITenant getTenantByAuthenticationToken(String token) throws SiteWhereException {
        try {
            DBCollection tenants = getMongoClient().getTenantsCollection();
            BasicDBObject query = new BasicDBObject(MongoTenant.PROP_AUTH_TOKEN, token);
            DBObject match = tenants.findOne(query);
            if (match == null) {
                return null;
            }
            return MongoTenant.fromDBObject(match);
        } catch (MongoTimeoutException e) {
            throw new SiteWhereException("Connection to MongoDB lost.", e);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#listTenants(com.sitewhere.spi.
     * search. user.ITenantSearchCriteria)
     */
    @Override
    public ISearchResults<ITenant> listTenants(ITenantSearchCriteria criteria) throws SiteWhereException {
        DBCollection tenants = getMongoClient().getTenantsCollection();
        BasicDBObject dbCriteria = new BasicDBObject();
        if (criteria.getTextSearch() != null) {
            try {
                Pattern regex = Pattern.compile(Pattern.quote(criteria.getTextSearch()));
                DBObject idSearch = new BasicDBObject(MongoTenant.PROP_ID, regex);
                DBObject nameSearch = new BasicDBObject(MongoTenant.PROP_NAME, regex);
                BasicDBList or = new BasicDBList();
                or.add(idSearch);
                or.add(nameSearch);
                dbCriteria.append("$or", or);
            } catch (PatternSyntaxException e) {
                LOGGER.warn("Invalid regex for searching tenant list. Ignoring.");
            }
        }
        if (criteria.getUserId() != null) {
            dbCriteria.append(MongoTenant.PROP_AUTH_USERS, criteria.getUserId());
        }
        BasicDBObject sort = new BasicDBObject(MongoTenant.PROP_NAME, 1);
        ISearchResults<ITenant> list = MongoPersistence.search(ITenant.class, tenants, dbCriteria, sort, criteria);
        SiteWherePersistence.tenantListLogic(list.getResults(), criteria);
        return list;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#deleteTenant(java.lang.String,
     * boolean)
     */
    @Override
    public ITenant deleteTenant(String tenantId, boolean force) throws SiteWhereException {
        DBObject existing = assertTenant(tenantId);
        if (force) {
            DBCollection tenants = getMongoClient().getTenantsCollection();
            MongoPersistence.delete(tenants, existing);
            return MongoTenant.fromDBObject(existing);
        } else {
            MongoSiteWhereEntity.setDeleted(existing, true);
            BasicDBObject query = new BasicDBObject(MongoTenant.PROP_ID, tenantId);
            DBCollection tenants = getMongoClient().getTenantsCollection();
            MongoPersistence.update(tenants, query, existing);
            return MongoTenant.fromDBObject(existing);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.sitewhere.spi.tenant.ITenantManagement#createTenantGroup(com.
     * sitewhere.spi. tenant.request.ITenantGroupCreateRequest)
     */
    @Override
    public ITenantGroup createTenantGroup(ITenantGroupCreateRequest request) throws SiteWhereException {
        // Use common logic so all backend implementations work the same.
        String uuid = ((request.getToken() != null) ? request.getToken() : UUID.randomUUID().toString());
        TenantGroup group = SiteWherePersistence.tenantGroupCreateLogic(uuid, request);

        DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
        DBObject created = MongoTenantGroup.toDBObject(group);
        MongoPersistence.insert(tgroups, created);

        return MongoTenantGroup.fromDBObject(created);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#updateTenantGroup(java.lang.
     * String, com.sitewhere.spi.tenant.request.ITenantGroupCreateRequest)
     */
    @Override
    public ITenantGroup updateTenantGroup(String token, ITenantGroupCreateRequest request)
            throws SiteWhereException {
        DBObject dbExisting = assertTenantGroup(token);
        TenantGroup existing = MongoTenantGroup.fromDBObject(dbExisting);

        // Use common update logic.
        SiteWherePersistence.tenantGroupUpdateLogic(request, existing);
        DBObject updated = MongoTenantGroup.toDBObject(existing);

        BasicDBObject query = new BasicDBObject(MongoTenantGroup.PROP_TOKEN, token);
        DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
        MongoPersistence.update(tgroups, query, updated);

        return MongoTenantGroup.fromDBObject(updated);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#getTenantGroupByToken(java.
     * lang.String)
     */
    @Override
    public ITenantGroup getTenantGroupByToken(String token) throws SiteWhereException {
        DBObject dbExisting = getTenantGroupObjectByToken(token);
        if (dbExisting == null) {
            return null;
        }
        return MongoTenantGroup.fromDBObject(dbExisting);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#listTenantGroups(com.sitewhere
     * .spi. search.ISearchCriteria)
     */
    @Override
    public ISearchResults<ITenantGroup> listTenantGroups(ISearchCriteria criteria) throws SiteWhereException {
        DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
        BasicDBObject dbCriteria = new BasicDBObject();
        BasicDBObject sort = new BasicDBObject(MongoTenantGroup.PROP_NAME, 1);
        ISearchResults<ITenantGroup> list = MongoPersistence.search(ITenantGroup.class, tgroups, dbCriteria, sort,
                criteria);
        return list;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#deleteTenantGroup(java.lang.
     * String, boolean)
     */
    @Override
    public ITenantGroup deleteTenantGroup(String token, boolean force) throws SiteWhereException {
        DBObject existing = assertTenantGroup(token);
        if (force) {
            DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
            MongoPersistence.delete(tgroups, existing);
            return MongoTenantGroup.fromDBObject(existing);
        } else {
            MongoSiteWhereEntity.setDeleted(existing, true);
            BasicDBObject query = new BasicDBObject(MongoTenantGroup.PROP_TOKEN, token);
            DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
            MongoPersistence.update(tgroups, query, existing);
            return MongoTenantGroup.fromDBObject(existing);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#addTenantGroupElements(java.
     * lang.String, java.util.List)
     */
    @Override
    public List<ITenantGroupElement> addTenantGroupElements(String groupToken,
            List<ITenantGroupElementCreateRequest> elements) throws SiteWhereException {
        List<ITenantGroupElement> results = new ArrayList<ITenantGroupElement>();
        for (ITenantGroupElementCreateRequest request : elements) {
            TenantGroupElement element = SiteWherePersistence.tenantGroupElementCreateLogic(groupToken, request);
            DBObject created = MongoTenantGroupElement.toDBObject(element);
            MongoPersistence.insert(getMongoClient().getTenantGroupElementsCollection(), created);
            results.add(MongoTenantGroupElement.fromDBObject(created));
        }
        return results;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#removeTenantGroupElements(java
     * .lang. String, java.util.List)
     */
    @Override
    public List<ITenantGroupElement> removeTenantGroupElements(String groupToken,
            List<ITenantGroupElementCreateRequest> elements) throws SiteWhereException {
        List<ITenantGroupElement> deleted = new ArrayList<ITenantGroupElement>();
        for (ITenantGroupElementCreateRequest request : elements) {
            BasicDBObject match = new BasicDBObject(MongoTenantGroupElement.PROP_GROUP_TOKEN, groupToken)
                    .append(MongoTenantGroupElement.PROP_TENANT_ID, request.getTenantId());
            DBCursor found = getMongoClient().getTenantGroupElementsCollection().find(match);
            while (found.hasNext()) {
                DBObject current = found.next();
                WriteResult result = MongoPersistence.delete(getMongoClient().getTenantGroupElementsCollection(),
                        current);
                if (result.getN() > 0) {
                    deleted.add(MongoTenantGroupElement.fromDBObject(current));
                }
            }
        }
        return deleted;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.sitewhere.spi.tenant.ITenantManagement#listTenantGroupElements(java.
     * lang. String, com.sitewhere.spi.search.ISearchCriteria)
     */
    @Override
    public ISearchResults<ITenantGroupElement> listTenantGroupElements(String groupId, ISearchCriteria criteria)
            throws SiteWhereException {
        BasicDBObject match = new BasicDBObject(MongoTenantGroupElement.PROP_GROUP_TOKEN, groupId);
        BasicDBObject sort = new BasicDBObject(MongoTenantGroupElement.PROP_TENANT_ID, 1);
        return MongoPersistence.search(ITenantGroupElement.class,
                getMongoClient().getTenantGroupElementsCollection(), match, sort, criteria);
    }

    /**
     * Get the {@link DBObject} for a tenant given id. Throw an exception if not
     * found.
     * 
     * @param id
     * @return
     * @throws SiteWhereException
     */
    protected DBObject assertTenant(String id) throws SiteWhereException {
        DBObject match = getTenantObjectById(id);
        if (match == null) {
            throw new SiteWhereSystemException(ErrorCode.InvalidTenantId, ErrorLevel.ERROR,
                    HttpServletResponse.SC_NOT_FOUND);
        }
        return match;
    }

    /**
     * Get the DBObject for a Tenant given unique id.
     * 
     * @param id
     * @return
     * @throws SiteWhereException
     */
    protected DBObject getTenantObjectById(String id) throws SiteWhereException {
        try {
            DBCollection tenants = getMongoClient().getTenantsCollection();
            BasicDBObject query = new BasicDBObject(MongoTenant.PROP_ID, id);
            return tenants.findOne(query);
        } catch (MongoTimeoutException e) {
            throw new SiteWhereException("Connection to MongoDB lost.", e);
        }
    }

    /**
     * Get the {@link DBObject} for a tenant group given token. Throw an
     * exception if not found.
     * 
     * @param token
     * @return
     * @throws SiteWhereException
     */
    protected DBObject assertTenantGroup(String token) throws SiteWhereException {
        DBObject match = getTenantGroupObjectByToken(token);
        if (match == null) {
            throw new SiteWhereSystemException(ErrorCode.InvalidTenantGroupId, ErrorLevel.ERROR,
                    HttpServletResponse.SC_NOT_FOUND);
        }
        return match;
    }

    /**
     * Get the DBObject for a TenantGroup given token.
     * 
     * @param token
     * @return
     * @throws SiteWhereException
     */
    protected DBObject getTenantGroupObjectByToken(String token) throws SiteWhereException {
        try {
            DBCollection tgroups = getMongoClient().getTenantGroupsCollection();
            BasicDBObject query = new BasicDBObject(MongoTenantGroup.PROP_TOKEN, token);
            return tgroups.findOne(query);
        } catch (MongoTimeoutException e) {
            throw new SiteWhereException("Connection to MongoDB lost.", e);
        }
    }

    public IUserManagementMongoClient getMongoClient() {
        return mongoClient;
    }

    public void setMongoClient(IUserManagementMongoClient mongoClient) {
        this.mongoClient = mongoClient;
    }
}