Enhance the core module
[Bug 494090] add wildcard for acp
Update thread handling and policy
Update initialization phase
Reject NP attributes on Update request
Fix some label update
Signed-off-by: Francois Aissaoui <aissaoui@laas.fr>
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/Activator.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/Activator.java
index 0668361..20283c3 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/Activator.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/Activator.java
@@ -30,9 +30,9 @@
import org.eclipse.om2m.core.persistence.PersistenceService;
import org.eclipse.om2m.core.router.Router;
import org.eclipse.om2m.core.service.CseService;
+import org.eclipse.om2m.core.thread.CoreExecutor;
import org.eclipse.om2m.datamapping.service.DataMapperService;
import org.eclipse.om2m.interworking.service.InterworkingService;
-import org.eclipse.om2m.persistence.service.DBConstants;
import org.eclipse.om2m.persistence.service.DBService;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -64,9 +64,8 @@
@Override
public Object addingService(ServiceReference<Object> reference) {
- LOGGER.info("DataMapper Service discovered");
DataMapperService dataMapper = (DataMapperService) this.context.getService(reference);
- LOGGER.info("Add Data Mapper Service: " + dataMapper.getServiceDataType());
+ LOGGER.info("Added Data Mapper Service: " + dataMapper.getServiceDataType());
DataMapperSelector.getDataMapperList().put(dataMapper.getServiceDataType(), dataMapper);
return dataMapper;
}
@@ -74,9 +73,8 @@
@Override
public void removedService(ServiceReference<Object> reference,
Object service) {
- LOGGER.info("DataMapper Service removed");
DataMapperService dataMapper = (DataMapperService) service;
- LOGGER.info("Remove Data Mapper Service: " + dataMapper.getServiceDataType());
+ LOGGER.info("Removed Data Mapper Service: " + dataMapper.getServiceDataType());
DataMapperSelector.getDataMapperList().remove(dataMapper.getServiceDataType());
}
@@ -91,7 +89,22 @@
LOGGER.info("DataBase persistence service discovered");
DBService dbService = (DBService) this.context.getService(reference);
PersistenceService.getInstance().setDbService(dbService);
- PersistenceService.getInstance().getDbReady().release();
+
+ // Post the start routine in the CoreExecutor
+ CoreExecutor.postThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ CSEInitializer.init();
+ } catch (InterruptedException e) {
+ LOGGER.error("Error in CSEInitializer", e);
+ }
+ LOGGER.info("Registering CseService...");
+ context.registerService(CseService.class.getName(), new Router(), null);
+ LOGGER.info("CSE Started");
+ }
+ });
+
return dbService;
}
@@ -100,7 +113,6 @@
Object service) {
LOGGER.info("Database persistence service removed.");
PersistenceService.getInstance().setDbService(null);
- PersistenceService.getInstance().resetSemaphoreDb();
}
};
@@ -110,9 +122,9 @@
restClientServiceTracker = new ServiceTracker<Object,Object>(bundleContext, RestClientService.class.getName(), null){
public Object addingService(org.osgi.framework.ServiceReference<Object> reference) {
- LOGGER.info("Rest client service discovered");
RestClientService service = (RestClientService) this.context.getService(reference);
RestClient.getRestClients().put(service.getProtocol(), service);
+ LOGGER.info("Rest client service discovered. Protocol: " + service.getProtocol());
return service;
};
@@ -145,15 +157,7 @@
};
ipeServiceTracker.open();
-
- if (DBConstants.DB_RESET) {
- CSEInitializer.init();
- }
- LOGGER.info("Registering CseService...");
- bundleContext.registerService(CseService.class.getName(), new Router(), null);
-
- LOGGER.info("CSE Started");
}
public void stop(BundleContext bundleContext) throws Exception {
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/CSEInitializer.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/CSEInitializer.java
index 94b55cd..67fc229 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/CSEInitializer.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/CSEInitializer.java
@@ -70,29 +70,36 @@
* Initialize the current launching CSE.
*/
public static void init() throws InterruptedException{
- LOGGER.info("Waiting for the database service");
- PersistenceService.getInstance().getDbReady().acquire();
+ LOGGER.info("Initializating the cseBase");
+ // Check the existence of the cseBase in the database
+ DBService dbs = PersistenceService.getInstance().getDbService();
+ DBTransaction transaction = dbs.getDbTransaction();
+ transaction.open();
+ CSEBaseEntity cseBase = dbs.getDAOFactory().getCSEBaseDAO().find(transaction, "/" + Constants.CSE_ID);
+ // if the cseBase is not initialized, then create the base resources
+ if(cseBase == null){
+ // Create AccessRight resource
+ LOGGER.info("Create AccessControlPolicy resource");
+ initACP();
+
+ // Create CSEBase resource
+ LOGGER.info("Create CSEBase resource");
+ initCSEBase();
- // Create AccessRight resource
- LOGGER.info("Create AccessControlPolicy resource");
- initACP();
-
- // Create CSEBase resource
- LOGGER.info("Create CSEBase resource");
- initCSEBase();
-
- if(!Constants.CSE_TYPE.equalsIgnoreCase(CSEType.IN) && Constants.CSE_AUTHENTICATION){
- LOGGER.info("Register CSE to another CSE.");
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- registerCSE();
- }
- }).start();
+ if(!Constants.CSE_TYPE.equalsIgnoreCase(CSEType.IN) && Constants.CSE_AUTHENTICATION){
+ LOGGER.info("Register CSE to another CSE.");
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ registerCSE();
+ }
+ }).start();
+ }
+ } else {
+ LOGGER.info("cseBase already initialized");
}
- PersistenceService.getInstance().getDbReady().release();
}
/**
@@ -170,7 +177,8 @@
remoteCSE.setCSEID("/" + Constants.CSE_ID);
remoteCSE.setCSEBase("//" + Constants.M2M_SP_ID + remoteCSE.getCSEID());
remoteCSE.setRequestReachability(new Boolean(true));
-
+ remoteCSE.setName(Constants.CSE_ID);
+
String representation = DataMapperSelector.getDataMapperList().get(contentFormat).objToString(remoteCSE);
RequestPrimitive request = new RequestPrimitive();
@@ -182,7 +190,6 @@
remotePoa += Constants.REMOTE_CSE_ID;
request.setTo(remotePoa);
request.setContent(representation);
- request.setName(Constants.CSE_ID);
request.setOperation(Operation.CREATE);
request.setResourceType(BigInteger.valueOf(ResourceType.REMOTE_CSE));
request.setRequestContentType(contentFormat);
@@ -278,6 +285,7 @@
ruleEntity.setNotify(true);
ruleEntity.setDiscovery(true);
ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity(Constants.ADMIN_REQUESTING_ENTITY));
+ ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity("/" + Constants.CSE_ID));
acp.getPrivileges().add(ruleEntity);
// privileges for ALL originators (read + discovery)
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/comm/RestClient.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/comm/RestClient.java
index 6d5a24e..1b84b6a 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/comm/RestClient.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/comm/RestClient.java
@@ -25,7 +25,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.binding.service.RestClientService;
-import org.eclipse.om2m.commons.constants.ResponseStatusCode;
+import org.eclipse.om2m.commons.exceptions.InternalServerErrorException;
+import org.eclipse.om2m.commons.exceptions.NotImplementedException;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
@@ -63,17 +64,14 @@
}
}catch(Exception e){
LOGGER.error("RestClient error",e);
- response.setResponseStatusCode(ResponseStatusCode.INTERNAL_SERVER_ERROR);
- response.setErrorMessage("RestClient error");
+ throw new InternalServerErrorException("RestClient Error", e);
}
}else{
- response.setResponseStatusCode(ResponseStatusCode.NOT_IMPLEMENTED);
- response.setErrorMessage("No RestClient service found for protocol: " + protocol);
+ throw new NotImplementedException("No RestClient service found for protocol: " + protocol);
}
LOGGER.info(response);
return response;
-
}
/**
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AEController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AEController.java
index b156a9c..813dfe1 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AEController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AEController.java
@@ -52,6 +52,7 @@
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;
/**
@@ -129,17 +130,14 @@
if (request.getFrom() != null){
if (request.getFrom().startsWith("S")) {
- response.setResponseStatusCode(ResponseStatusCode.NOT_IMPLEMENTED);
- response.setErrorMessage("originator starting with S not implemented yet");
- transaction.close();
- return response;
+ throw new NotImplementedException("originator starting with S not implemented yet");
} else if (request.getFrom().startsWith("C")) {
assignAeiC = false;
- } else {
+ } else if(!request.getFrom().equals("")){
// Check access control policy of the originator
checkACP(acpsToCheck, request.getFrom(), Operation.CREATE);
}
- }
+ }
// Check if content is present
if (request.getContent() == null){
@@ -183,7 +181,7 @@
}
// nodeLink NP
if (ae.getNodeLink() != null){
- throw new NotPermittedAttrException("NodeLink is Not Permitted");
+ aeEntity.setNodeLink(ae.getNodeLink());
}
// app-ID M
@@ -208,60 +206,62 @@
aeEntity.setAeid(request.getFrom());
}
// Set other parameters
- aeEntity.setResourceID("/" + Constants.CSE_ID + "/" + ShortName.AE + Constants.PREFIX_SEPERATOR + aeEntity.getAeid());
+ aeEntity.setResourceID("/" + Constants.CSE_ID + "/" + aeEntity.getAeid());
if (dbs.getDAOFactory().getAeDAO().find(transaction, aeEntity.getResourceID()) != null) {
- transaction.close();
- response.setResponseStatusCode(ResponseStatusCode.CONFLICT);
- response.setErrorMessage("Already registered");
- return response;
+ throw new ConflictException("Already registered");
}
// accessControlPolicyIDs O
if (!ae.getAccessControlPolicyIDs().isEmpty()){
aeEntity.setAccessControlPolicies(
ControllerUtil.buildAcpEntityList(ae.getAccessControlPolicyIDs(), transaction));
- } else {
- AccessControlPolicyEntity acpEntity = new AccessControlPolicyEntity();
- acpEntity.setCreationTime(DateUtil.now());
- acpEntity.setLastModifiedTime(DateUtil.now());
- acpEntity.setParentID("/" + Constants.CSE_ID);
- acpEntity.setResourceID("/" + Constants.CSE_ID + "/" + ShortName.ACP + Constants.PREFIX_SEPERATOR + generateId());
- acpEntity.setName(ShortName.ACP + ShortName.AE + Constants.PREFIX_SEPERATOR + generatedId);
- AccessControlRuleEntity ruleEntity = new AccessControlRuleEntity();
- AccessControlOriginatorEntity originatorEntity = new AccessControlOriginatorEntity(Constants.ADMIN_REQUESTING_ENTITY);
- ruleEntity.getAccessControlOriginators().add(originatorEntity);
- ruleEntity.setCreate(true);
- ruleEntity.setRetrieve(true);
- ruleEntity.setUpdate(true);
- ruleEntity.setDelete(true);
- ruleEntity.setNotify(true);
- ruleEntity.setDiscovery(true);
- acpEntity.getSelfPrivileges().add(ruleEntity);
- // Privileges
- ruleEntity = new AccessControlRuleEntity();
- ruleEntity.setCreate(true);
- ruleEntity.setRetrieve(true);
- ruleEntity.setUpdate(true);
- ruleEntity.setDelete(true);
- ruleEntity.setNotify(true);
- ruleEntity.setDiscovery(true);
- ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity(aeEntity.getAeid()));
- ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity(Constants.ADMIN_REQUESTING_ENTITY));
- acpEntity.getPrivileges().add(ruleEntity);
- acpEntity.setHierarchicalURI("/" + Constants.CSE_ID + "/" + acpEntity.getName());
- UriMapper.addNewUri(acpEntity.getHierarchicalURI(), acpEntity.getResourceID(), ResourceType.ACCESS_CONTROL_POLICY);
- dbs.getDAOFactory().getAccessControlPolicyDAO().create(transaction, acpEntity);
-
- AccessControlPolicyEntity acpDB = dbs.getDAOFactory().getAccessControlPolicyDAO().find(transaction, acpEntity.getResourceID());
- CSEBaseEntity cseBase = dbs.getDAOFactory().getCSEBaseDAO().find(transaction, "/" + Constants.CSE_ID);
- cseBase.getChildAccessControlPolicies().add(acpDB);
- dbs.getDAOFactory().getCSEBaseDAO().update(transaction, cseBase);
- // adding new acp to the acp list
- aeEntity.getAccessControlPolicies().add(acpDB);
- // direct link to the generated acp
- aeEntity.setGeneratedAcp(acpDB);
}
+ // FIXME [0001] Creation of AE with an acpi provided
+ // } else {
+ // Create the acp corresponding to the AE_ID
+ AccessControlPolicyEntity acpEntity = new AccessControlPolicyEntity();
+ acpEntity.setCreationTime(DateUtil.now());
+ acpEntity.setLastModifiedTime(DateUtil.now());
+ acpEntity.setParentID("/" + Constants.CSE_ID);
+ acpEntity.setResourceID("/" + Constants.CSE_ID + "/" + ShortName.ACP + Constants.PREFIX_SEPERATOR + generateId());
+ acpEntity.setName(ShortName.ACP + ShortName.AE + Constants.PREFIX_SEPERATOR + generatedId);
+ AccessControlRuleEntity ruleEntity = new AccessControlRuleEntity();
+ AccessControlOriginatorEntity originatorEntity = new AccessControlOriginatorEntity(Constants.ADMIN_REQUESTING_ENTITY);
+ ruleEntity.getAccessControlOriginators().add(originatorEntity);
+ ruleEntity.setCreate(true);
+ ruleEntity.setRetrieve(true);
+ ruleEntity.setUpdate(true);
+ ruleEntity.setDelete(true);
+ ruleEntity.setNotify(true);
+ ruleEntity.setDiscovery(true);
+ acpEntity.getSelfPrivileges().add(ruleEntity);
+ // Privileges
+ ruleEntity = new AccessControlRuleEntity();
+ ruleEntity.setCreate(true);
+ ruleEntity.setRetrieve(true);
+ ruleEntity.setUpdate(true);
+ ruleEntity.setDelete(true);
+ ruleEntity.setNotify(true);
+ ruleEntity.setDiscovery(true);
+ ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity(aeEntity.getAeid()));
+ ruleEntity.getAccessControlOriginators().add(new AccessControlOriginatorEntity(Constants.ADMIN_REQUESTING_ENTITY));
+ acpEntity.getPrivileges().add(ruleEntity);
+ acpEntity.setHierarchicalURI("/" + Constants.CSE_ID + "/" + Constants.CSE_NAME + "/" + acpEntity.getName());
+ // Add the acp in the UriMapper table
+ UriMapper.addNewUri(acpEntity.getHierarchicalURI(), acpEntity.getResourceID(), ResourceType.ACCESS_CONTROL_POLICY);
+ dbs.getDAOFactory().getAccessControlPolicyDAO().create(transaction, acpEntity);
+ // Retrieve the acp in the database to make the link with the CSEBase resource
+ AccessControlPolicyEntity acpDB = dbs.getDAOFactory().getAccessControlPolicyDAO().find(transaction, acpEntity.getResourceID());
+ CSEBaseEntity cseBase = dbs.getDAOFactory().getCSEBaseDAO().find(transaction, "/" + Constants.CSE_ID);
+ cseBase.getChildAccessControlPolicies().add(acpDB);
+ dbs.getDAOFactory().getCSEBaseDAO().update(transaction, cseBase);
+ // adding new acp to the acp list
+ aeEntity.getAccessControlPolicies().add(acpDB);
+ // direct link to the generated acp
+ aeEntity.setGeneratedAcp(acpDB);
+ // }
+
// appName O
if (ae.getAppName() != null){
aeEntity.setAppName(ae.getAppName());
@@ -283,14 +283,14 @@
}
aeEntity.setName(ae.getName());
} else
- if (request.getName() != null){
- if (!Patterns.checkResourceName(request.getName())){
- throw new BadRequestException("Name provided is incorrect. Must be:" + Patterns.ID_STRING);
+ if (request.getName() != null){
+ if (!Patterns.checkResourceName(request.getName())){
+ throw new BadRequestException("Name provided is incorrect. Must be:" + Patterns.ID_STRING);
+ }
+ aeEntity.setName(request.getName());
+ } else {
+ aeEntity.setName(ShortName.AE + "_" + generatedId);
}
- aeEntity.setName(request.getName());
- } else {
- aeEntity.setName(ShortName.AE + "_" + generatedId);
- }
aeEntity.setHierarchicalURI(parentEntity.getHierarchicalURI() + "/" + aeEntity.getName());
if (!UriMapper.addNewUri(aeEntity.getHierarchicalURI(), aeEntity.getResourceID(), ResourceType.AE)){
throw new ConflictException("Name already present in the parent collection.");
@@ -411,14 +411,31 @@
// parentID NP
// creationTime NP
// lastModifiedTime NP
- // labels NP
+ UpdateUtil.checkNotPermittedParameters(ae);
// app-ID NP
+ if(ae.getAppID() != null){
+ throw new BadRequestException("AppID is NP");
+ }
// ae-ID NP
+ if(ae.getAEID() != null){
+ throw new BadRequestException("AE ID is NP");
+ }
// nodeLink NP
+ if(ae.getNodeLink() != null){
+ throw new BadRequestException("NodeLink is NP");
+ }
AE modifiedAttributes = new AE();
+ // labels O
+ if(!ae.getLabels().isEmpty()){
+ aeEntity.setLabelsEntitiesFromSring(ae.getLabels());
+ modifiedAttributes.getLabels().addAll(ae.getLabels());
+ }
// accessControlPolicyIDs O
if(!ae.getAccessControlPolicyIDs().isEmpty()){
+ for(AccessControlPolicyEntity acpe : aeEntity.getAccessControlPolicies()){
+ checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
+ }
aeEntity.getAccessControlPolicies().clear();
aeEntity.setAccessControlPolicies(ControllerUtil.buildAcpEntityList(ae.getAccessControlPolicyIDs(), transaction));
modifiedAttributes.getAccessControlPolicyIDs().addAll(ae.getAccessControlPolicyIDs());
@@ -462,7 +479,7 @@
aeEntity.setRequestReachability(ae.getRequestReachability());
modifiedAttributes.setRequestReachability(ae.getRequestReachability());
}
-
+
// Last Time Modified update
aeEntity.setLastModifiedTime(DateUtil.now());
modifiedAttributes.setLastModifiedTime(aeEntity.getLastModifiedTime());
@@ -496,7 +513,11 @@
Operation.DELETE);
UriMapper.deleteUri(aeEntity.getHierarchicalURI());
-
+
+ if(aeEntity.getGeneratedAcp() != null){
+ UriMapper.deleteUri(aeEntity.getGeneratedAcp().getHierarchicalURI());
+ }
+
Notifier.notifyDeletion(aeEntity.getSubscriptions(), aeEntity);
// Delete the resource
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AccessControlPolicyController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AccessControlPolicyController.java
index 7514fb0..8d4c252 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AccessControlPolicyController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/AccessControlPolicyController.java
@@ -50,6 +50,7 @@
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;
import org.eclipse.om2m.persistence.service.DBService;
import org.eclipse.om2m.persistence.service.DBTransaction;
@@ -311,14 +312,14 @@
AccessControlPolicy modifiedAttributes = new AccessControlPolicy();
- // NP attributes are ignored
+ // NP attributes
// @resourceName NP
// resourceType NP
// resourceID NP
// parentID NP
// creationTime NP
// lastModifiedTime NP
-
+ UpdateUtil.checkNotPermittedParameters(acp);
// expirationTime O
if(acp.getExpirationTime() != null){
acpEntity.setExpirationTime(acp.getExpirationTime());
@@ -388,6 +389,14 @@
if (acpEntity == null){
throw new ResourceNotFoundException("Resource not found");
}
+
+ // Check this acp is not a generated acp for an AE to avoid inconsistency
+ for(AeEntity ae : acpEntity.getLinkedAes()){
+ if(ae.getGeneratedAcp().getResourceID().equals(acpEntity.getResourceID())){
+ throw new BadRequestException("Delete the linked ae(s) to avoid acp inconsistency.");
+ }
+ }
+
// Check self access control policy
checkSelfACP(acpEntity, request.getFrom(), Operation.DELETE);
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/CSEBaseController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/CSEBaseController.java
index 913b0a7..2c69f73 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/CSEBaseController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/CSEBaseController.java
@@ -24,6 +24,7 @@
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.CSEBaseEntity;
+import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.CSEBase;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
@@ -39,9 +40,7 @@
// OPERATION_NOT_ALLOWED
@Override
public ResponsePrimitive doCreate(RequestPrimitive requestIndication) {
- ResponsePrimitive response = new ResponsePrimitive(requestIndication);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Create of CSEBase is not allowed");
}
// Generic retrieve operation
@@ -69,17 +68,13 @@
// OPERATION_NOT_ALLOWED
@Override
public ResponsePrimitive doUpdate(RequestPrimitive requestIndication) {
- ResponsePrimitive response = new ResponsePrimitive(requestIndication);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update of CSEBase is not allowed");
}
// OPERATION_NOT_ALLOWED
@Override
public ResponsePrimitive doDelete(RequestPrimitive requestIndication) {
- ResponsePrimitive response = new ResponsePrimitive(requestIndication);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Delete of CSEBase is not allowed");
}
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContainerController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContainerController.java
index d40df35..0d4b614 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContainerController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContainerController.java
@@ -19,6 +19,7 @@
*******************************************************************************/
package org.eclipse.om2m.core.controller;
+import java.math.BigInteger;
import java.util.List;
import org.eclipse.om2m.commons.constants.Constants;
@@ -49,6 +50,7 @@
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;
/**
@@ -232,19 +234,28 @@
// maxNrOfInstances O
if (container.getMaxNrOfInstances() != null) {
containerEntity.setMaxNrOfInstances(container.getMaxNrOfInstances());
+ } else {
+ containerEntity.setMaxNrOfInstances(Constants.MAX_NBR_OF_INSTANCES);
}
// maxByteSize O
if (container.getMaxByteSize() != null) {
containerEntity.setMaxByteSize(container.getMaxByteSize());
+ } else {
+ containerEntity.setMaxByteSize(Constants.MAX_BYTE_SIZE);
}
// maxInstanceAge O
if (container.getMaxInstanceAge() != null) {
containerEntity.setMaxInstanceAge(container.getMaxInstanceAge());
+ } else {
+ containerEntity.setMaxInstanceAge(BigInteger.valueOf(0));
}
// locationID O
if (container.getLocationID() != null) {
containerEntity.setLocationID(container.getLocationID());
}
+
+ // stateTag init
+ containerEntity.setStateTag(BigInteger.valueOf(0));
// create the container in the DB
dbs.getDAOFactory().getContainerDAO().create(transaction, containerEntity);
@@ -370,13 +381,22 @@
// creationTime NP
// creator NP
// lastModifiedTime NP
+ UpdateUtil.checkNotPermittedParameters(container);
// currentNrOfInstances NP
+ if(container.getCurrentNrOfInstances() != null){
+ throw new BadRequestException("CurrentNrOfInstances is NP");
+ }
// currentByteSize NP
-
+ if(container.getCurrentByteSize() != null){
+ throw new BadRequestException("CurrentByteSize is NP");
+ }
+
Container modifiedAttributes = new Container();
- // labels O
// accessControlPolicyIDs O
if(!container.getAccessControlPolicyIDs().isEmpty()){
+ for(AccessControlPolicyEntity acpe : containerEntity.getAccessControlPolicies()){
+ checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
+ }
containerEntity.getAccessControlPolicies().clear();
containerEntity.setAccessControlPolicies(ControllerUtil.
buildAcpEntityList(container.getAccessControlPolicyIDs(), transaction));
@@ -430,7 +450,13 @@
containerEntity.setOntologyRef(container.getOntologyRef());
modifiedAttributes.setOntologyRef(container.getOntologyRef());
}
-
+
+ // Update state tag
+ if(containerEntity.getStateTag() != null){
+ containerEntity.setStateTag(BigInteger.valueOf(containerEntity.getStateTag().intValue() + 1));
+ modifiedAttributes.setStateTag(containerEntity.getStateTag());
+ }
+
containerEntity.setLastModifiedTime(DateUtil.now());
modifiedAttributes.setLastModifiedTime(containerEntity.getLastModifiedTime());
response.setContent(modifiedAttributes);
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContentInstanceController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContentInstanceController.java
index 645c745..d30eef1 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContentInstanceController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/ContentInstanceController.java
@@ -36,6 +36,7 @@
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.OperationNotAllowed;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.ContentInstance;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
@@ -222,6 +223,10 @@
dbs.getDAOFactory().getContentInstanceDAO().delete(transaction, container.getChildContentInstances().get(0));
}
cinEntity.setParentContainer(container);
+ if(container.getStateTag() != null){
+ container.setStateTag(BigInteger.valueOf(container.getStateTag().intValue() + 1));
+ dbs.getDAOFactory().getContainerDAO().update(transaction, container);
+ }
}
// case parent is ContainerAnnc
if (parentEntity.getResourceType().intValue() == (ResourceType.CONTAINER_ANNC)) {
@@ -280,10 +285,7 @@
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
// this operation is not allowed for content instance resource
- // create the response primitive
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update on ContentInstance is not Allowed");
}
/**
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/Controller.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/Controller.java
index 3fc3e2c..7307475 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/Controller.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/Controller.java
@@ -26,7 +26,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.eclipse.om2m.commons.constants.AccessControl;
import org.eclipse.om2m.commons.constants.MimeMediaType;
import org.eclipse.om2m.commons.constants.Operation;
import org.eclipse.om2m.commons.constants.ResultContent;
@@ -42,6 +41,7 @@
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;
@@ -155,14 +155,11 @@
public void checkACP(List<AccessControlPolicyEntity> acpList, String originator, BigInteger operation)
throws AccessDeniedException{
if(originator == null){
- throw new AccessDeniedException("No originator privded");
+ throw new AccessDeniedException();
}
if (acpList == null || acpList.isEmpty()) {
throw new ResourceNotFoundException("Current resource does not have any ACP attached");
}
- if (!originatorExists(originator)) {
- throw new AccessDeniedException("Provided originator not found");
- }
// Check Resource accessRight existence not found
boolean originatorFound = false;
boolean operationAllowed = false;
@@ -171,7 +168,7 @@
originatorFound = false ;
operationAllowed = false;
for (AccessControlOriginatorEntity originatorEntity : rule.getAccessControlOriginators()){
- if (originatorEntity.getOriginatorID().equalsIgnoreCase(AccessControl.ORIGINATOR_ALL) || originatorEntity.getOriginatorID().equalsIgnoreCase(originator)){
+ if (originator.matches(originatorEntity.getOriginatorID().replace("*", ".*"))){
originatorFound = true;
break;
}
@@ -187,7 +184,7 @@
operationAllowed = true;
} else if (operation.equals(Operation.DISCOVERY) && rule.isDiscovery()){
operationAllowed = true;
- }else if(operation.equals(Operation.NOTIFY) && rule.isNotify()){
+ } else if (operation.equals(Operation.NOTIFY) && rule.isNotify()){
operationAllowed = true;
}
}
@@ -201,7 +198,7 @@
}
if (!originatorFound){
- throw new AccessDeniedException("Given originator is not found");
+ throw new AccessDeniedException();
}
if (!operationAllowed){
throw new AccessDeniedException();
@@ -224,7 +221,7 @@
originatorFound = false ;
operationAllowed = false ;
for (AccessControlOriginatorEntity originatorEntity : rule.getAccessControlOriginators()){
- if (originatorEntity.getOriginatorID().equalsIgnoreCase(AccessControl.ORIGINATOR_ALL) || originatorEntity.getOriginatorID().equalsIgnoreCase(originator)){
+ if (originator.matches(originatorEntity.getOriginatorID().replace("*", ".*"))){
originatorFound = true;
break;
}
@@ -253,7 +250,7 @@
}
}
if (!originatorFound){
- throw new AccessDeniedException("Given originator is not found");
+ throw new AccessDeniedException();
}
if (!operationAllowed){
throw new AccessDeniedException();
@@ -280,9 +277,15 @@
return generateId("", "");
}
- @SuppressWarnings("unchecked")
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)){
@@ -292,9 +295,7 @@
}
if(request.getResultContent().equals(ResultContent.HIERARCHICAL_AND_ATTRIBUTES)
|| request.getResultContent().equals(ResultContent.ATTRIBUTES)){
- Resource res = EntityMapperFactory.
- getMapperFromResourceType(entity.getResourceType().intValue()).
- mapEntityToResource(entity, ResultContent.ATTRIBUTES);
+ Resource res = mapper.mapEntityToResource(entity, ResultContent.ATTRIBUTES);
if(request.getReturnContentType().equals(MimeMediaType.OBJ)){
response.setContent(res);
} else {
@@ -304,13 +305,12 @@
}
}
} else {
- response.setContent(EntityMapperFactory.
- getMapperFromResourceType(entity.getResourceType().intValue()).
- mapEntityToResource(entity, ResultContent.ATTRIBUTES));
+ response.setContent(mapper.mapEntityToResource(entity, ResultContent.ATTRIBUTES));
response.setLocation(entity.getResourceID());
}
}
-
+
+
/**
* Allows to know if the provided originator exists in the system
* @param originator
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/DiscoveryController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/DiscoveryController.java
index 00c76f3..d878030 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/DiscoveryController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/DiscoveryController.java
@@ -31,23 +31,26 @@
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.AeEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkDeviceInfoEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkInfoEntity;
import org.eclipse.om2m.commons.entities.CSEBaseEntity;
import org.eclipse.om2m.commons.entities.ContainerEntity;
import org.eclipse.om2m.commons.entities.ContentInstanceEntity;
import org.eclipse.om2m.commons.entities.GroupEntity;
import org.eclipse.om2m.commons.entities.LabelEntity;
+import org.eclipse.om2m.commons.entities.NodeEntity;
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.entities.UriMapperEntity;
import org.eclipse.om2m.commons.exceptions.BadRequestException;
import org.eclipse.om2m.commons.exceptions.NotImplementedException;
+import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
-import org.eclipse.om2m.commons.resource.DiscoveryResult;
-import org.eclipse.om2m.commons.resource.DiscoveryResult.ResourceRef;
import org.eclipse.om2m.commons.resource.FilterCriteria;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
+import org.eclipse.om2m.commons.resource.URIList;
import org.eclipse.om2m.core.persistence.PersistenceService;
import org.eclipse.om2m.core.router.Patterns;
import org.eclipse.om2m.persistence.service.DAO;
@@ -62,9 +65,7 @@
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Delete of Discovery is not allowed");
}
@Override
@@ -157,43 +158,36 @@
childUris = dbs.getDBUtilManager().getComplexFindUtil().
getChildUrisDis(request.getTargetId(), filter);
}
-
- // Create the result object that will be serialized
- DiscoveryResult result = new DiscoveryResult();
- for (UriMapperEntity uriEntity : childUris){
- if(filter.getLimit() != null && result.getReferences().size() == filter.getLimit().intValue()){
- System.out.println("Limit reached");
+
+ URIList uriList = new URIList();
+ for(UriMapperEntity uriEntity : childUris){
+ if(filter.getLimit() != null && uriList.getListOfUri().size() == filter.getLimit().intValue()){
break;
}
- ResourceRef ref = new ResourceRef();
- ref.setResourceType(uriEntity.getResourceType());
if(request.getDiscoveryResultType().equals(DiscoveryResultType.HIERARCHICAL)){
- ref.setUri(uriEntity.getHierarchicalUri());
+ if(!uriList.getListOfUri().contains(uriEntity.getHierarchicalUri())){
+ uriList.getListOfUri().add(uriEntity.getHierarchicalUri());
+ }
} else {
- ref.setUri(uriEntity.getNonHierarchicalUri());
- }
- if(!result.getReferences().contains(ref)){
- result.getReferences().add(ref);
+ if(!uriList.getListOfUri().contains(uriEntity.getNonHierarchicalUri())){
+ uriList.getListOfUri().add(uriEntity.getNonHierarchicalUri());
+ }
}
}
- response.setContent(result);
+ response.setContent(uriList);
response.setResponseStatusCode(ResponseStatusCode.OK);
return response;
}
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update of Discovery is not allowed");
}
@Override
public ResponsePrimitive doDelete(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Delete of Discovery is not allowed");
}
private List<AccessControlPolicyEntity> getAcpsFromEntity(
@@ -216,6 +210,16 @@
return ((CSEBaseEntity) resourceEntity).getAccessControlPolicies();
case ResourceType.SUBSCRIPTION:
return ((SubscriptionEntity) resourceEntity).getAcpList();
+ case ResourceType.NODE:
+ return ((NodeEntity) resourceEntity).getAccessControlPolicies();
+ case ResourceType.MGMT_OBJ:
+ if (resourceEntity instanceof AreaNwkInfoEntity) {
+ return ((AreaNwkInfoEntity) resourceEntity).getAcps();
+ }
+ if (resourceEntity instanceof AreaNwkDeviceInfoEntity) {
+ return ((AreaNwkDeviceInfoEntity) resourceEntity).getAcps();
+ }
+ return null;
default:
// TODO On implementing resource, add the reference here
return null;
@@ -245,6 +249,14 @@
case(ResourceType.CSE_BASE):
result.addAll(labelEntity.getLinkedCsb());
break;
+ case(ResourceType.NODE): {
+ result.addAll(labelEntity.getLinkedNodes());
+ }
+ break;
+ case(ResourceType.MGMT_OBJ): {
+ result.addAll(labelEntity.getLinkedAni());
+ result.addAll(labelEntity.getLinkedAndi());
+ }
default:
break;
}
@@ -255,6 +267,9 @@
result.addAll(labelEntity.getLinkedGroup());
result.addAll(labelEntity.getLinkedCsr());
result.addAll(labelEntity.getLinkedCsb());
+ result.addAll(labelEntity.getLinkedNodes());
+ result.addAll(labelEntity.getLinkedAni());
+ result.addAll(labelEntity.getLinkedAndi());
}
return result;
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/FanOutPointController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/FanOutPointController.java
index 76b9945..1fc142a 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/FanOutPointController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/FanOutPointController.java
@@ -21,6 +21,9 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import org.eclipse.om2m.commons.constants.MimeMediaType;
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
@@ -31,12 +34,23 @@
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
import org.eclipse.om2m.core.router.Router;
+import org.eclipse.om2m.core.thread.CoreExecutor;
/**
* Controller for fan out point handling (virtual resource)
*
*/
public class FanOutPointController extends Controller {
+
+ private String foptSuffix;
+
+ public FanOutPointController(){
+ super();
+ }
+
+ public FanOutPointController(String foptSuffix){
+ this.foptSuffix = foptSuffix;
+ }
/**
* Fan out the request verifying access rights etc
@@ -46,9 +60,10 @@
protected ResponsePrimitive fanOutRequest(RequestPrimitive request) {
String targetGroup = request.getTargetId();
AggregatedResponse aggResp = new AggregatedResponse();
- ArrayList<RequestPrimitive> requests = new ArrayList<>();
+// ArrayList<RequestPrimitive> requests = new ArrayList<>();
ResponsePrimitive resp = new ResponsePrimitive(request);
-
+ List<Future<ResponsePrimitive>> listOfResponse = new ArrayList<Future<ResponsePrimitive>>();
+
// retrieve the parent group
GroupEntity group = dbs.getDAOFactory().getGroupDAO().find(transaction, targetGroup);
// check authorization of the originator
@@ -57,29 +72,34 @@
// TODO validate member types if not retrieve
- ArrayList<FanOutSender> threads = new ArrayList<>();
+// ArrayList<FanOutSender> threads = new ArrayList<>();
// fanout request to each member
for (String to : group.getMemberIDs()){
RequestPrimitive fanRequest = request.cloneParameters();
- fanRequest.setTo(to);
- fanRequest.setTargetId(to);
+ // if a suffix is provided add it to the request uri
+ LOGGER.info("Suffix in FanOutController " + this.foptSuffix);
+ if(this.foptSuffix != null){
+ fanRequest.setTo(to + foptSuffix);
+ } else {
+ fanRequest.setTo(to);
+ }
+ LOGGER.info(fanRequest.getTo());
fanRequest.setReturnContentType(MimeMediaType.OBJ);
- requests.add(fanRequest);
- FanOutSender t = new FanOutSender(fanRequest);
- threads.add(t);
- t.start();
+ listOfResponse.add(CoreExecutor.submit(new FanOutWorker(fanRequest)));
}
- // aggregate responses
- for (FanOutSender t : threads) {
+ for(Future<ResponsePrimitive> response : listOfResponse){
try {
- t.join();
- aggResp.getResponsePrimitive().add(t.getResp());
- } catch (InterruptedException e) {
- LOGGER.debug("Fan out thread interrupted", e);
+ aggResp.getResponsePrimitive().add(response.get());
+ } catch (InterruptedException | ExecutionException e) {
+ LOGGER.error("FanOutCallable exception", e);
+ ResponsePrimitive responsePrimitive = new ResponsePrimitive();
+ PrimitiveContent content = new PrimitiveContent();
+ content.getAny().add(e.getMessage());
+ responsePrimitive.setContent(content);
+ responsePrimitive.setResponseStatusCode(ResponseStatusCode.INTERNAL_SERVER_ERROR);
}
}
-
// sub group creation?
resp.setResponseStatusCode(ResponseStatusCode.OK);
@@ -110,64 +130,38 @@
// fan out the request
return fanOutRequest(request);
}
-
-
+
/**
- * Thread to fan out request
+ * This inner class defines the Callable that will return the
+ * response of a request for the FanOutPoint broadcast.
*
*/
- class FanOutSender extends Thread {
- /** Request to fan out */
- private RequestPrimitive reqToFanOut;
- /** Response primitive returned by the router */
- private ResponsePrimitive resp ;
+ private static class FanOutWorker implements Callable<ResponsePrimitive>{
+
+ /** The request that will be fan out to the router. */
+ private RequestPrimitive request;
+
/**
- * Constructor
- * @param req to fan out
+ * Main constructor with the request to be fan out.
+ * @param request request to fan out
*/
- public FanOutSender(RequestPrimitive req) {
- this.reqToFanOut = req;
+ public FanOutWorker(RequestPrimitive request){
+ this.request = request;
}
-
+
/**
- * Send the request
+ * Implementation of the call() method from Callable<T>.
+ * It sends the request to the router and retrieve the result
+ * that will be send to the caller of the class.
*/
@Override
- public void run() {
- resp = new Router().doRequest(reqToFanOut);
+ public ResponsePrimitive call() throws Exception {
+ ResponsePrimitive resp = new Router().doRequest(request);
resp.setPrimitiveContent(new PrimitiveContent());
resp.getPritimitiveContent().getAny().add(resp.getContent());
- }
-
- /**
- * @return the reqToFanOut
- */
- public RequestPrimitive getReqToFanOut() {
- return reqToFanOut;
- }
-
- /**
- * @param reqToFanOut the reqToFanOut to set
- */
- public void setReqToFanOut(RequestPrimitive reqToFanOut) {
- this.reqToFanOut = reqToFanOut;
- }
-
- /**
- * @return the resp
- */
- public ResponsePrimitive getResp() {
return resp;
}
-
- /**
- * @param resp the resp to set
- */
- public void setResp(ResponsePrimitive resp) {
- this.resp = resp;
- }
-
-
+
}
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/GroupController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/GroupController.java
index e2c85d1..d20ec6c 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/GroupController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/GroupController.java
@@ -23,6 +23,7 @@
import org.eclipse.om2m.commons.constants.ConsistencyStrategy;
import org.eclipse.om2m.commons.constants.Constants;
+import org.eclipse.om2m.commons.constants.MemberType;
import org.eclipse.om2m.commons.constants.MimeMediaType;
import org.eclipse.om2m.commons.constants.Operation;
import org.eclipse.om2m.commons.constants.ResourceStatus;
@@ -53,6 +54,7 @@
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.core.util.GroupUtil;
import org.eclipse.om2m.persistence.service.DAO;
import org.eclipse.om2m.persistence.service.DBService;
@@ -194,11 +196,12 @@
}
groupEntity.setMaxNrOfMembers(group.getMaxNrOfMembers());
- // memberType M
+ // memberType O
if(group.getMemberType() == null){
- throw new BadRequestException("MemberType is Mandatory");
+ groupEntity.setMemberType(MemberType.MIXED);
+ } else {
+ groupEntity.setMemberType(group.getMemberType());
}
- groupEntity.setMemberType(group.getMemberType());
// memberID M
if (group.getMemberIDs().isEmpty()){
throw new BadRequestException("MemberIDs is Mandatory");
@@ -381,10 +384,23 @@
// accessControlPolicyIDs NP
// creationTime NP
// lastModifiedTime NP
+ UpdateUtil.checkNotPermittedParameters(group);
// creator NP
+ if(group.getCreator() != null){
+ throw new BadRequestException("Creator is NP");
+ }
// currentNrOdMembers NP
+ if(group.getCurrentNrOfMembers() != null){
+ throw new BadRequestException("CurrentNrOfMembers is NP");
+ }
// memberTypeValidated NP
+ if(group.getMemberTypeValidated() != null){
+ throw new BadRequestException("MemberTypeValidated is NP");
+ }
// consistencyStrategy NP
+ if(group.getConsistencyStrategy() != null){
+ throw new BadRequestException("ConsistencyStrategy is NP");
+ }
Group modifiedAttributes = new Group();
@@ -430,6 +446,9 @@
}
// membersACPIDs O
if(!group.getMembersAccessControlPolicyIDs().isEmpty()){
+ for(AccessControlPolicyEntity acpe : groupEntity.getAccessControlPolicies()){
+ checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
+ }
groupEntity.getMemberAcpIds().clear();
groupEntity.getMemberAcpIds().addAll(group.getMembersAccessControlPolicyIDs());
modifiedAttributes.getMembersAccessControlPolicyIDs().addAll(group.getMembersAccessControlPolicyIDs());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/LatestOldestController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/LatestOldestController.java
index 20a7f7b..2aa5012 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/LatestOldestController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/LatestOldestController.java
@@ -25,6 +25,7 @@
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.ContainerEntity;
import org.eclipse.om2m.commons.entities.ContentInstanceEntity;
+import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.ContentInstance;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
@@ -52,9 +53,7 @@
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Create on " + policy.toString() +" is not allowed");
}
@Override
@@ -98,9 +97,7 @@
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update on " + policy + " is not allowed");
}
@Override
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/NodeController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/NodeController.java
index 04c1003..8b21332 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/NodeController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/NodeController.java
@@ -47,6 +47,7 @@
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;
@@ -271,14 +272,23 @@
// creationTime NP
// creator NP
// lastModifiedTime NP
- // currentNrOfInstances NP
- // currentByteSize NP
- // labels NP
+ UpdateUtil.checkNotPermittedParameters(node);
+ // hostedCseLink NP
+ if(node.getHostedCSELink() != null){
+ throw new BadRequestException("HostedCSELink is NP");
+ }
Node modifiedAttributes = new Node();
-
+ // 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());
@@ -307,10 +317,6 @@
nodeEntity.setNodeID(node.getNodeID());
modifiedAttributes.setNodeID(node.getNodeID());
}
- // hostedCSELink NP
- if (node.getHostedCSELink() != null) {
- response.setErrorMessage("WARNING: update of hosted CSE link is not permitted and has not been updated");
- }
nodeEntity.setLastModifiedTime(DateUtil.now());
modifiedAttributes.setLastModifiedTime(nodeEntity.getLastModifiedTime());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelController.java
index ea53daf..f90ec52 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelController.java
@@ -34,7 +34,6 @@
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.AccessDeniedException;
import org.eclipse.om2m.commons.exceptions.BadRequestException;
import org.eclipse.om2m.commons.exceptions.ConflictException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
@@ -48,6 +47,7 @@
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;
/**
@@ -99,10 +99,8 @@
return response;
}
- if(!request.getFrom().equals(originatorToCheck)){
- throw new AccessDeniedException("Only the creator of the parent resource can create a polling channel.");
- }
-
+ checkACP(acpsToCheck, request.getFrom(), Operation.CREATE);
+
// Check if content is present
if (request.getContent() == null){
throw new BadRequestException("A content is requiered for PollingChannel creation");
@@ -250,8 +248,9 @@
throw new BadRequestException("Error in provided content");
}
- PollingChannel modifiedAttributes = new PollingChannel();
+ UpdateUtil.checkNotPermittedParameters(pollingChannel);
+ PollingChannel modifiedAttributes = new PollingChannel();
// expirationTime O
if(pollingChannel.getExpirationTime() != null){
pollingChannelEntity.setExpirationTime(pollingChannel.getExpirationTime());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelUriController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelUriController.java
index 6b24930..c94c98f 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelUriController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/PollingChannelUriController.java
@@ -19,42 +19,35 @@
*******************************************************************************/
package org.eclipse.om2m.core.controller;
-import org.eclipse.om2m.commons.constants.ResponseStatusCode;
+import org.eclipse.om2m.commons.exceptions.NotImplementedException;
+import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
/**
- * Controller for polling channel uri
+ * Controller for polling channel URI
*
*/
public class PollingChannelUriController extends Controller {
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Create on PollingChannelUri is not allowed");
}
@Override
public ResponsePrimitive doRetrieve(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.NOT_IMPLEMENTED);
- return response;
+ throw new NotImplementedException("Retrieve operation on PollingChannelURI is not implemented");
}
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update on PollingChannelUri is not allowed");
}
@Override
public ResponsePrimitive doDelete(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Delete on PollingChannelUri is not allowed");
}
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RemoteCSEController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RemoteCSEController.java
index 1781ac7..e26a89e 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RemoteCSEController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RemoteCSEController.java
@@ -51,6 +51,7 @@
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;
import org.eclipse.om2m.persistence.service.DBService;
import org.eclipse.om2m.persistence.service.DBTransaction;
@@ -428,16 +429,36 @@
// parentID NP
// creationTime NP
// lastModifiedTime NP
- // labels NP
+ UpdateUtil.checkNotPermittedParameters(csr);
// cseType NP
+ if(csr.getCseType() != null){
+ throw new BadRequestException("CseType is NP");
+ }
// CseBase NP
+ if(csr.getCSEBase() != null){
+ throw new BadRequestException("CseBase is NP");
+ }
// CSE-ID NP
+ if(csr.getCSEID() != null){
+ throw new BadRequestException("CseID is NP");
+ }
// nodeLink NP
+ if(csr.getNodeLink() != null){
+ throw new BadRequestException("NodeLink is NP");
+ }
RemoteCSE modifiedAttributes = new RemoteCSE();
-
+ // labels O
+ if(!csr.getLabels().isEmpty()){
+ csrEntity.setLabelsEntitiesFromSring(csr.getLabels());
+ modifiedAttributes.getLabels().addAll(csr.getLabels());
+ }
+
// accessControlPolicyIDs O
if (!csr.getAccessControlPolicyIDs().isEmpty()){
+ for(AccessControlPolicyEntity acpe : csrEntity.getAccessControlPolicies()){
+ checkSelfACP(acpe, request.getFrom(), Operation.UPDATE);
+ }
csrEntity.setAccessControlPolicies(
ControllerUtil.buildAcpEntityList(csr.getAccessControlPolicyIDs(), transaction));
modifiedAttributes.getAccessControlPolicyIDs().addAll(csr.getAccessControlPolicyIDs());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RequestController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RequestController.java
index 7e4f6ce..bb77183 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RequestController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/RequestController.java
@@ -23,6 +23,7 @@
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
import org.eclipse.om2m.commons.entities.RequestEntity;
import org.eclipse.om2m.commons.exceptions.AccessDeniedException;
+import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.Request;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
@@ -34,9 +35,7 @@
@Override
public ResponsePrimitive doCreate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Create on Request is not allowed");
}
@Override
@@ -64,9 +63,7 @@
@Override
public ResponsePrimitive doUpdate(RequestPrimitive request) {
- ResponsePrimitive response = new ResponsePrimitive(request);
- response.setResponseStatusCode(ResponseStatusCode.OPERATION_NOT_ALLOWED);
- return response;
+ throw new OperationNotAllowed("Update on Request is not allowed");
}
@Override
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/SubscriptionController.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/SubscriptionController.java
index a2a2962..50173a1 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/SubscriptionController.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/controller/SubscriptionController.java
@@ -52,6 +52,7 @@
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;
@@ -120,7 +121,7 @@
acpsToCheck = csr.getAccessControlPolicies();
}
- if(acpsToCheck.isEmpty()){
+ if(acpsToCheck == null){
throw new NotImplementedException("Subscription is not yet supported on this resource");
}
@@ -358,22 +359,37 @@
// 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){
@@ -382,19 +398,23 @@
// 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){
@@ -407,31 +427,39 @@
// 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();
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkDeviceInfoMapper.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkDeviceInfoMapper.java
new file mode 100644
index 0000000..3f07125
--- /dev/null
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkDeviceInfoMapper.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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.entitymapper;
+
+import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkDeviceInfoEntity;
+import org.eclipse.om2m.commons.resource.AreaNwkDeviceInfo;
+
+/**
+ * Mapper for AreaNwkDeviceInfo
+ *
+ */
+public class AreaNwkDeviceInfoMapper extends EntityMapper<AreaNwkDeviceInfoEntity, AreaNwkDeviceInfo> {
+
+ @Override
+ protected void mapAttributes(AreaNwkDeviceInfoEntity entity,
+ AreaNwkDeviceInfo resource) {
+ resource.setAreaNwkId(entity.getAreaNwkId());
+ resource.setDescription(entity.getDescription());
+ resource.setDevID(entity.getDevID());
+ resource.setExpirationTime(entity.getExpirationTime());
+ resource.setMgmtDefinition(entity.getMgmtDefinition());
+ resource.setName(entity.getName());
+ resource.setSleepDuration(entity.getSleepDuration());
+ resource.setSleepInterval(entity.getSleepInterval());
+ resource.setStatus(entity.getStatus());
+
+ for (AccessControlPolicyEntity acp : entity.getAcps()) {
+ resource.getAccessControlPolicyIDs().add(acp.getResourceID());
+ }
+
+ if (!entity.getAnnouncedAttribute().isEmpty()) {
+ resource.getAnnouncedAttribute().addAll(entity.getAnnouncedAttribute());
+ }
+ if (!entity.getAnnounceTo().isEmpty()) {
+ resource.getAnnounceTo().addAll(entity.getAnnounceTo());
+ }
+
+ }
+
+ @Override
+ protected void mapChildResourceRef(AreaNwkDeviceInfoEntity entity,
+ AreaNwkDeviceInfo resource) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void mapChildResources(AreaNwkDeviceInfoEntity entity,
+ AreaNwkDeviceInfo resource) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected AreaNwkDeviceInfo createResource() {
+ return new AreaNwkDeviceInfo();
+ }
+
+
+
+}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkInfoMapper.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkInfoMapper.java
new file mode 100644
index 0000000..bec4633
--- /dev/null
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/AreaNwkInfoMapper.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.entitymapper;
+
+import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkInfoEntity;
+import org.eclipse.om2m.commons.entities.LabelEntity;
+import org.eclipse.om2m.commons.resource.AreaNwkInfo;
+
+public class AreaNwkInfoMapper extends EntityMapper<AreaNwkInfoEntity, AreaNwkInfo> {
+
+ @Override
+ protected void mapAttributes(AreaNwkInfoEntity entity, AreaNwkInfo resource) {
+ resource.setAreaNwkType(entity.getAreaNwkType());
+ resource.setCreationTime(entity.getCreationTime());
+ resource.setDescription(entity.getDescription());
+ resource.setExpirationTime(entity.getExpirationTime());
+ resource.setLastModifiedTime(entity.getLastModifiedTime());
+ resource.setMgmtDefinition(entity.getMgmtDefinition());
+ resource.setName(entity.getName());
+ resource.setParentID(entity.getParentID());
+ resource.setResourceID(entity.getResourceID());
+ resource.setResourceType(entity.getResourceType());
+ if (!entity.getAnnouncedAttribute().isEmpty()) {
+ resource.getAnnouncedAttribute().addAll(entity.getAnnouncedAttribute());
+ }
+ if (!entity.getAnnounceTo().isEmpty()) {
+ resource.getAnnounceTo().addAll(entity.getAnnounceTo());
+ }
+ for (AccessControlPolicyEntity acp : entity.getAcps()) {
+ resource.getAccessControlPolicyIDs().add(acp.getResourceID());
+ }
+ for (LabelEntity lbl : entity.getLabelsEntities()) {
+ resource.getLabels().add(lbl.getLabel());
+ }
+ if (!entity.getListOfDevices().isEmpty()) {
+ resource.getListOfDevices().addAll(entity.getListOfDevices());
+ }
+ }
+
+ @Override
+ protected void mapChildResourceRef(AreaNwkInfoEntity entity,
+ AreaNwkInfo resource) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void mapChildResources(AreaNwkInfoEntity entity,
+ AreaNwkInfo resource) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected AreaNwkInfo createResource() {
+ return new AreaNwkInfo();
+ }
+
+}
+
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/ContainerMapper.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/ContainerMapper.java
index 8ab93d6..0401feb 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/ContainerMapper.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/ContainerMapper.java
@@ -23,6 +23,7 @@
import org.eclipse.om2m.commons.constants.ResourceType;
import org.eclipse.om2m.commons.constants.ResultContent;
+import org.eclipse.om2m.commons.constants.ShortName;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.ContainerEntity;
import org.eclipse.om2m.commons.entities.ContentInstanceEntity;
@@ -61,6 +62,8 @@
for (AccessControlPolicyEntity acp : entity.getAccessControlPolicies()) {
resource.getAccessControlPolicyIDs().add(acp.getResourceID());
}
+ resource.setOldest(entity.getHierarchicalURI() + "/" + ShortName.OLDEST);
+ resource.setLatest(entity.getHierarchicalURI() + "/" + ShortName.LATEST);
}
@Override
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapper.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapper.java
index 1cebf36..a202f77 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapper.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapper.java
@@ -27,7 +27,6 @@
import org.eclipse.om2m.commons.entities.ResourceEntity;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
import org.eclipse.om2m.commons.resource.Resource;
-import org.eclipse.om2m.commons.utils.UriUtil;
/**
* Generic entity mapper
@@ -47,7 +46,7 @@
resource.setLastModifiedTime(entity.getLastModifiedTime());
resource.setName(entity.getName());
resource.setParentID(entity.getParentID());
- resource.setResourceID(UriUtil.toCseRelativeUri(entity.getResourceID()));
+ resource.setResourceID(entity.getResourceID());
resource.setResourceType(entity.getResourceType());
for (LabelEntity lbl : entity.getLabelsEntities()){
resource.getLabels().add(lbl.getLabel());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapperFactory.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapperFactory.java
index 2f710aa..dc12cab 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapperFactory.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/EntityMapperFactory.java
@@ -22,10 +22,13 @@
import org.eclipse.om2m.commons.constants.ResourceType;
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.AeEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkDeviceInfoEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkInfoEntity;
import org.eclipse.om2m.commons.entities.CSEBaseEntity;
import org.eclipse.om2m.commons.entities.ContainerEntity;
import org.eclipse.om2m.commons.entities.ContentInstanceEntity;
import org.eclipse.om2m.commons.entities.GroupEntity;
+import org.eclipse.om2m.commons.entities.MgmtObjEntity;
import org.eclipse.om2m.commons.entities.NodeEntity;
import org.eclipse.om2m.commons.entities.PollingChannelEntity;
import org.eclipse.om2m.commons.entities.RemoteCSEEntity;
@@ -33,6 +36,8 @@
import org.eclipse.om2m.commons.entities.SubscriptionEntity;
import org.eclipse.om2m.commons.resource.AE;
import org.eclipse.om2m.commons.resource.AccessControlPolicy;
+import org.eclipse.om2m.commons.resource.AreaNwkDeviceInfo;
+import org.eclipse.om2m.commons.resource.AreaNwkInfo;
import org.eclipse.om2m.commons.resource.CSEBase;
import org.eclipse.om2m.commons.resource.Container;
import org.eclipse.om2m.commons.resource.ContentInstance;
@@ -95,6 +100,16 @@
return new RequestMapper();
}
+ /** Get the Area Nwk info mapper */
+ public static EntityMapper<AreaNwkInfoEntity, AreaNwkInfo> getAreaNwkInfoMapper(){
+ return new AreaNwkInfoMapper();
+ }
+
+ /** Get the Area Nwk device info mapper */
+ public static EntityMapper<AreaNwkDeviceInfoEntity, AreaNwkDeviceInfo> getAreaNwkDeviceInfoMapper(){
+ return new AreaNwkDeviceInfoMapper();
+ }
+
/**
* Get entity mapper from resource type
* @param resourceType (integer)
@@ -126,9 +141,27 @@
return new PollingChannelMapper();
case ResourceType.REQUEST:
return new RequestMapper();
+ case ResourceType.MGMT_OBJ:
+ throw new IllegalArgumentException("Cannot get Mapper for MGMT OBJ");
default:
return null;
}
}
+
+ /**
+ * Get the entity mapper for specific mgmtObj entity
+ * @param mgmtObj
+ * @return entity mapper
+ */
+ @SuppressWarnings("rawtypes")
+ public static EntityMapper getMapperForMgmtObj(MgmtObjEntity mgmtObj) {
+ if (mgmtObj instanceof AreaNwkInfoEntity) {
+ return new AreaNwkInfoMapper();
+ }
+ if (mgmtObj instanceof AreaNwkDeviceInfoEntity) {
+ return new AreaNwkDeviceInfoMapper();
+ }
+ return null;
+ }
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/NodeMapper.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/NodeMapper.java
index 5c2811c..113b3a4 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/NodeMapper.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/entitymapper/NodeMapper.java
@@ -19,7 +19,15 @@
*******************************************************************************/
package org.eclipse.om2m.core.entitymapper;
+import org.eclipse.om2m.commons.constants.ResourceType;
+import org.eclipse.om2m.commons.constants.ResultContent;
+import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkDeviceInfoEntity;
+import org.eclipse.om2m.commons.entities.AreaNwkInfoEntity;
import org.eclipse.om2m.commons.entities.NodeEntity;
+import org.eclipse.om2m.commons.resource.AreaNwkDeviceInfo;
+import org.eclipse.om2m.commons.resource.AreaNwkInfo;
+import org.eclipse.om2m.commons.resource.ChildResourceRef;
import org.eclipse.om2m.commons.resource.Node;
/**
@@ -32,16 +40,52 @@
protected void mapAttributes(NodeEntity entity, Node resource) {
resource.setNodeID(entity.getNodeID());
resource.setHostedCSELink(entity.getHostedCSELink());
+ resource.setExpirationTime(entity.getExpirationTime());
+
+ if (!entity.getAnnouncedAttribute().isEmpty()) {
+ resource.getAnnouncedAttribute().addAll(entity.getAnnouncedAttribute());
+ }
+ if (!entity.getAnnounceTo().isEmpty()) {
+ resource.getAnnounceTo().addAll(entity.getAnnounceTo());
+ }
+
+ for (AccessControlPolicyEntity acp : entity.getAccessControlPolicies()) {
+ resource.getAccessControlPolicyIDs().add(acp.getResourceID());
+ }
}
@Override
protected void mapChildResourceRef(NodeEntity entity, Node resource) {
- // TODO Auto-generated method stub
+ // add child area nwk info entities
+ for (AreaNwkInfoEntity aniEntity : entity.getChildAreaNwkInfoEntities()) {
+ ChildResourceRef chref = new ChildResourceRef();
+ chref.setResourceName(aniEntity.getName());
+ chref.setType(ResourceType.MGMT_OBJ);
+ chref.setValue(aniEntity.getResourceID());
+ resource.getChildResource().add(chref);
+ }
+ // add child area nwk device info entities
+ for (AreaNwkDeviceInfoEntity andiEntity : entity.getChildAreaNwkDeviceInfoEntities()) {
+ ChildResourceRef chref = new ChildResourceRef();
+ chref.setResourceName(andiEntity.getName());
+ chref.setType(ResourceType.MGMT_OBJ);
+ chref.setValue(andiEntity.getResourceID());
+ resource.getChildResource().add(chref);
+ }
}
@Override
protected void mapChildResources(NodeEntity entity, Node resource) {
- // TODO Auto-generated method stub
+ // add child area nwk info entities
+ for (AreaNwkInfoEntity aniEntity : entity.getChildAreaNwkInfoEntities()) {
+ AreaNwkInfo aniRes = new AreaNwkInfoMapper().mapEntityToResource(aniEntity, ResultContent.ATTRIBUTES);
+ resource.getMemoryOrBatteryOrAreaNwkInfo().add(aniRes);
+ }
+ // add child area nwk device info entities
+ for (AreaNwkDeviceInfoEntity andiEntity : entity.getChildAreaNwkDeviceInfoEntities()) {
+ AreaNwkDeviceInfo andiRes = new AreaNwkDeviceInfoMapper().mapEntityToResource(andiEntity, ResultContent.ATTRIBUTES);
+ resource.getMemoryOrBatteryOrAreaNwkInfo().add(andiRes);
+ }
}
@Override
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingHandler.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingHandler.java
index fbb9513..818ae60 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingHandler.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingHandler.java
@@ -71,18 +71,22 @@
if(request.getRequestContentType().equals(MimeMediaType.OBJ)){
requestEntity.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.JSON).objToString(request.getContent()));
requestEntity.setRequestContentType(MimeMediaType.JSON);
- } else if(!request.getRequestContentType().equals(MimeMediaType.JSON)){
- Object resource = DataMapperSelector.getDataMapperList().
- get(request.getReturnContentType()).stringToObj((String)request.getContent());
- requestEntity.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.JSON).objToString(resource));
- requestEntity.setRequestContentType(request.getRequestContentType());
} else {
- requestEntity.setContent((String) request.getContent());
- requestEntity.setRequestContentType(request.getRequestContentType());
+ if(request.getContent() instanceof String && !((String)request.getContent()).isEmpty()){
+ if(!request.getRequestContentType().equals(MimeMediaType.JSON)){
+ Object resource = DataMapperSelector.getDataMapperList().
+ get(request.getReturnContentType()).stringToObj((String)request.getContent());
+ requestEntity.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.JSON).objToString(resource));
+ requestEntity.setRequestContentType(request.getRequestContentType());
+ } else {
+ requestEntity.setContent((String) request.getContent());
+ requestEntity.setRequestContentType(request.getRequestContentType());
+ }
+ }
}
}
} catch (Exception e){
- throw new BadRequestException("Error in provided content");
+ throw new BadRequestException("Error in provided content", e);
}
requestEntity.setCreationTime(DateUtil.now());
@@ -129,6 +133,7 @@
Request requestResource = EntityMapperFactory.getRequestMapper().mapEntityToResource(requestEntity, ResultContent.ATTRIBUTES);
response.setContent(requestResource.getResourceID());
+ response.setContentType(MimeMediaType.TEXT_PLAIN);
response.setResponseStatusCode(ResponseStatusCode.ACCEPTED);
response.setLocation(requestDb.getResourceID());
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingWorker.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingWorker.java
index 81c6db6..5473266 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingWorker.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/nblocking/NonBlockingWorker.java
@@ -96,7 +96,13 @@
if(request.getReturnContentType().equals(MimeMediaType.OBJ)){
managedRequest.setOperationResultContent(DataMapperSelector.
getDataMapperList().get(MimeMediaType.JSON).objToString(response.getContent()));
- } else {
+ } else if(request.getReturnContentType().equals(MimeMediaType.XML)){
+ Object objReseult = DataMapperSelector.getDataMapperList().
+ get(MimeMediaType.XML).stringToObj((String)response.getContent());
+ String jsonResult = DataMapperSelector.getDataMapperList().get(MimeMediaType.JSON).objToString(objReseult);
+ managedRequest.setOperationResultContent(jsonResult);
+ }
+ else {
managedRequest.setOperationResultContent((String) response.getContent());
}
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/notifier/Notifier.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/notifier/Notifier.java
index 362de0b..3744af3 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/notifier/Notifier.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/notifier/Notifier.java
@@ -1,278 +1,276 @@
-/*******************************************************************************
- * 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.notifier;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-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.NotificationContentType;
-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.ResultContent;
-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.ScheduleEntity;
-import org.eclipse.om2m.commons.entities.SubscriptionEntity;
-import org.eclipse.om2m.commons.exceptions.Om2mException;
-import org.eclipse.om2m.commons.resource.Notification;
-import org.eclipse.om2m.commons.resource.Notification.NotificationEvent;
-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.comm.RestClient;
-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.core.router.Patterns;
-import org.eclipse.om2m.core.router.Router;
-import org.eclipse.om2m.core.urimapper.UriMapper;
-import org.eclipse.om2m.persistence.service.DAO;
-import org.eclipse.om2m.persistence.service.DBService;
-import org.eclipse.om2m.persistence.service.DBTransaction;
-
-/**
- * Notifies subscribers when a change occurs on a resource according to their subscriptions.
- */
-public class Notifier {
- /** Logger */
- private static Log LOGGER = LogFactory.getLog(Notifier.class);
-
- private static final int NOTIFICATION_NTHREADS = Integer.parseInt(System.getProperty("org.eclipse.om2m.notification.nthreads", "20"));
- private static final ExecutorService threadPool = Executors.newFixedThreadPool(NOTIFICATION_NTHREADS);
-
- /**
- * Finds all resource subscribers and notifies them.
- * @param statusCode - Notification status code
- * @param resource - Notification resource
- */
- public static void notify(List<SubscriptionEntity> listSubscription, ResourceEntity resource, int resourceStatus) {
- if (listSubscription != null){
- for(SubscriptionEntity sub : listSubscription){
- NotificationWorker worker = new NotificationWorker(sub, resourceStatus, resource);
- threadPool.execute(worker);
- }
- }
- }
-
- /**
- * Used in DELETE procedure when a resource is deleted. It notifies the subscribed resource
- * and the parent resource subscribed entities.
- * @param listSubs
- * @param resourceDeleted
- */
- public static void notifyDeletion(List<SubscriptionEntity> listSubs, ResourceEntity resourceDeleted){
- List<SubscriptionEntity> parentSubscriptions = getParentSubscriptions(resourceDeleted);
- if(parentSubscriptions != null){
- notify(parentSubscriptions, resourceDeleted, ResourceStatus.CHILD_DELETED);
- }
- if(listSubs != null){
- notify(listSubs, resourceDeleted, ResourceStatus.DELETED);
- }
- }
-
- public static void performVerificationRequest(RequestPrimitive request,
- SubscriptionEntity subscriptionEntity) {
- for(String uri : subscriptionEntity.getNotificationURI()){
- if(!uri.equals(request.getFrom())){
- Notification notification = new Notification();
- notification.setCreator(subscriptionEntity.getCreator());
- notification.setVerificationRequest(true);
- notification.setSubscriptionReference(subscriptionEntity.getHierarchicalURI());
- notification.setSubscriptionDeletion(false);
- RequestPrimitive notifRequest = new RequestPrimitive();
- notifRequest.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.XML).objToString(notification));
- notifRequest.setFrom("/" + Constants.CSE_ID);
- notifRequest.setTo(uri);
- notifRequest.setOperation(Operation.NOTIFY);
- notifRequest.setRequestContentType(MimeMediaType.XML);
- notifRequest.setReturnContentType(MimeMediaType.XML);
- ResponsePrimitive resp = notify(notifRequest, uri);
- if(resp.getResponseStatusCode().equals(ResponseStatusCode.TARGET_NOT_REACHABLE)){
- throw new Om2mException("Error during the verification request",
- ResponseStatusCode.SUBSCRIPTION_VERIFICATION_INITIATION_FAILED);
- }
- if(resp.getResponseStatusCode().equals(ResponseStatusCode.SUBSCRIPTION_CREATOR_HAS_NO_PRIVILEGE)
- || resp.getResponseStatusCode().equals(ResponseStatusCode.SUBSCRIPTION_HOST_HAS_NO_PRIVILEGE)){
- throw new Om2mException(resp.getResponseStatusCode());
- }
- }
- }
- }
-
- public static ResponsePrimitive notify(RequestPrimitive request, String contact){
- // Check whether the subscription contact is protocol-dependent or not.
- LOGGER.info("Sending notify request to: " + contact);
- if(contact.matches(".*://.*")){
- // Contact = protocol-dependent -> direct notification using the rest client.
- request.setTo(contact);
- return RestClient.sendRequest(request);
- }else{
- request.setTargetId(contact);
- LOGGER.info("Sending notify request...");
- return new Router().doRequest(request);
- }
- }
-
- /**
- * Used to retrieve the subscription list of the parent resource
- * @param resource
- * @return
- */
- private static List<SubscriptionEntity> getParentSubscriptions(
- ResourceEntity resourceDeleted) {
- List<SubscriptionEntity> result;
- // Get parent id
- String[] ids = resourceDeleted.getHierarchicalURI().split("/");
- String parentHierarchicalId = resourceDeleted.getHierarchicalURI().replace("/" + ids[ids.length - 1], "");
- String parentId = UriMapper.getNonHierarchicalUri(parentHierarchicalId);
- // get parent entity
- DBService dbs = PersistenceService.getInstance().getDbService();
-
- DAO<?> dao = Patterns.getDAO(parentId, dbs);
- DBTransaction transaction = dbs.getDbTransaction();
- transaction.open();
- ResourceEntity parentEntity = (ResourceEntity) dao.find(transaction, parentId);
- // get the sub list from parent
- switch(parentEntity.getResourceType().intValue()){
- case ResourceType.ACCESS_CONTROL_POLICY:
- AccessControlPolicyEntity acp = (AccessControlPolicyEntity) parentEntity;
- result = acp.getChildSubscriptions();
- break;
- case ResourceType.AE:
- AeEntity ae = (AeEntity) parentEntity;
- result = ae.getSubscriptions();
- break;
- case ResourceType.CONTAINER:
- ContainerEntity cnt = (ContainerEntity) parentEntity;
- result = cnt.getSubscriptions();
- break;
- case ResourceType.CSE_BASE:
- CSEBaseEntity csb = (CSEBaseEntity) parentEntity;
- result = csb.getSubscriptions();
- break;
- case ResourceType.GROUP:
- GroupEntity group = (GroupEntity) parentEntity;
- result = group.getSubscriptions();
- break;
- case ResourceType.REMOTE_CSE:
- RemoteCSEEntity csr = (RemoteCSEEntity) parentEntity;
- result = csr.getSubscriptions();
- break;
- case ResourceType.SCHEDULE:
- ScheduleEntity schedule = (ScheduleEntity) parentEntity;
- result = schedule.getSubscriptions();
- break;
- default:
- result = new ArrayList<SubscriptionEntity>();
- }
- transaction.close();
- return result;
- }
-
- /**
- * Worker that perform the notification task for a subscription
- *
- */
- static class NotificationWorker extends Thread {
- /** resource status of the notification */
- private int resourceStatus;
- /** the subscription to handle */
- private SubscriptionEntity sub;
- /** the resource to be sent */
- private ResourceEntity resource;
-
- public NotificationWorker(SubscriptionEntity sub, int resourceStatus, ResourceEntity resource) {
- this.resourceStatus = resourceStatus;
- this.sub = sub;
- this.resource = resource;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- final RequestPrimitive request = new RequestPrimitive();
- Notification notification = new Notification();
- NotificationEvent notifEvent = new NotificationEvent();
- notification.setNotificationEvent(notifEvent);
-
- // Set attributes of notification object
- notifEvent.setResourceStatus(BigInteger.valueOf(resourceStatus));
- notification.setCreator(sub.getCreator());
-
- // Set request parameters
- request.setOperation(Operation.NOTIFY);
- request.setFrom("/" + Constants.CSE_ID);
-
- if(resourceStatus == ResourceStatus.DELETED){
- notification.setSubscriptionDeletion(true);
- } else {
- notification.setSubscriptionDeletion(false);
- }
-
- notification.setSubscriptionReference(sub.getHierarchicalURI());
-
- // Get the representation of the content
- if (sub.getNotificationContentType() != null){
- if(sub.getNotificationContentType().equals(NotificationContentType.MODIFIED_ATTRIBUTES)){
- Resource serializableResource = (Resource) EntityMapperFactory.
- getMapperFromResourceType(resource.getResourceType().intValue()).
- mapEntityToResource(resource, ResultContent.ATTRIBUTES);
- notification.getNotificationEvent().setRepresentation(serializableResource);
- request.setRequestContentType(MimeMediaType.XML);
- } else if(sub.getNotificationContentType().equals(NotificationContentType.WHOLE_RESOURCE)){
- Resource serializableResource = (Resource) EntityMapperFactory.
- getMapperFromResourceType(resource.getResourceType().intValue()).
- mapEntityToResource(resource, ResultContent.ATTRIBUTES);
- notification.getNotificationEvent().setRepresentation(serializableResource);
- request.setRequestContentType(MimeMediaType.XML);
- }
- }
-
- // Set the content
- request.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.XML).objToString(notification));
- // For each notification URI: send the notify request
- for(final String uri : sub.getNotificationURI()){
- ExecutorService senderThreadPool = Executors.newFixedThreadPool(5);
- senderThreadPool.execute(new Thread(){
- public void run() {
- Notifier.notify(request, uri);
- };
- });
- senderThreadPool.shutdown();
- }
- }
- }
-
-}
+/*******************************************************************************
+ * 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.notifier;
+
+import java.math.BigInteger;
+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.Constants;
+import org.eclipse.om2m.commons.constants.MimeMediaType;
+import org.eclipse.om2m.commons.constants.NotificationContentType;
+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.ResultContent;
+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.MgmtObjEntity;
+import org.eclipse.om2m.commons.entities.RemoteCSEEntity;
+import org.eclipse.om2m.commons.entities.ResourceEntity;
+import org.eclipse.om2m.commons.entities.ScheduleEntity;
+import org.eclipse.om2m.commons.entities.SubscriptionEntity;
+import org.eclipse.om2m.commons.exceptions.Om2mException;
+import org.eclipse.om2m.commons.resource.Notification;
+import org.eclipse.om2m.commons.resource.Notification.NotificationEvent;
+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.comm.RestClient;
+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.core.router.Patterns;
+import org.eclipse.om2m.core.router.Router;
+import org.eclipse.om2m.core.thread.CoreExecutor;
+import org.eclipse.om2m.core.urimapper.UriMapper;
+import org.eclipse.om2m.persistence.service.DAO;
+import org.eclipse.om2m.persistence.service.DBService;
+import org.eclipse.om2m.persistence.service.DBTransaction;
+
+/**
+ * Notifies subscribers when a change occurs on a resource according to their subscriptions.
+ */
+public class Notifier {
+ /** Logger */
+ private static Log LOGGER = LogFactory.getLog(Notifier.class);
+
+ /**
+ * Finds all resource subscribers and notifies them.
+ * @param statusCode - Notification status code
+ * @param resource - Notification resource
+ */
+ public static void notify(List<SubscriptionEntity> listSubscription, ResourceEntity resource, int resourceStatus) {
+ if (listSubscription != null){
+ for(SubscriptionEntity sub : listSubscription){
+ NotificationWorker worker = new NotificationWorker(sub, resourceStatus, resource);
+ CoreExecutor.postThread(worker);
+ }
+ }
+ }
+
+ /**
+ * Used in DELETE procedure when a resource is deleted. It notifies the subscribed resource
+ * and the parent resource subscribed entities.
+ * @param listSubs
+ * @param resourceDeleted
+ */
+ public static void notifyDeletion(List<SubscriptionEntity> listSubs, ResourceEntity resourceDeleted){
+ List<SubscriptionEntity> parentSubscriptions = getParentSubscriptions(resourceDeleted);
+ if(parentSubscriptions != null){
+ notify(parentSubscriptions, resourceDeleted, ResourceStatus.CHILD_DELETED);
+ }
+ if(listSubs != null){
+ notify(listSubs, resourceDeleted, ResourceStatus.DELETED);
+ }
+ }
+
+ public static void performVerificationRequest(RequestPrimitive request,
+ SubscriptionEntity subscriptionEntity) {
+ for(String uri : subscriptionEntity.getNotificationURI()){
+ if(!uri.equals(request.getFrom())){
+ Notification notification = new Notification();
+ notification.setCreator(subscriptionEntity.getCreator());
+ notification.setVerificationRequest(true);
+ notification.setSubscriptionReference(subscriptionEntity.getHierarchicalURI());
+ notification.setSubscriptionDeletion(false);
+ RequestPrimitive notifRequest = new RequestPrimitive();
+ notifRequest.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.XML).objToString(notification));
+ notifRequest.setFrom("/" + Constants.CSE_ID);
+ notifRequest.setTo(uri);
+ notifRequest.setOperation(Operation.NOTIFY);
+ notifRequest.setRequestContentType(MimeMediaType.XML);
+ notifRequest.setReturnContentType(MimeMediaType.XML);
+ ResponsePrimitive resp = notify(notifRequest, uri);
+ if(resp.getResponseStatusCode().equals(ResponseStatusCode.TARGET_NOT_REACHABLE)){
+ throw new Om2mException("Error during the verification request",
+ ResponseStatusCode.SUBSCRIPTION_VERIFICATION_INITIATION_FAILED);
+ }
+ if(resp.getResponseStatusCode().equals(ResponseStatusCode.SUBSCRIPTION_CREATOR_HAS_NO_PRIVILEGE)
+ || resp.getResponseStatusCode().equals(ResponseStatusCode.SUBSCRIPTION_HOST_HAS_NO_PRIVILEGE)){
+ throw new Om2mException(resp.getResponseStatusCode());
+ }
+ }
+ }
+ }
+
+ public static ResponsePrimitive notify(RequestPrimitive request, String contact){
+ // Check whether the subscription contact is protocol-dependent or not.
+ LOGGER.info("Sending notify request to: " + contact);
+ if(contact.matches(".*://.*")){
+ // Contact = protocol-dependent -> direct notification using the rest client.
+ request.setTo(contact);
+ return RestClient.sendRequest(request);
+ }else{
+ request.setTargetId(contact);
+ LOGGER.info("Sending notify request...");
+ return new Router().doRequest(request);
+ }
+ }
+
+ /**
+ * Used to retrieve the subscription list of the parent resource
+ * @param resource
+ * @return
+ */
+ private static List<SubscriptionEntity> getParentSubscriptions(
+ ResourceEntity resourceDeleted) {
+ List<SubscriptionEntity> result;
+ // Get parent id
+ String[] ids = resourceDeleted.getHierarchicalURI().split("/");
+ String parentHierarchicalId = resourceDeleted.getHierarchicalURI().replace("/" + ids[ids.length - 1], "");
+ String parentId = UriMapper.getNonHierarchicalUri(parentHierarchicalId);
+ // get parent entity
+ DBService dbs = PersistenceService.getInstance().getDbService();
+
+ DAO<?> dao = Patterns.getDAO(parentId, dbs);
+ DBTransaction transaction = dbs.getDbTransaction();
+ transaction.open();
+ ResourceEntity parentEntity = (ResourceEntity) dao.find(transaction, parentId);
+ // get the sub list from parent
+ switch(parentEntity.getResourceType().intValue()){
+ case ResourceType.ACCESS_CONTROL_POLICY:
+ AccessControlPolicyEntity acp = (AccessControlPolicyEntity) parentEntity;
+ result = acp.getChildSubscriptions();
+ break;
+ case ResourceType.AE:
+ AeEntity ae = (AeEntity) parentEntity;
+ result = ae.getSubscriptions();
+ break;
+ case ResourceType.CONTAINER:
+ ContainerEntity cnt = (ContainerEntity) parentEntity;
+ result = cnt.getSubscriptions();
+ break;
+ case ResourceType.CSE_BASE:
+ CSEBaseEntity csb = (CSEBaseEntity) parentEntity;
+ result = csb.getSubscriptions();
+ break;
+ case ResourceType.GROUP:
+ GroupEntity group = (GroupEntity) parentEntity;
+ result = group.getSubscriptions();
+ break;
+ case ResourceType.REMOTE_CSE:
+ RemoteCSEEntity csr = (RemoteCSEEntity) parentEntity;
+ result = csr.getSubscriptions();
+ break;
+ case ResourceType.SCHEDULE:
+ ScheduleEntity schedule = (ScheduleEntity) parentEntity;
+ result = schedule.getSubscriptions();
+ break;
+ default:
+ result = new ArrayList<SubscriptionEntity>();
+ }
+ transaction.close();
+ return result;
+ }
+
+ /**
+ * Worker that perform the notification task for a subscription
+ *
+ */
+ static class NotificationWorker implements Runnable {
+ /** resource status of the notification */
+ private int resourceStatus;
+ /** the subscription to handle */
+ private SubscriptionEntity sub;
+ /** the resource to be sent */
+ private ResourceEntity resource;
+
+ public NotificationWorker(SubscriptionEntity sub, int resourceStatus, ResourceEntity resource) {
+ this.resourceStatus = resourceStatus;
+ this.sub = sub;
+ this.resource = resource;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ final RequestPrimitive request = new RequestPrimitive();
+ Notification notification = new Notification();
+ NotificationEvent notifEvent = new NotificationEvent();
+ notification.setNotificationEvent(notifEvent);
+
+ // Set attributes of notification object
+ notifEvent.setResourceStatus(BigInteger.valueOf(resourceStatus));
+ notification.setCreator(sub.getCreator());
+
+ // Set request parameters
+ request.setOperation(Operation.NOTIFY);
+ request.setFrom("/" + Constants.CSE_ID);
+
+ if(resourceStatus == ResourceStatus.DELETED){
+ notification.setSubscriptionDeletion(true);
+ } else {
+ notification.setSubscriptionDeletion(false);
+ }
+
+ notification.setSubscriptionReference(sub.getHierarchicalURI());
+
+ // Get the representation of the content
+ Resource serializableResource;
+ EntityMapper mapper ;
+ if (sub.getNotificationContentType() != null){
+ if (resource.getResourceType().equals(ResourceType.MGMT_OBJ)) {
+ mapper = EntityMapperFactory.getMapperForMgmtObj((MgmtObjEntity) resource);
+ } else {
+ mapper = EntityMapperFactory.
+ getMapperFromResourceType(resource.getResourceType().intValue());
+ }
+ if(sub.getNotificationContentType().equals(NotificationContentType.MODIFIED_ATTRIBUTES)){
+ serializableResource = (Resource)mapper.mapEntityToResource(resource, ResultContent.ATTRIBUTES);
+ notification.getNotificationEvent().setRepresentation(serializableResource);
+ request.setRequestContentType(MimeMediaType.XML);
+ } else if(sub.getNotificationContentType().equals(NotificationContentType.WHOLE_RESOURCE)){
+ serializableResource = (Resource) mapper.mapEntityToResource(resource, ResultContent.ATTRIBUTES);
+ notification.getNotificationEvent().setRepresentation(serializableResource);
+ request.setRequestContentType(MimeMediaType.XML);
+ }
+ }
+ // Set the content
+ request.setContent(DataMapperSelector.getDataMapperList().get(MimeMediaType.XML).objToString(notification));
+ // For each notification URI: send the notify request
+ for(final String uri : sub.getNotificationURI()){
+ CoreExecutor.postThread(new Runnable(){
+ public void run() {
+ Notifier.notify(request, uri);
+ };
+ });
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/persistence/PersistenceService.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/persistence/PersistenceService.java
index c9a6f56..a5d9596 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/persistence/PersistenceService.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/persistence/PersistenceService.java
@@ -19,8 +19,6 @@
*******************************************************************************/
package org.eclipse.om2m.core.persistence;
-import java.util.concurrent.Semaphore;
-
import org.eclipse.om2m.persistence.service.DBService;
/**
@@ -30,7 +28,6 @@
public class PersistenceService {
private DBService dbService ;
- private Semaphore dbReady = new Semaphore(0);
private static PersistenceService service = new PersistenceService();
@@ -49,15 +46,4 @@
this.dbService = dbService;
}
- /**
- * @return the dbReady
- */
- public Semaphore getDbReady() {
- return dbReady;
- }
-
- public void resetSemaphoreDb(){
- dbReady = new Semaphore(0);
- }
-
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/redirector/Redirector.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/redirector/Redirector.java
index fbf20a1..fd20c05 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/redirector/Redirector.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/redirector/Redirector.java
@@ -23,6 +23,7 @@
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.constants.CSEType;
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.ResponseStatusCode;
import org.eclipse.om2m.commons.entities.AeEntity;
@@ -76,69 +77,79 @@
DAO<RemoteCSEEntity> dao = dbs.getDAOFactory().getRemoteCSEbyCseIdDAO();
RemoteCSEEntity csrEntity = dao.find(transaction, remoteCseId);
if (csrEntity != null) {
- // test if remote cse is reachable
- if (!csrEntity.isRequestReachability()) {
- throw new Om2mException("Remote Cse is not request reachable",
- ResponseStatusCode.TARGET_NOT_REACHABLE);
- }
- // get Point of Access
- String url = "";
- if (!csrEntity.getPointOfAccess().isEmpty()) {
- boolean done = false;
- int i = 0;
- // iterating on points of access while target are not reachable
- while (!done & i < csrEntity.getPointOfAccess().size()) {
- url = csrEntity.getPointOfAccess().get(i);
- if(!url.endsWith("/")){
- url += "/";
- }
- String cseId = (csrEntity.getRemoteCseId().startsWith("/")?
- csrEntity.getRemoteCseId().replace("/", ""):
- csrEntity.getRemoteCseId());
- if (request.getTargetId().startsWith("/" + cseId)){
- url += "~" + request.getTargetId();
- } else {
- url += request.getTargetId();
- }
- request.setTo(url);
- response = RestClient.sendRequest(request);
- if(!(response.getResponseStatusCode()
- .equals(ResponseStatusCode.TARGET_NOT_REACHABLE))){
- done = true;
- if(i > 0){
- String poa = csrEntity.getPointOfAccess().get(i);
- csrEntity.getPointOfAccess().remove(i);
- csrEntity.getPointOfAccess().add(0, poa);
- dbs.getDAOFactory().getRemoteCSEDAO().update(transaction, csrEntity);
- transaction.commit();
- }
- }
- i++;
- }
- } else {
- // TODO to improve w/ polling channel policy
- throw new Om2mException("The point of access parameter is missing", ResponseStatusCode.TARGET_NOT_REACHABLE);
- }
+ LOGGER.info("RemoteCSE found: " + csrEntity.getRemoteCseId());
+ response = sendRedirectorRequest(request, csrEntity, transaction);
} else {
if (!Constants.CSE_TYPE.equalsIgnoreCase(CSEType.IN)) {
- String url = "http://" + Constants.REMOTE_CSE_IP + ":"
- + Constants.REMOTE_CSE_PORT
- + Constants.REMOTE_CSE_CONTEXT;
- if (Constants.REMOTE_CSE_CONTEXT.length() > 1) {
- url += "/";
- }
- url += request.getTargetId();
- request.setTo(url);
+ LOGGER.info("Unknow CSE, sending request to registrar CSE: " + Constants.REMOTE_CSE_ID);
+ csrEntity = dao.find(transaction, "/" + Constants.REMOTE_CSE_ID);
// transfer the request and get the response
- response = RestClient.sendRequest(request);
+ response =sendRedirectorRequest(request, csrEntity, transaction);
} else {
// case nothing found
- response.setResponseStatusCode(ResponseStatusCode.NOT_FOUND);
+ throw new ResourceNotFoundException("RemoteCse with cseId " + remoteCseId + " has not been found");
}
}
transaction.close();
return response;
}
+
+ private static ResponsePrimitive sendRedirectorRequest(RequestPrimitive request, RemoteCSEEntity csrEntity, DBTransaction transaction){
+ // test if the remoteCse is reachable
+ if (!csrEntity.isRequestReachability()) {
+ throw new Om2mException("Remote Cse is not request reachable",
+ ResponseStatusCode.TARGET_NOT_REACHABLE);
+ }
+ DBService dbs = PersistenceService.getInstance().getDbService();
+ // get Point of Access
+ String url = "";
+ if (!csrEntity.getPointOfAccess().isEmpty()) {
+ boolean done = false;
+ int i = 0;
+ // iterating on points of access while target are not reachable
+ while (!done & i < csrEntity.getPointOfAccess().size()) {
+ url = csrEntity.getPointOfAccess().get(i);
+ // Remove a potential / added at the end of the poa
+ if(url.endsWith("/")){
+ LOGGER.debug("Removing / at the end of poa: " + url);
+ url = url.substring(0, url.length() - 1);
+ }
+
+ if(request.getTo().startsWith("//")){
+ url += request.getTo().replaceFirst("//", "/_/");
+ } else if(request.getTo().startsWith("/")){
+ url += request.getTo().replaceFirst("/", "/~/");
+ } else {
+ url+= "/" + request.getTo();
+ }
+
+ request.setTo(url);
+ ResponsePrimitive response = RestClient.sendRequest(request);
+ if(!(response.getResponseStatusCode()
+ .equals(ResponseStatusCode.TARGET_NOT_REACHABLE))){
+ done = true;
+ if(i > 0){
+ String poa = csrEntity.getPointOfAccess().get(i);
+ csrEntity.getPointOfAccess().remove(i);
+ csrEntity.getPointOfAccess().add(0, poa);
+ dbs.getDAOFactory().getRemoteCSEDAO().update(transaction, csrEntity);
+ transaction.commit();
+ }
+ return response;
+ }
+ i++;
+ }
+ // if we reach this point, there is no poa working
+ ResponsePrimitive response = new ResponsePrimitive(request);
+ response.setResponseStatusCode(ResponseStatusCode.TARGET_NOT_REACHABLE);
+ response.setContent("Target is not reachable");
+ response.setContentType(MimeMediaType.TEXT_PLAIN);
+ return response;
+ } else {
+ // TODO to improve w/ polling channel policy
+ throw new Om2mException("The point of access parameter is missing", ResponseStatusCode.TARGET_NOT_REACHABLE);
+ }
+ }
public static ResponsePrimitive retargetNotify(RequestPrimitive request){
ResponsePrimitive response = new ResponsePrimitive(request);
@@ -151,13 +162,15 @@
dbt.close();
throw new ResourceNotFoundException("AE resource " + request.getTargetId() + " not found.");
}
-
- new AEController().checkACP(ae.getAccessControlPolicies(), request.getFrom(), Operation.NOTIFY);
-
+
+ // FIXME use the correct originator when a notification is generated
+ if(!request.getFrom().equals("/" + Constants.CSE_ID)){
+ new AEController().checkACP(ae.getAccessControlPolicies(), request.getFrom(), Operation.NOTIFY);
+ }
+
// Get point of access
if(ae.getPointOfAccess().isEmpty() || !(ae.isRequestReachable())){
- response.setResponseStatusCode(ResponseStatusCode.TARGET_NOT_REACHABLE);
- response.setErrorMessage("AE has no Point of Access");
+ throw new Om2mException("AE has no point of access", ResponseStatusCode.TARGET_NOT_REACHABLE);
} else {
boolean done = false ;
int i = 0;
@@ -173,7 +186,7 @@
LOGGER.info("Om2m exception caught in Redirector: " + om2mE.getMessage() );
throw om2mE;
} catch (Exception e){
- LOGGER.error("Exception caught in IPE execution");
+ LOGGER.error("Exception caught in IPE execution",e);
throw new Om2mException("IPE Internal Error", e, ResponseStatusCode.INTERNAL_SERVER_ERROR);
}
done = true;
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Patterns.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Patterns.java
index 862c19e..4b14183 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Patterns.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Patterns.java
@@ -38,7 +38,7 @@
private static final String ALL_SHORT_NAMES = ShortName.ACP+"|"+ShortName.AE+"|"+ShortName.CNT+
"|"+ShortName.CIN + "|" + ShortName.REMOTE_CSE + "|" + ShortName.LATEST + "|" + ShortName.OLDEST +
"|" + ShortName.GROUP + "|" + ShortName.FANOUTPOINT + "|" + ShortName.SUB + "|" + ShortName.PCH +
- "|" + ShortName.POLLING_CHANNEL_URI + "|" + ShortName.REQ + "|" + ShortName.NODE;
+ "|" + ShortName.POLLING_CHANNEL_URI + "|" + ShortName.REQ + "|" + ShortName.NODE + "|" + ShortName.ANI + "|" + ShortName.ANDI;
private static final String NON_HIERARCHICAL_ID = "(" + Constants.PREFIX_SEPERATOR +"(\\b\\w+\\b)?)" ;
@@ -59,15 +59,10 @@
/** CseBase resource uri pattern. */
public static final Pattern CSE_BASE_PATTERN= Pattern.compile("/" + Constants.CSE_ID);
- /** Non-hierarchical URI pattern */
- public static final Pattern NON_HIERARCHICAL_PATTERN = Pattern.compile(
- "(" + CSE_BASE_PATTERN + "/(" + ALL_SHORT_NAMES + ")" + Constants.PREFIX_SEPERATOR + ID_STRING + ")|(" + CSE_BASE_PATTERN+ ")"
- );
-
/** AccessControlPolicy uri pattern MAY BE NOT COMPLETE */
public static final Pattern ACP_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.ACP + Constants.PREFIX_SEPERATOR + ID_STRING );
- public static final Pattern AE_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.AE + Constants.PREFIX_SEPERATOR + ID_STRING);
+ public static final Pattern AE_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + "(C|S)" + ID_STRING);
public static final Pattern CONTAINER_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.CNT + Constants.PREFIX_SEPERATOR + ID_STRING);
@@ -91,6 +86,20 @@
public static final Pattern NODE_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.NODE + Constants.PREFIX_SEPERATOR + ID_STRING);
+ public static final Pattern AREA_NW_INFO_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.ANI + Constants.PREFIX_SEPERATOR + ID_STRING);
+
+ public static final Pattern AREA_NWK_DEVICE_INFO_PATTERN = Pattern.compile(CSE_BASE_PATTERN + "/" + ShortName.ANDI + Constants.PREFIX_SEPERATOR + ID_STRING);
+
+ /** Non-hierarchical URI pattern */
+ public static final Pattern NON_HIERARCHICAL_PATTERN = Pattern.compile(
+ "(" + CSE_BASE_PATTERN + "/(" + ALL_SHORT_NAMES + ")" + Constants.PREFIX_SEPERATOR + ID_STRING + ")|(" + CSE_BASE_PATTERN+ ")|" +
+ AE_PATTERN.pattern());
+
+ /** Hierarchical URI Pattern */
+ public static final Pattern HIERARCHICAL_PATTERN = Pattern.compile(
+ CSE_BASE_PATTERN + "(/" + Constants.CSE_NAME + "(/"+ ID_PATTERN +")*)?"
+ );
+
/**
* match uri with a pattern.
* @param pattern - pattern
@@ -143,6 +152,9 @@
if(match(REQUEST_PATTERN, uri)){
return db.getDAOFactory().getRequestEntityDAO();
}
+ if (match(NODE_PATTERN, uri)) {
+ return db.getDAOFactory().getNodeEntityDAO();
+ }
return null;
}
@@ -152,6 +164,6 @@
* @return
*/
public static boolean checkResourceName(String resourceName){
- return (!match(UNAUTHORIZED_NAMES, resourceName) && match(ID_PATTERN, resourceName));
+ return match(ID_PATTERN, resourceName);
}
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Router.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Router.java
index 0bfc16f..44f4f5c 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Router.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/router/Router.java
@@ -20,6 +20,10 @@
package org.eclipse.om2m.core.router;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -32,6 +36,7 @@
import org.eclipse.om2m.commons.constants.ResultContent;
import org.eclipse.om2m.commons.constants.ShortName;
import org.eclipse.om2m.commons.exceptions.BadRequestException;
+import org.eclipse.om2m.commons.exceptions.NotImplementedException;
import org.eclipse.om2m.commons.exceptions.Om2mException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
import org.eclipse.om2m.commons.resource.RequestPrimitive;
@@ -74,9 +79,9 @@
public ResponsePrimitive doRequest(RequestPrimitive request) {
LOGGER.info("Received request in Router: " + request.toString());
ResponsePrimitive response = new ResponsePrimitive(request);
-
+
try{
-
+
// Non blocking request handling
if (request.getResponseTypeInfo() != null
&& request.getResponseTypeInfo().getResponseType() != null){
@@ -86,8 +91,9 @@
return NonBlockingHandler.handle(request);
} else {
response.setResponseStatusCode(ResponseStatusCode.NON_BLOCKING_REQUEST_NOT_SUPPORTED);
- response.setErrorMessage("Non blocking request is not supported");
- return response;
+ response.setContent("Non blocking request is not supported");
+ response.setContentType(MimeMediaType.TEXT_PLAIN);
+ return response;
}
}
}
@@ -95,37 +101,35 @@
// Check if the data type has been set
if (request.getRequestContentType() == null){
request.setRequestContentType(MimeMediaType.XML);
+ LOGGER.info("No Content-Type parameter set, setting to default: " + request.getRequestContentType());
}
if (request.getReturnContentType() == null){
request.setReturnContentType(MimeMediaType.XML);
+ LOGGER.info("No Accept parameter set, setting to default: " + request.getReturnContentType());
}
// Check if the data type requested is supported
if (request.getRequestContentType() != MimeMediaType.OBJ && request.getRequestContentType()!=null){
if (!DataMapperSelector.getDataMapperList().containsKey(request.getRequestContentType())){
- response.setResponseStatusCode(ResponseStatusCode.NOT_IMPLEMENTED);
- response.setErrorMessage(request.getRequestContentType()+" is not supported.");
- return response;
+ throw new NotImplementedException(request.getRequestContentType()+" is not supported.");
}
}
if (request.getReturnContentType() != MimeMediaType.OBJ && request.getReturnContentType()!=null){
if (!DataMapperSelector.getDataMapperList().containsKey(request.getReturnContentType())){
- response.setResponseStatusCode(ResponseStatusCode.NOT_IMPLEMENTED);
- response.setErrorMessage(request.getReturnContentType()+" is not supported.");
- return response;
+ throw new NotImplementedException(request.getReturnContentType()+" is not supported.");
}
}
-
+
// Check if the operation has been provided
if(request.getOperation() == null){
throw new BadRequestException("No Operation provided");
}
-
+
// URI Handling
if(request.getTargetId() == null){
request.setTargetId(request.getTo());
}
-
+
if(request.getTargetId().startsWith("~")){
request.setTargetId(request.getTargetId().substring(1));
}
@@ -135,7 +139,7 @@
String uri = request.getTargetId().substring(2);
String spId = uri.split("/")[0];
if (!spId.equals(Constants.M2M_SP_ID)){
- throw new ResourceNotFoundException("Not the current SP Domain.");
+ throw new ResourceNotFoundException("Not the current SP Domain (" + spId + ")");
} else {
request.setTargetId(uri.replace(spId, ""));
}
@@ -148,14 +152,34 @@
request.setTargetId(request.getTargetId().substring(0,request.getTargetId().length()-1));
}
+ getQueryStringFromTargetId(request);
+
// Redirection case
if (!Patterns.match(Patterns.NON_RETARGETING_PATTERN, request.getTargetId())){
+ LOGGER.info("Request targeting another CSE, forwarding to Redirector: " + request.getTo());
return Redirector.retarget(request);
}
+ LOGGER.info("Request handling in the current CSE: " + request.getTo());
Controller controller = null ;
// Case of hierarchical URI, retrieve the non-hierarchical URI of the resource
- if (!Patterns.match(Patterns.NON_HIERARCHICAL_PATTERN, request.getTargetId())){
+ if (Patterns.match(Patterns.HIERARCHICAL_PATTERN, request.getTargetId())){
+ if(request.getTargetId().contains(Patterns.FANOUT_POINT_MATCH + "/")){
+ int foptIndex = request.getTargetId().indexOf(Patterns.FANOUT_POINT_MATCH);
+ String uri = request.getTargetId().substring(0, foptIndex);
+ String suffix = request.getTargetId()
+ .substring(
+ foptIndex + Patterns.FANOUT_POINT_MATCH.length(),
+ request.getTargetId().length()
+ );
+ controller = new FanOutPointController(suffix);
+ request.setTargetId(uri);
+ LOGGER.info("Fan Out request received: [grp uri: " + uri + ", suffix: " + suffix + "]");
+ } if (request.getTargetId().endsWith(Patterns.FANOUT_POINT_MATCH)) {
+ controller = new FanOutPointController();
+ request.setTargetId(request.getTargetId().replaceAll(Patterns.FANOUT_POINT_MATCH, ""));
+ LOGGER.info("Fan Out request received: [grp uri: " + request.getTargetId()+ "]");
+ }
if(request.getTargetId().endsWith("/" + ShortName.LATEST)){
controller = new LatestOldestController(SortingPolicy.LATEST);
request.setTargetId(request.getTargetId() + "/");
@@ -166,15 +190,12 @@
request.setTargetId(request.getTargetId() + "/");
request.setTargetId(request.getTargetId().replace("/"+ShortName.OLDEST+"/", ""));
}
- if (request.getTargetId().endsWith(Patterns.FANOUT_POINT_MATCH)) {
- controller = new FanOutPointController();
- request.setTargetId(request.getTargetId().replaceAll(Patterns.FANOUT_POINT_MATCH, ""));
- }
String nonHierarchicalUri = UriMapper.getNonHierarchicalUri(request.getTargetId());
if (nonHierarchicalUri == null){
throw new ResourceNotFoundException("Resource not found");
}
request.setTargetId(nonHierarchicalUri);
+ LOGGER.debug("Changing to unstructured uri for routing to: " + request.getTargetId());
}
// Notify case
@@ -198,7 +219,7 @@
}
if (controller!=null){
- LOGGER.info("ResourceController ["+ controller.getClass().getSimpleName()+"]");
+ LOGGER.info("ResourceController to be used ["+ controller.getClass().getSimpleName()+"]");
// Perform the request in the specific controller
response = controller.doRequest(request);
if(request.getResultContent() != null && request.getResultContent().equals(ResultContent.NOTHING)){
@@ -209,20 +230,23 @@
String representation = DataMapperSelector.getDataMapperList().
get(request.getReturnContentType()).objToString(response.getContent());
response.setContent(representation);
+ response.setContentType(request.getReturnContentType());
}
}
} else {
- response.setResponseStatusCode(ResponseStatusCode.BAD_REQUEST);
- response.setErrorMessage("Malformed URI");
+ throw new BadRequestException("Malformed URI");
}
} catch (Om2mException om2mException){
response.setResponseStatusCode(om2mException.getErrorStatusCode());
- response.setErrorMessage(om2mException.getMessage());
- LOGGER.debug("Om2m exception catched in Controller", om2mException);
+ response.setContent(om2mException.getMessage());
+ response.setContentType(MimeMediaType.TEXT_PLAIN);
+ LOGGER.info("OM2M exception caught in Router: " + om2mException.getMessage());
+ LOGGER.debug("OM2M exception caught in Router", om2mException);
} catch(Exception e){
- response.setResponseStatusCode(ResponseStatusCode.INTERNAL_SERVER_ERROR);
- response.setErrorMessage("Router internal error");
LOGGER.error("Router internal error", e);
+ response.setResponseStatusCode(ResponseStatusCode.INTERNAL_SERVER_ERROR);
+ response.setContent("Router internal error");
+ response.setContentType(MimeMediaType.TEXT_PLAIN);
}
LOGGER.info("Response in Router= " + response);
@@ -286,7 +310,7 @@
protected Controller getResourceControllerFromRT(BigInteger resourceType){
// test in case resourceType is null
if (resourceType == null) {
- throw new BadRequestException("Resource type is missing");
+ throw new BadRequestException("Resource type is missing for creation request");
}
// switch case
switch(resourceType.intValue()){
@@ -311,7 +335,43 @@
case ResourceType.POLLING_CHANNEL:
return new PollingChannelController();
default :
- return null;
+ throw new NotImplementedException("ResourceType: " + resourceType + " is not implemented");
}
}
+
+ private static void getQueryStringFromTargetId(RequestPrimitive request){
+ if(request.getTargetId().contains("?")){
+ String query = request.getTargetId().split("\\?")[1];
+ Map<String, List<String>> parameters = new HashMap<String, List<String>>();
+ if (query != null) {
+ String[] pairs = query.split("[&]");
+ for (String pair : pairs) {
+ String[] param = pair.split("[=]");
+
+ String key = null;
+ String value = null;
+ if (param.length > 0) {
+ key = param[0];
+ }
+ if (param.length > 1) {
+ value = param[1];
+ }
+ if (parameters.containsKey(key)) {
+ parameters.get(key).add(value);
+ } else {
+ List<String> values = new ArrayList<String>();
+ values.add(value);
+ parameters.put(key,values);
+ }
+ }
+ }
+ request.getQueryStrings().putAll(parameters);
+ if(request.getTo() == null){
+ request.setTo(request.getTargetId().split("\\?")[0]);
+ request.setTargetId(request.getTo());
+ }
+ }
+
+ }
+
}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/thread/CoreExecutor.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/thread/CoreExecutor.java
new file mode 100644
index 0000000..de56423
--- /dev/null
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/thread/CoreExecutor.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.thread;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.om2m.commons.constants.Constants;
+
+/**
+ * This class provides a management of thread policies. It is initialized using
+ * the Constants.MAX_THREAD_POOL_SIZE and avoid creating too much thread and overload
+ * an instance.
+ *
+ */
+public class CoreExecutor {
+
+ /** Default logger */
+ private static final Log LOGGER = LogFactory.getLog(CoreExecutor.class.getName());
+ /** The ExecutorService with the applied thread policy */
+ private static final ExecutorService threadPool;
+
+ /**
+ * Initialize the threadPool with the specific policy
+ */
+ static {
+ // Use minimum 2 threads
+ int maximumPoolSize = Constants.MAX_THREAD_POOL_SIZE > 2 ? Constants.MAX_THREAD_POOL_SIZE: 2;
+ // Provide 10% of thread kept alive for better performance
+ int corePoolSize = maximumPoolSize / 10;
+ LOGGER.info("Creating thread pool with corePoolSize=" + corePoolSize +
+ " & maximumSize=" + maximumPoolSize);
+ // Keep alive the threads for a minute in the pool
+ threadPool = new ThreadPoolExecutor(
+ corePoolSize, maximumPoolSize,
+ 60L, TimeUnit.SECONDS,
+ new SynchronousQueue<Runnable>()
+ );
+ }
+
+ /**
+ * Submit the operation to the executor service.
+ * It will return a Future<T> object. To access the result of the
+ * operation, use the get() method of the Future<T> object that will
+ * block until the result is not available. Then, it will provide the
+ * result of the operation of type <T>.
+ * @param callable the operation to perform with the specific type
+ * @return the Future<T> object, use the get() method to retrieve the result
+ */
+ public static <T> Future<T> submit(Callable<T> callable){
+ return threadPool.submit(callable);
+ }
+
+ /**
+ * Post the runnable into the executor service.
+ * @param runnable the operation to be performed
+ */
+ public static void postThread(Runnable runnable){
+ threadPool.execute(runnable);
+ }
+
+}
diff --git a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/util/ControllerUtil.java b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/util/ControllerUtil.java
index fef9741..b4081b2 100644
--- a/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/util/ControllerUtil.java
+++ b/org.eclipse.om2m.core/src/main/java/org/eclipse/om2m/core/util/ControllerUtil.java
@@ -26,6 +26,7 @@
import org.eclipse.om2m.commons.entities.AccessControlPolicyEntity;
import org.eclipse.om2m.commons.entities.AnnounceableSubordinateEntity;
import org.eclipse.om2m.commons.entities.ResourceEntity;
+import org.eclipse.om2m.commons.exceptions.BadRequestException;
import org.eclipse.om2m.commons.exceptions.NotPermittedAttrException;
import org.eclipse.om2m.commons.exceptions.Om2mException;
import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
@@ -86,9 +87,6 @@
public static void fillEntityFromGenericResource(Resource resource, ResourceEntity entity)
throws NotPermittedAttrException{
- /*if(resource.getName() != null){
- throw new NotPermittedAttrException("Name is Not Permitted");
- }*/
if(resource.getResourceType() != null){
throw new NotPermittedAttrException("ResourceType is Not Permitted");
}
@@ -122,9 +120,38 @@
}
if(resource.getExpirationTime() != null){
entity.setExpirationTime(resource.getExpirationTime());
+ } else {
+ entity.setExpirationTime(DateUtil.getDefaultExpirationTime());
}
}
}
+
+ public static class UpdateUtil{
+
+ private UpdateUtil(){}
+
+ public static void checkNotPermittedParameters(Resource resource){
+ if(resource.getName() != null){
+ throw new BadRequestException("ResourceName is NP");
+ }
+ if(resource.getResourceType() != null){
+ throw new BadRequestException("ResourceType is NP");
+ }
+ if(resource.getResourceID() != null){
+ throw new BadRequestException("ResourceID is NP");
+ }
+ if(resource.getParentID() != null){
+ throw new BadRequestException("ParentID is NP");
+ }
+ if(resource.getCreationTime() != null){
+ throw new BadRequestException("CreationTime is NP");
+ }
+ if(resource.getLastModifiedTime() != null){
+ throw new BadRequestException("LastModifiedTime is NP");
+ }
+ }
+
+ }
}