blob: 50173a11565fa645b6e71bf824f86d29ab1bc417 [file] [log] [blame]
/*******************************************************************************
* 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
* François Aïssaoui : Developer
*
* New contributors :
*******************************************************************************/
package org.eclipse.om2m.core.controller;
import java.util.ArrayList;
import java.util.List;
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.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.AeEntity;
import org.eclipse.om2m.commons.entities.CSEBaseEntity;
import org.eclipse.om2m.commons.entities.ContainerEntity;
import org.eclipse.om2m.commons.entities.GroupEntity;
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.NotImplementedException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
import org.eclipse.om2m.commons.resource.Subscription;
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.persistence.PersistenceService;
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.CreateUtil;
import org.eclipse.om2m.core.util.ControllerUtil.UpdateUtil;
import org.eclipse.om2m.persistence.service.DAO;
import org.eclipse.om2m.persistence.service.DBService;
import org.eclipse.om2m.persistence.service.DBTransaction;
/**
* Controller for Subscription
*
*/
public class SubscriptionController extends Controller{
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
ResponsePrimitive response = new ResponsePrimitive(request);
// Get the DAO of the parent
DAO<?> dao = (DAO<?>) Patterns.getDAO(request.getTargetId(), dbs);
if (dao == null){
throw new ResourceNotFoundException("Cannot find parent resource");
}
// Get the parent entity
ResourceEntity parentEntity = (ResourceEntity) dao.find(transaction, request.getTargetId());
// Check the parent existence
if (parentEntity == null){
throw new ResourceNotFoundException("Cannot find parent resource");
}
// Get lists to change in the method corresponding to specific object
List<AccessControlPolicyEntity> acpsToCheck = null;
// Distinguish parents
// Case of CSEBase
if(parentEntity.getResourceType().intValue() == (ResourceType.CSE_BASE)){
CSEBaseEntity cseBase = (CSEBaseEntity) parentEntity;
acpsToCheck = cseBase.getAccessControlPolicies();
}
if(parentEntity.getResourceType().intValue() == (ResourceType.AE)){
AeEntity ae = (AeEntity) parentEntity;
acpsToCheck = ae.getAccessControlPolicies();
}
if(parentEntity.getResourceType().intValue() == (ResourceType.REMOTE_CSE)){
RemoteCSEEntity remoteCSE = (RemoteCSEEntity) parentEntity;
acpsToCheck = remoteCSE.getAccessControlPolicies();
}
if(parentEntity.getResourceType().intValue() == (ResourceType.GROUP)){
GroupEntity group = (GroupEntity) parentEntity;
acpsToCheck = group.getAccessControlPolicies();
}
if(parentEntity.getResourceType().intValue() == (ResourceType.CONTAINER)){
ContainerEntity container = (ContainerEntity) parentEntity;
acpsToCheck = container.getAccessControlPolicies();
}
if(parentEntity.getResourceType().intValue() == (ResourceType.ACCESS_CONTROL_POLICY)){
AccessControlPolicyEntity acp = (AccessControlPolicyEntity) parentEntity;
acpsToCheck = new ArrayList<>();
acpsToCheck.add(acp); // TODO check the acp to check in case of acp parent for subs
}
if(parentEntity.getResourceType().intValue() == ResourceType.REMOTE_CSE){
RemoteCSEEntity csr = (RemoteCSEEntity) parentEntity;
acpsToCheck = csr.getAccessControlPolicies();
}
if(acpsToCheck == null){
throw new NotImplementedException("Subscription is not yet supported on this resource");
}
// Check access control policy of the originator
checkACP(acpsToCheck, request.getFrom(), Operation.RETRIEVE);
// Check if content is present
if (request.getContent() == null){
throw new BadRequestException("A content is requiered for Subscription creation");
}
Subscription subscription = null;
try {
if(request.getRequestContentType().equals(MimeMediaType.OBJ)){
subscription = (Subscription) request.getContent();
} else {
subscription = (Subscription) DataMapperSelector.getDataMapperList().
get(request.getRequestContentType()).stringToObj((String)request.getContent());
}
} catch (ClassCastException e){
throw new BadRequestException("Incorrect resource representation in content", e);
}
if(subscription == null){
throw new BadRequestException("Error in provided content");
}
// Check attributes
// @resourceName NP
// resourceType NP
// resourceID NP
// parentID NP
// creationTime NP
// lastModifiedTime NP
// labels O
SubscriptionEntity subscriptionEntity = new SubscriptionEntity();
CreateUtil.fillEntityFromGenericResource(subscription, subscriptionEntity);
// notificationUri M
if(subscription.getNotificationURI().isEmpty()){
throw new BadRequestException("Notification URI is mandatory");
} else {
subscriptionEntity.getNotificationURI().addAll(subscription.getNotificationURI());
}
// expirationTime O
if(subscription.getExpirationTime() != null){
subscriptionEntity.setExpirationTime(subscription.getExpirationTime());
}
// eventNotificationCriteria O
if(subscription.getEventNotificationCriteria() != null){
// TODO Subscription EventNotoficationCriteria handling
}
// expirationCounter O
if(subscription.getExpirationCounter() != null){
subscriptionEntity.setExpirationCounter(subscription.getExpirationCounter());
}
// groupID O
if(subscription.getGroupID() != null){
subscriptionEntity.setGroupID(subscription.getGroupID());
}
// notificationForwardingUri O
if(subscription.getNotificationForwardingURI() != null){
}
// batchNotify O
if(subscription.getBatchNotify() != null){
// TODO BatchNotify
}
// rateLimit O
if(subscription.getRateLimit() != null){
// TODO RateLimit
}
// preSubscriptionNotification O
if(subscription.getPreSubscriptionNotify() != null){
subscriptionEntity.setPreSubscriptionNotify(
subscription.getPreSubscriptionNotify());
}
// pendingNotification O
if(subscription.getPendingNotification() != null){
subscriptionEntity.setPendingNotification(subscription.getPendingNotification());
}
// notificationStoragePriority O
if(subscription.getNotificationStoragePriority() != null){
subscriptionEntity.setNotificationStoragePriority(
subscription.getNotificationStoragePriority());
}
// latestNotify O
if(subscription.isLatestNotify() != null){
subscriptionEntity.setLatestNotify(subscription.isLatestNotify());
}
// notificationContentType O
if(subscription.getNotificationContentType() != null){
subscriptionEntity.setNotificationContentType(
subscription.getNotificationContentType());
}
// notificationEventCat O
if(subscription.getNotificationEventCat() != null){
subscriptionEntity.setNotificationEventCat(
subscription.getNotificationEventCat());
}
// creator O
if(subscription.getCreator() != null){
subscriptionEntity.setCreator(subscription.getCreator());
}
// subscriberURI O
if(subscription.getSubscriberURI() != null){
subscriptionEntity.setSubscriberURI(subscription.getSubscriberURI());
}
if(!subscription.getAccessControlPolicyIDs().isEmpty()){
subscriptionEntity.setAcpList(
ControllerUtil.buildAcpEntityList(subscription.getAccessControlPolicyIDs(), transaction));
} else {
subscriptionEntity.getAcpList().addAll(acpsToCheck);
}
String generatedId = generateId();
subscriptionEntity.setResourceID("/" + Constants.CSE_ID + "/" + ShortName.SUB + Constants.PREFIX_SEPERATOR + generatedId);
subscriptionEntity.setCreationTime(DateUtil.now());
subscriptionEntity.setLastModifiedTime(DateUtil.now());
subscriptionEntity.setParentID(parentEntity.getResourceID());
subscriptionEntity.setResourceType(ResourceType.SUBSCRIPTION);
if (subscription.getName() != null){
if (!Patterns.checkResourceName(subscription.getName())){
throw new BadRequestException("Name provided is incorrect. Must be:" + Patterns.ID_STRING);
}
subscriptionEntity.setName(subscription.getName());
} else
if(request.getName() != null){
if(!Patterns.checkResourceName(request.getName())){
throw new BadRequestException("Name provided is incorrect. Must be:" + Patterns.ID_STRING);
}
subscriptionEntity.setName(request.getName());
} else {
subscriptionEntity.setName(ShortName.SUB + "_" + generatedId);
}
Notifier.performVerificationRequest(request, subscriptionEntity);
subscriptionEntity.setHierarchicalURI(parentEntity.getHierarchicalURI() + "/" + subscriptionEntity.getName());
if(!UriMapper.addNewUri(subscriptionEntity.getHierarchicalURI(), subscriptionEntity.getResourceID(), ResourceType.SUBSCRIPTION)){
throw new ConflictException("Name already present in the parent collection.");
}
subscriptionEntity.setParentEntity(parentEntity);
dbs.getDAOFactory().getSubsciptionDAO().create(transaction, subscriptionEntity);
transaction.commit();
response.setResponseStatusCode(ResponseStatusCode.CREATED);
setLocationAndCreationContent(request, response, subscriptionEntity);
return response;
}
@Override
public ResponsePrimitive doRetrieve(RequestPrimitive request) {
ResponsePrimitive response = new ResponsePrimitive(request);
SubscriptionEntity subscriptionEntity = dbs.getDAOFactory()
.getSubsciptionDAO().find(transaction, request.getTargetId());
if (subscriptionEntity == null){
throw new ResourceNotFoundException();
}
checkACP(subscriptionEntity.getAcpList(), request.getFrom(),
Operation.RETRIEVE);
// Create the object used to create the representation of the resource
Subscription subscription = EntityMapperFactory.getSubscriptionMapper().mapEntityToResource(subscriptionEntity, request);
response.setContent(subscription);
response.setResponseStatusCode(ResponseStatusCode.OK);
return response;
}
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
ResponsePrimitive response = new ResponsePrimitive(request);
DBService dbs = PersistenceService.getInstance().getDbService();
DBTransaction transaction = dbs.getDbTransaction();
transaction.open();
SubscriptionEntity subscriptionEntity = dbs.getDAOFactory()
.getSubsciptionDAO().find(transaction, request.getTargetId());
if (subscriptionEntity == null){
throw new ResourceNotFoundException();
}
checkACP(subscriptionEntity.getAcpList(), request.getFrom(),
Operation.UPDATE);
// Check if content is present
if (request.getContent() == null){
throw new BadRequestException("A content is requiered for Subscription update");
}
Subscription subscription = null;
try {
if(request.getRequestContentType().equals(MimeMediaType.OBJ)){
subscription = (Subscription) request.getContent();
} else {
subscription = (Subscription) DataMapperSelector.getDataMapperList().
get(request.getRequestContentType()).stringToObj((String)request.getContent());
}
} catch (ClassCastException e){
throw new BadRequestException("Incorrect resource representation in content", e);
}
if(subscription == null){
throw new BadRequestException("Error in provided content");
}
// Check attributes
// NP Attributes are ignored
// resourceName NP
// resourceType NP
// resourceID NP
// parentID NP
// creationTime NP
// lastTimeModified NP
UpdateUtil.checkNotPermittedParameters(subscription);
// preSubscriptionNotify NP
if(subscription.getPreSubscriptionNotify() != null){
throw new BadRequestException("PreSubscriptionNotify is NP");
}
// subscriberURI NP
if(subscription.getSubscriberURI() != null){
throw new BadRequestException("SubscripberURI is NP");
}
Subscription modifiedAttributes = new Subscription();
// ACPIDs O
if(!subscription.getAccessControlPolicyIDs().isEmpty()){
for(AccessControlPolicyEntity acpe : subscriptionEntity.getAcpList()){
checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
}
subscriptionEntity.getAcpList().clear();
subscriptionEntity.setAcpList(ControllerUtil.buildAcpEntityList(subscription.getAccessControlPolicyIDs(), transaction));
modifiedAttributes.getAccessControlPolicyIDs().addAll(subscription.getAccessControlPolicyIDs());
}
// expirationTime O
if(subscription.getExpirationTime() != null){
subscriptionEntity.setExpirationTime(subscription.getExpirationTime());
modifiedAttributes.setExpirationTime(subscription.getExpirationTime());
}
// labels O
if(!subscription.getLabels().isEmpty()){
subscriptionEntity.getLabelsEntities().clear();
subscriptionEntity.setLabelsEntitiesFromSring(subscription.getLabels());
modifiedAttributes.getLabels().addAll(subscription.getLabels());
}
// eventNotificationCriteria O
if(subscription.getEventNotificationCriteria() != null){
// TODO eventNotificationCriteria
}
// expirationCounter O
if(subscription.getExpirationCounter() != null){
subscriptionEntity.setExpirationCounter(subscription.getExpirationCounter());
modifiedAttributes.setExpirationCounter(subscription.getExpirationCounter());
}
// notificationUri O
if(!subscription.getNotificationURI().isEmpty()){
subscriptionEntity.getNotificationURI().clear();
subscriptionEntity.getNotificationURI().addAll(subscription.getNotificationURI());
modifiedAttributes.getNotificationURI().addAll(subscription.getNotificationURI());
}
// groupID O
if(subscription.getGroupID() != null){
subscriptionEntity.setGroupID(subscription.getGroupID());
modifiedAttributes.setGroupID(subscription.getGroupID());
}
// notificationForwardingUri O
if(subscription.getNotificationForwardingURI() != null){
subscriptionEntity.setNotificationForwardingURI(subscription.getNotificationForwardingURI());
modifiedAttributes.setNotificationForwardingURI(subscription.getNotificationForwardingURI());
}
// batchNotify O
if(subscription.getBatchNotify() != null){
// TODO batch notify
}
// rateLimit O
if(subscription.getRateLimit() != null){
// TODO rate limit
}
// pendingNotification O
if(subscription.getPendingNotification() != null){
subscriptionEntity.setPendingNotification(subscription.getPendingNotification());
modifiedAttributes.setPendingNotification(subscription.getPendingNotification());
}
// notificationStorePriority O
if(subscription.getNotificationStoragePriority() != null){
subscriptionEntity.setNotificationStoragePriority(subscription.getNotificationStoragePriority());
modifiedAttributes.setNotificationStoragePriority(subscription.getNotificationStoragePriority());
}
// latestNotify O
if(subscription.isLatestNotify() != null){
subscriptionEntity.setLatestNotify(subscription.isLatestNotify());
modifiedAttributes.setLatestNotify(subscription.isLatestNotify());
}
// notificationContentType O
if(subscription.getNotificationContentType() != null){
subscriptionEntity.setNotificationContentType(subscription.getNotificationContentType());
modifiedAttributes.setNotificationContentType(subscription.getNotificationContentType());
}
// notificationEventCat O
if(subscription.getNotificationEventCat() != null){
subscriptionEntity.setNotificationEventCat(subscription.getNotificationEventCat());
modifiedAttributes.setNotificationEventCat(subscription.getNotificationEventCat());
}
// creator O
if(subscription.getCreator() != null){
subscriptionEntity.setCreator(subscription.getCreator());
modifiedAttributes.setCreator(subscription.getCreator());
}
// Update last time modified
subscriptionEntity.setLastModifiedTime(DateUtil.now());
modifiedAttributes.setLastModifiedTime(subscriptionEntity.getLastModifiedTime());
response.setContent(modifiedAttributes);
dbs.getDAOFactory().getSubsciptionDAO().update(transaction, subscriptionEntity);
transaction.commit();
response.setResponseStatusCode(ResponseStatusCode.UPDATED);
return response;
}
@Override
public ResponsePrimitive doDelete(RequestPrimitive request) {
ResponsePrimitive response = new ResponsePrimitive(request);
// Get the database service
DBService dbs = PersistenceService.getInstance().getDbService();
DBTransaction transaction = dbs.getDbTransaction();
transaction.open();
SubscriptionEntity se = dbs.getDAOFactory()
.getSubsciptionDAO().find(transaction, request.getTargetId());
if (se == null){
throw new ResourceNotFoundException();
}
checkACP(se.getAcpList(), request.getFrom(),
Operation.DELETE);
// Delete the resource in UriMapper table
UriMapper.deleteUri(se.getHierarchicalURI());
// Delete the resource
dbs.getDAOFactory().getSubsciptionDAO().delete(transaction, se);
transaction.commit();
response.setResponseStatusCode(ResponseStatusCode.DELETED);
return response;
}
}