org.eclipse.om2m.core.controller.Controller.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.om2m.core.controller.Controller.java

Source

/*******************************************************************************
 * Copyright (c) 2013-2016 LAAS-CNRS (www.laas.fr)
 * 7 Colonel Roche 31077 Toulouse - France
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Initial Contributors:
 *     Thierry Monteil : Project manager, technical co-manager
 *     Mahdi Ben Alaya : Technical co-manager
 *     Samir Medjiah : Technical co-manager
 *     Khalil Drira : Strategy expert
 *     Guillaume Garzone : Developer
 *     Franois Assaoui : Developer
 *
 * New contributors :
 *******************************************************************************/
package org.eclipse.om2m.core.controller;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.constants.MimeMediaType;
import org.eclipse.om2m.commons.constants.Operation;
import org.eclipse.om2m.commons.constants.ResultContent;
import org.eclipse.om2m.commons.entities.AccessControlOriginatorEntity;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.AccessControlRuleEntity;
import org.eclipse.om2m.commons.entities.ResourceEntity;
import org.eclipse.om2m.commons.exceptions.AccessDeniedException;
import org.eclipse.om2m.commons.exceptions.BadRequestException;
import org.eclipse.om2m.commons.exceptions.Om2mException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.Resource;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
import org.eclipse.om2m.core.datamapper.DataMapperSelector;
import org.eclipse.om2m.core.entitymapper.EntityMapper;
import org.eclipse.om2m.core.entitymapper.EntityMapperFactory;
import org.eclipse.om2m.core.persistence.PersistenceService;
import org.eclipse.om2m.persistence.service.DBService;
import org.eclipse.om2m.persistence.service.DBTransaction;

/**
 * Controller class contains generic and abstract Create, Retrieve, Update, Delete and Execute
 * methods to handle generic REST request that will be implemented in extended-to classes.
 *
 */
public abstract class Controller {
    /** Logger */
    protected static Log LOGGER = LogFactory.getLog(Controller.class);

    /** Pointer to Database service */
    protected DBService dbs;
    /** Transaction for the current instance of controller and request */
    protected DBTransaction transaction;

    /**
     * Perform the request on selected controller
     * @param request
     * @return
     */
    public ResponsePrimitive doRequest(RequestPrimitive request) throws Om2mException {
        ResponsePrimitive response = new ResponsePrimitive(request);
        dbs = PersistenceService.getInstance().getDbService();
        transaction = dbs.getDbTransaction();
        try {
            transaction.open();
            if (request.getOperation().equals(Operation.CREATE)) {
                response = doCreate(request);
            } else if (request.getOperation().equals(Operation.RETRIEVE)) {
                response = doRetrieve(request);
            } else if (request.getOperation().equals(Operation.UPDATE)) {
                response = doUpdate(request);
            } else if (request.getOperation().equals(Operation.DELETE)) {
                response = doDelete(request);
            } else {
                throw new BadRequestException("Incorrect Operation value (op): " + request.getOperation());
            }
        } catch (Om2mException om2mException) {
            throw om2mException;
        } catch (Exception e) {
            LOGGER.error("Controller internal error", e);
            throw e;
        } finally {
            transaction.close();
        }
        return response;
    }

    /**
     * Abstract Create method to handle generic REST request.
     * @param request - The generic request to handle.
     * @return The generic returned response.
     */
    public abstract ResponsePrimitive doCreate(RequestPrimitive request);

    /**
     * Abstract Retrieve method to handle generic REST request.
     * @param request - The generic request to handle.
     * @return The generic returned response.
     */
    public abstract ResponsePrimitive doRetrieve(RequestPrimitive request);

    /**
     * Abstract Update method to handle generic REST request.
     * @param request - The generic request to handle.
     * @return The generic returned response.
     */
    public abstract ResponsePrimitive doUpdate(RequestPrimitive request);

    /**
     * Abstract Delete method to handle generic REST request.
     * @param request - The generic request to handle.
     * @return The generic returned response.
     */
    public abstract ResponsePrimitive doDelete(RequestPrimitive request);

    /**
     * Check the access right based on acpId
     * @param acpID
     * @param originator
     * @param method
     */
    public void checkACP(String acpID, String originator, BigInteger method) throws AccessDeniedException {
        DBService db = PersistenceService.getInstance().getDbService();
        DBTransaction transaction = db.getDbTransaction();
        transaction.open();
        if (!originatorExists(originator)) {
            throw new AccessDeniedException("Provided originator not found");
        }
        AccessControlPolicyEntity acp = db.getDAOFactory().getAccessControlPolicyDAO().find(transaction, acpID);
        if (acp == null) {
            throw new ResourceNotFoundException();
        }
        List<AccessControlPolicyEntity> acpList = new ArrayList<>();
        acpList.add(acp);
        checkACP(acpList, originator, method);
        transaction.close();
    }

    /**
     * Checks the Access Right based on ACP list (Permission)
     * @param acp - Id of the accessRight
     * @param originator - requesting entity used by the requester
     * @param operation - requested method
     * @return error with a specific status code if the requesting Entity or the method does not exist otherwise null
     */
    public void checkACP(List<AccessControlPolicyEntity> acpList, String originator, BigInteger operation)
            throws AccessDeniedException {
        if (originator == null) {
            throw new AccessDeniedException();
        }
        if (acpList == null || acpList.isEmpty()) {
            throw new ResourceNotFoundException("Current resource does not have any ACP attached");
        }
        // Check Resource accessRight existence not found
        boolean originatorFound = false;
        boolean operationAllowed = false;
        for (AccessControlPolicyEntity acp : acpList) {
            for (AccessControlRuleEntity rule : acp.getPrivileges()) {
                originatorFound = false;
                operationAllowed = false;
                for (AccessControlOriginatorEntity originatorEntity : rule.getAccessControlOriginators()) {
                    if (originator.matches(originatorEntity.getOriginatorID().replace("*", ".*"))) {
                        originatorFound = true;
                        break;
                    }
                }
                if (originatorFound) {
                    if (operation.equals(Operation.CREATE) && rule.isCreate()) {
                        operationAllowed = true;
                    } else if (operation.equals(Operation.RETRIEVE) && rule.isRetrieve()) {
                        operationAllowed = true;
                    } else if (operation.equals(Operation.UPDATE) && rule.isUpdate()) {
                        operationAllowed = true;
                    } else if (operation.equals(Operation.DELETE) && rule.isDelete()) {
                        operationAllowed = true;
                    } else if (operation.equals(Operation.DISCOVERY) && rule.isDiscovery()) {
                        operationAllowed = true;
                    } else if (operation.equals(Operation.NOTIFY) && rule.isNotify()) {
                        operationAllowed = true;
                    }
                }
                if (originatorFound && operationAllowed) {
                    break;
                }
            }
            if (originatorFound && operationAllowed) {
                break;
            }
        }

        if (!originatorFound) {
            throw new AccessDeniedException();
        }
        if (!operationAllowed) {
            throw new AccessDeniedException();
        }
    }

    /**
     * Check Access Right from Acp Self privileges for ACP modifications
     * @param acp to check
     * @param originator to validate
     * @param operation
     */
    public void checkSelfACP(AccessControlPolicyEntity acp, String originator, BigInteger operation)
            throws AccessDeniedException {
        // Check Resource accessRight existence not found
        boolean originatorFound = false;
        boolean operationAllowed = false;

        for (AccessControlRuleEntity rule : acp.getSelfPrivileges()) {
            originatorFound = false;
            operationAllowed = false;
            for (AccessControlOriginatorEntity originatorEntity : rule.getAccessControlOriginators()) {
                if (originator.matches(originatorEntity.getOriginatorID().replace("*", ".*"))) {
                    originatorFound = true;
                    break;
                }
            }
            if (originatorFound) {
                if (operation.equals(Operation.CREATE)) {
                    if (rule.isCreate()) {
                        operationAllowed = true;
                    }
                } else if (operation.equals(Operation.RETRIEVE)) {
                    if (rule.isRetrieve()) {
                        operationAllowed = true;
                    }
                } else if (operation.equals(Operation.UPDATE)) {
                    if (rule.isUpdate()) {
                        operationAllowed = true;
                    }
                } else if (operation.equals(Operation.DELETE)) {
                    if (rule.isDelete()) {
                        operationAllowed = true;
                    }
                }
            }
            if (originatorFound && operationAllowed) {
                break;
            }
        }
        if (!originatorFound) {
            throw new AccessDeniedException();
        }
        if (!operationAllowed) {
            throw new AccessDeniedException();
        }
    }

    /**
     * Generates an random ID based on SecureRandom library
     * @param prefix - prefix of the resource ID
     * @param postfix - postfix of the resource ID
     * @return generated resource ID
     */
    public static String generateId(String prefix, String postfix) {
        SecureRandom secureRandom = new SecureRandom();
        return prefix + String.valueOf(secureRandom.nextInt(999999999)) + postfix;
    }

    /**
     * Generates a random ID based on SecureRandom library
     * @return generated resource ID
     */
    public static String generateId() {
        return generateId("", "");
    }

    protected void setLocationAndCreationContent(RequestPrimitive request, ResponsePrimitive response,
            ResourceEntity entity) {
        setLocationAndCreationContent(request, response, entity,
                EntityMapperFactory.getMapperFromResourceType(entity.getResourceType().intValue()));
    }

    @SuppressWarnings("unchecked")
    protected void setLocationAndCreationContent(RequestPrimitive request, ResponsePrimitive response,
            ResourceEntity entity, @SuppressWarnings("rawtypes") EntityMapper mapper) {
        if (request.getResultContent() != null) {
            if (request.getResultContent().equals(ResultContent.HIERARCHICAL_ADRESS)
                    || request.getResultContent().equals(ResultContent.HIERARCHICAL_AND_ATTRIBUTES)) {
                response.setLocation(entity.getHierarchicalURI());
            } else {
                response.setLocation(entity.getResourceID());
            }
            if (request.getResultContent().equals(ResultContent.HIERARCHICAL_AND_ATTRIBUTES)
                    || request.getResultContent().equals(ResultContent.ATTRIBUTES)) {
                Resource res = mapper.mapEntityToResource(entity, ResultContent.ATTRIBUTES);
                if (request.getReturnContentType().equals(MimeMediaType.OBJ)) {
                    response.setContent(res);
                } else {
                    String representation = DataMapperSelector.getDataMapperList()
                            .get(request.getReturnContentType()).objToString(res);
                    response.setContent(representation);
                }
            }
        } else {
            response.setContent(mapper.mapEntityToResource(entity, ResultContent.ATTRIBUTES));
            response.setLocation(entity.getResourceID());
        }
    }

    /**
     * Allows to know if the provided originator exists in the system
     * @param originator
     * @return true if exists
     */
    protected boolean originatorExists(String originator) {
        boolean isValid = false;
        DBService db = PersistenceService.getInstance().getDbService();
        DBTransaction transaction = db.getDbTransaction();
        transaction.open();
        AccessControlOriginatorEntity originatorEntity = db.getDAOFactory().getAccessControlOriginatorDAO()
                .find(transaction, originator);
        if (originatorEntity != null) {
            isValid = true;
        }
        transaction.close();
        return isValid;
    }

    /**
     * Allows to store the originator
     * @param originator
     */
    protected void registerOriginator(String originator) {
        DBService db = PersistenceService.getInstance().getDbService();
        DBTransaction transaction = db.getDbTransaction();
        transaction.open();
        // create the new originator
        AccessControlOriginatorEntity originatorEntity = new AccessControlOriginatorEntity();
        originatorEntity.setOriginatorID(originator);
        // persist the new access control originator
        db.getDAOFactory().getAccessControlOriginatorDAO().create(transaction, originatorEntity);
        transaction.commit();
        transaction.close();
    }

}