blob: 6d1e3e1eeb63ecab8233119e9837a835f88ab9b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2017 Orange.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*******************************************************************************/
package org.eclipse.om2m.core.controller;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.constants.Constants;
import org.eclipse.om2m.commons.constants.MimeMediaType;
import org.eclipse.om2m.commons.constants.Operation;
import org.eclipse.om2m.commons.constants.ResourceStatus;
import org.eclipse.om2m.commons.constants.ResourceType;
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
import org.eclipse.om2m.commons.constants.ShortName;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.AeAnncEntity;
import org.eclipse.om2m.commons.entities.CSEBaseEntity;
import org.eclipse.om2m.commons.entities.NodeAnncEntity;
import org.eclipse.om2m.commons.entities.RemoteCSEEntity;
import org.eclipse.om2m.commons.entities.ResourceEntity;
import org.eclipse.om2m.commons.entities.SubscriptionEntity;
import org.eclipse.om2m.commons.exceptions.BadRequestException;
import org.eclipse.om2m.commons.exceptions.ConflictException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.NodeAnnc;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
import org.eclipse.om2m.commons.utils.Util.DateUtil;
import org.eclipse.om2m.core.datamapper.DataMapperSelector;
import org.eclipse.om2m.core.entitymapper.EntityMapperFactory;
import org.eclipse.om2m.core.notifier.Notifier;
import org.eclipse.om2m.core.router.Patterns;
import org.eclipse.om2m.core.urimapper.UriMapper;
import org.eclipse.om2m.core.util.ControllerUtil;
import org.eclipse.om2m.core.util.ControllerUtil.UpdateUtil;
import org.eclipse.om2m.persistence.service.DAO;
/**
* Controller for Node resource
*
*/
public class NodeAnncController extends Controller {
/** Logger */
private static Log LOGGER = LogFactory.getLog(NodeAnncController.class);
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
/*
* NODE CREATION PROCEDURE
* @resourceName NP
* resourceType NP
* resourceID NP
* parentID NP
* accessControlPolicyIDs O
* creationTime NP
* expirationTime O
* lastModifiedTime NP
* labels O
*
* nodeID M
* hostedCSELink O
*
*/
ResponsePrimitive response = new ResponsePrimitive(request);
Patterns patterns = new Patterns();
// retrieve the parent
DAO<ResourceEntity> dao = (DAO<ResourceEntity>) patterns.getDAO(request.getTo(), dbs);
if (dao == null) {
throw new ResourceNotFoundException("Cannot find parent resource");
}
// Get the parent entity
ResourceEntity parentEntity = (ResourceEntity) dao.find(transaction, request.getTo());
// Check the parent existence
if (parentEntity == null) {
throw new ResourceNotFoundException("Cannot find parent resource");
}
List<NodeAnncEntity> childNodes = null;
List<AccessControlPolicyEntity> acpsToCheck = null;
List<SubscriptionEntity> subscriptions = null;
// case parent is csb
if (parentEntity.getResourceType().intValue() == ResourceType.CSE_BASE) {
CSEBaseEntity csb = (CSEBaseEntity) parentEntity;
childNodes = csb.getChildAnncNodes();
acpsToCheck = csb.getAccessControlPolicies();
subscriptions = csb.getSubscriptions();
}
// case parent is csr
if (parentEntity.getResourceType().intValue() == ResourceType.REMOTE_CSE) {
RemoteCSEEntity remoteCse = (RemoteCSEEntity) parentEntity;
childNodes = remoteCse.getChildAnncNodes();
acpsToCheck = remoteCse.getAccessControlPolicies();
subscriptions = remoteCse.getSubscriptions();
}
// check access control policy of the originator
checkACP(acpsToCheck, request.getFrom(), Operation.CREATE);
// check if content is present
if (request.getContent() == null) {
throw new BadRequestException("A content is required for Container creation");
}
// get the object from the representation
NodeAnnc node = null;
try {
if (request.getRequestContentType().equals(MimeMediaType.OBJ)) {
node = (NodeAnnc) request.getContent();
} else {
node = (NodeAnnc)DataMapperSelector.getDataMapperList()
.get(request.getRequestContentType()).stringToObj((String)request.getContent());
}
} catch (ClassCastException e) {
throw new BadRequestException("Incorrect resource representation in content", e);
}
if (node == null) {
throw new BadRequestException("Error in provided content");
}
NodeAnncEntity nodeEntity = new NodeAnncEntity();
// check attributes
ControllerUtil.CreateUtil.fillEntityFromGenericResource(node, nodeEntity);
if (node.getLink() == null) {
throw new BadRequestException("Link is Mandatory");
} else {
nodeEntity.setLink(node.getLink());
}
/*
* nodeID M
* hostedCSELink O
*/
if (node.getNodeID() == null) {
throw new BadRequestException("Node ID is Mandatory");
} else {
nodeEntity.setNodeID(node.getNodeID());
}
if (node.getHostedCSELink() != null) {
nodeEntity.setHostedCSELink(node.getHostedCSELink());
}
if (node.getHostedServiceLinks() != null) {
nodeEntity.setHostedServiceLinks(node.getHostedServiceLinks());
}
String generatedId = generateId();
// Set other parameters
nodeEntity.setResourceID("/" + Constants.CSE_ID + "/" +
ShortName.NODE_ANNC + Constants.PREFIX_SEPERATOR + generatedId);
nodeEntity.setCreationTime(DateUtil.now());
nodeEntity.setLastModifiedTime(DateUtil.now());
nodeEntity.setParentID(parentEntity.getResourceID());
nodeEntity.setResourceType(ResourceType.NODE_ANNC);
if (parentEntity.getResourceType().intValue() == ResourceType.CSE_BASE) {
nodeEntity.setParentCsb((CSEBaseEntity) parentEntity);
} else if (parentEntity.getResourceType().intValue() == ResourceType.REMOTE_CSE) {
nodeEntity.setParentCsr((RemoteCSEEntity) parentEntity);
}
if (dbs.getDAOFactory().getNodeAnncDAO().find(transaction, nodeEntity.getResourceID()) != null) {
throw new ConflictException("Already registered");
}
if (node.getName() != null) {
if (!patterns.checkResourceName(node.getName())) {
throw new BadRequestException("Name provided is incorrect. Must be:" + patterns.ID_STRING);
}
nodeEntity.setName(node.getName());
} else {
nodeEntity.setName(ShortName.NODE_ANNC + "_" + generatedId);
}
nodeEntity.setHierarchicalURI(parentEntity.getHierarchicalURI() + "/" + nodeEntity.getName());
// set acps
if (!node.getAccessControlPolicyIDs().isEmpty()) {
nodeEntity.setAccessControlPolicies(ControllerUtil.buildAcpEntityList(node.getAccessControlPolicyIDs(), transaction));
} else {
nodeEntity.getAccessControlPolicies().addAll(acpsToCheck);
}
// dynamicAuthorizationConsultationIDs O
if (!node.getDynamicAuthorizationConsultationIDs().isEmpty()) {
nodeEntity.setDynamicAuthorizationConsultations(
ControllerUtil.buildDacEntityList(node.getDynamicAuthorizationConsultationIDs(), transaction));
}
// storing the hierarchical uri
if (!UriMapper.addNewUri(nodeEntity.getHierarchicalURI(), nodeEntity.getResourceID(), ResourceType.NODE_ANNC)) {
throw new ConflictException("Name already present in the parent collection.");
}
// persisting data
dbs.getDAOFactory().getNodeAnncDAO().create(transaction, nodeEntity);
// get the managed object
NodeAnncEntity nodeDB = dbs.getDAOFactory().getNodeAnncDAO().find(transaction, nodeEntity.getResourceID());
// Add the AE to the parentEntity list
childNodes.add(nodeDB);
dao.update(transaction, parentEntity);
transaction.commit();
Notifier.notify(subscriptions, nodeDB, ResourceStatus.CHILD_CREATED);
response.setResponseStatusCode(ResponseStatusCode.CREATED);
setLocationAndCreationContent(request, response, nodeDB);
return response;
}
@Override
public ResponsePrimitive doRetrieve(RequestPrimitive request) {
// create the response primitive
ResponsePrimitive response = new ResponsePrimitive(request);
// get the entity
NodeAnncEntity nodeEntity = dbs.getDAOFactory().getNodeAnncDAO().find(transaction,
request.getTo());
if (nodeEntity == null) {
throw new ResourceNotFoundException();
}
// check authorization
List<AccessControlPolicyEntity> acps = nodeEntity.getAccessControlPolicies();
checkACP(acps, request.getFrom(), request.getOperation());
response = new ResponsePrimitive(request);
// map the entity with the representation resource
NodeAnnc node = EntityMapperFactory.getNodeAnncMapper().mapEntityToResource(nodeEntity, request);
response.setContent(node);
// set status code
response.setResponseStatusCode(ResponseStatusCode.OK);
// return the response
return response;
}
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
// create the response base
ResponsePrimitive response = new ResponsePrimitive(request);
// retrieve the resource from database
NodeAnncEntity nodeEntity = dbs.getDAOFactory().getNodeAnncDAO().find(transaction, request.getTo());
if (nodeEntity == null) {
throw new ResourceNotFoundException();
}
// check ACP
checkACP(nodeEntity.getAccessControlPolicies(), request.getFrom(), Operation.UPDATE);
// check if content is present
if (request.getContent() == null) {
throw new BadRequestException("A content is required for node update");
}
// create the java object from the resource representation
// get the object from the representation
NodeAnnc node = null;
try{
if (request.getRequestContentType().equals(MimeMediaType.OBJ)) {
node = (NodeAnnc) request.getContent();
} else {
node = (NodeAnnc)DataMapperSelector.getDataMapperList()
.get(request.getRequestContentType()).stringToObj((String)request.getContent());
}
} catch (ClassCastException e) {
throw new BadRequestException("Incorrect resource representation in content", e);
}
if (node == null) {
throw new BadRequestException("Error in provided content");
}
// check attributes, NP attributes are ignored
// @resourceName NP
// resourceType NP
// resourceID NP
// parentID NP
// creationTime NP
// creator NP
// lastModifiedTime NP
UpdateUtil.checkNotPermittedParameters(node);
// hostedCseLink NP
if (node.getHostedCSELink() != null) {
throw new BadRequestException("HostedCSELink is NP");
}
NodeAnnc modifiedAttributes = new NodeAnnc();
// labels O
if (!node.getLabels().isEmpty()) {
nodeEntity.setLabelsEntitiesFromSring(node.getLabels());
modifiedAttributes.getLabels().addAll(node.getLabels());
}
// accessControlPolicyIDs O
if (!node.getAccessControlPolicyIDs().isEmpty()) {
for(AccessControlPolicyEntity acpe : nodeEntity.getAccessControlPolicies()) {
checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
}
nodeEntity.getAccessControlPolicies().clear();
nodeEntity.setAccessControlPolicies(ControllerUtil.buildAcpEntityList(node.getAccessControlPolicyIDs(), transaction));
modifiedAttributes.getAccessControlPolicyIDs().addAll(node.getAccessControlPolicyIDs());
}
// expirationTime O
if (node.getExpirationTime() != null) {
nodeEntity.setExpirationTime(node.getExpirationTime());
modifiedAttributes.setExpirationTime(node.getExpirationTime());
}
// nodeID O
if (node.getNodeID() != null) {
nodeEntity.setNodeID(node.getNodeID());
modifiedAttributes.setNodeID(node.getNodeID());
}
nodeEntity.setLastModifiedTime(DateUtil.now());
modifiedAttributes.setLastModifiedTime(nodeEntity.getLastModifiedTime());
response.setContent(modifiedAttributes);
// uptade the persisted resource
dbs.getDAOFactory().getNodeAnncDAO().update(transaction, nodeEntity);
// commit & close the db transaction
transaction.commit();
Notifier.notify(nodeEntity.getChildSubscriptions(), nodeEntity, ResourceStatus.UPDATED);
// set response status code
response.setResponseStatusCode(ResponseStatusCode.UPDATED);
return response;
}
@Override
public ResponsePrimitive doDelete(RequestPrimitive request) {
// Generic delete procedure
ResponsePrimitive response = new ResponsePrimitive(request);
// retrieve the entity
NodeAnncEntity nodeEntity = dbs.getDAOFactory().getNodeAnncDAO().find(transaction, request.getTo());
if (nodeEntity == null) {
throw new ResourceNotFoundException();
}
// check access control policies
checkACP(nodeEntity.getAccessControlPolicies(), request.getFrom(), Operation.DELETE);
UriMapper.deleteUri(nodeEntity.getHierarchicalURI());
Notifier.notifyDeletion(nodeEntity.getChildSubscriptions(), nodeEntity);
// delete the resource in the database
dbs.getDAOFactory().getNodeAnncDAO().delete(transaction, nodeEntity);
// commit the transaction
transaction.commit();
// return the response
response.setResponseStatusCode(ResponseStatusCode.DELETED);
return response;
}
}