HOT FIX: Bug 520517 solve contentInstance creation performance issue
diff --git a/org.eclipse.om2m.commons/src/main/java/org/eclipse/om2m/commons/entities/ContainerEntity.java b/org.eclipse.om2m.commons/src/main/java/org/eclipse/om2m/commons/entities/ContainerEntity.java
index 3ae3e7c..a01a202 100644
--- a/org.eclipse.om2m.commons/src/main/java/org/eclipse/om2m/commons/entities/ContainerEntity.java
+++ b/org.eclipse.om2m.commons/src/main/java/org/eclipse/om2m/commons/entities/ContainerEntity.java
@@ -1,4 +1,5 @@
 /*******************************************************************************
+
  * Copyright (c) 2013-2016 LAAS-CNRS (www.laas.fr)
  * 7 Colonel Roche 31077 Toulouse - France
  *
@@ -53,6 +54,8 @@
 	protected BigInteger maxNrOfInstances;
 	@Column(name= ShortName.MAX_BYTE_SIZE)
 	protected BigInteger maxByteSize;
+	@Column(name= ShortName.CURRENT_NUMBER_OF_INSTANCES)
+	protected BigInteger currentNrOfInstances;
 	@Column(name= ShortName.MAX_INSTANCE_AGE)
 	protected BigInteger maxInstanceAge;
 	@Column(name= ShortName.LOCATION_ID)
@@ -130,6 +133,16 @@
 			inverseJoinColumns={@JoinColumn(name=DBEntities.CSR_JOIN_ID, referencedColumnName=ShortName.RESOURCE_ID)},
 			joinColumns={@JoinColumn(name=DBEntities.CNT_JOIN_ID, referencedColumnName=ShortName.RESOURCE_ID)}
 			)
+	
+	
+	public BigInteger getCurrentNrOfInstances() {
+			return currentNrOfInstances;
+	}
+
+	public void setCurrentNrOfInstances(BigInteger currentNrOfInstances) {
+			this.currentNrOfInstances = currentNrOfInstances;
+	}
+	
 	protected RemoteCSEEntity parentCSR;
 	
 	/**
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 0d4b614..675d746 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
@@ -214,7 +214,8 @@
 		containerEntity.setHierarchicalURI(parentEntity.getHierarchicalURI() + "/" + containerEntity.getName());
 		containerEntity.setParentID(parentEntity.getResourceID());
 		containerEntity.setResourceType(ResourceType.CONTAINER);
-
+		containerEntity.setCurrentNrOfInstances(BigInteger.valueOf(0));
+		
 		// accessControlPolicyIDs	O
 		if (!container.getAccessControlPolicyIDs().isEmpty()){
 			containerEntity.setAccessControlPolicies(
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 45fb3bf..d0936d2 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
@@ -218,25 +218,20 @@
 		// case parent is Container
 		if (parentEntity.getResourceType().intValue() == (ResourceType.CONTAINER)) {
 			ContainerEntity container = (ContainerEntity) parentEntity;
-			List<ContentInstanceEntity> cinList = container.getChildContentInstances();
-			if (container.getMaxNrOfInstances() != null && (cinList.size() == container.getMaxNrOfInstances().intValue())) {
-				LOGGER.info("Deleting oldest content instance due to container size limit: " + 
-						container.getChildContentInstances().get(0).getHierarchicalURI());
-				String hierarchicalUriToDelete = container.getChildContentInstances().get(0).getHierarchicalURI();
-				dbs.getDAOFactory().getContentInstanceDAO().delete(transaction, container.getChildContentInstances().get(0));
-				transaction.commit();
-				transaction.close();
-				UriMapper.deleteUri(hierarchicalUriToDelete);
-				transaction = dbs.getDbTransaction();
-				transaction.open();
-				container = (ContainerEntity)dao.find(transaction, request.getTargetId());
-			}
+					if (container.getMaxNrOfInstances()!= null ){
+						if (container.getCurrentNrOfInstances().intValue() >= container.getMaxNrOfInstances().intValue()) {
+							LOGGER.info("Deleting oldest content instance due to container size limit");
+							dbs.getDAOFactory().getContentInstanceDAO().delete(transaction, dbs.getDAOFactory().getOldestDAO().find(transaction, request.getTargetId()));	
+						}else{
+							container.setCurrentNrOfInstances(BigInteger.valueOf(container.getCurrentNrOfInstances().intValue()+1));
+						}
+					}
 			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)) {
 			//TODO set parent containerAnnc when implemented
@@ -322,6 +317,14 @@
 				request.getFrom(), request.getOperation());		
 
 		UriMapper.deleteUri(cin.getHierarchicalURI());
+		
+		DAO<?> dao = (DAO<?>) Patterns.getDAO(cin.getParentID(), dbs);
+		ResourceEntity parentEntity = (ResourceEntity)dao.find(transaction, cin.getParentID());
+		ContainerEntity container = (ContainerEntity) parentEntity;
+
+		container.setCurrentNrOfInstances(BigInteger.valueOf(container.getCurrentNrOfInstances().intValue()-1));
+		dbs.getDAOFactory().getContainerDAO().update(transaction, container);
+		
 		Notifier.notifyDeletion(null, cin);
 
 		// delete the resource
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 2aa5012..e1738e9 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
@@ -19,12 +19,14 @@
  *******************************************************************************/
 package org.eclipse.om2m.core.controller;
 
+import java.math.BigInteger;
 import java.util.List;
 
 import org.eclipse.om2m.commons.constants.ResponseStatusCode;
 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.entities.ResourceEntity;
 import org.eclipse.om2m.commons.exceptions.OperationNotAllowed;
 import org.eclipse.om2m.commons.exceptions.ResourceNotFoundException;
 import org.eclipse.om2m.commons.resource.ContentInstance;
@@ -32,7 +34,9 @@
 import org.eclipse.om2m.commons.resource.ResponsePrimitive;
 import org.eclipse.om2m.core.entitymapper.EntityMapperFactory;
 import org.eclipse.om2m.core.notifier.Notifier;
+import org.eclipse.om2m.core.router.Patterns;
 import org.eclipse.om2m.core.urimapper.UriMapper;
+import org.eclipse.om2m.persistence.service.DAO;
 
 /**
  * Controller for latest/oldest virtual resources
@@ -82,7 +86,7 @@
 					containerEntity.getChildContentInstances().size()-1);
 			break;
 		case OLDEST:
-			cinEntity = containerEntity.getChildContentInstances().get(0);
+			cinEntity = dbs.getDAOFactory().getOldestDAO().find(transaction, request.getTargetId());
 			break;
 		default:
 			break;
@@ -132,11 +136,21 @@
 			break;
 		}
 		UriMapper.deleteUri(cinEntity.getHierarchicalURI());
-		
+		DAO<?> dao = (DAO<?>) Patterns.getDAO(cinEntity.getParentID(), dbs);
+		ResourceEntity parentEntity = (ResourceEntity)dao.find(transaction, cinEntity.getParentID());
+
+		ContainerEntity container = (ContainerEntity) parentEntity;
+
+		container.setCurrentNrOfInstances(BigInteger.valueOf(container.getCurrentNrOfInstances().intValue()-1));
+
+		dbs.getDAOFactory().getContainerDAO().update(transaction, container);
+
 		Notifier.notifyDeletion(null, cinEntity);
 		
 		dbs.getDAOFactory().getContentInstanceDAO().delete(transaction, cinEntity);
 		transaction.commit();
+		
+		
 		response.setResponseStatusCode(ResponseStatusCode.DELETED);
 		return response;
 	}
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 0401feb..6c5f7a5 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
@@ -44,7 +44,7 @@
 	protected void mapAttributes(ContainerEntity entity, Container resource) {
 		resource.setCreator(entity.getCreator());
 		resource.setCurrentByteSize(BigInteger.valueOf(entity.getCurrentByteSize()));
-		resource.setCurrentNrOfInstances(BigInteger.valueOf(entity.getChildContentInstances().size()));
+		resource.setCurrentNrOfInstances(entity.getCurrentNrOfInstances());
 		resource.setLocationID(entity.getLocationID());
 		resource.setMaxByteSize(entity.getMaxByteSize());
 		resource.setMaxInstanceAge(entity.getMaxInstanceAge());
diff --git a/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/DAOFactoryImpl.java b/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/DAOFactoryImpl.java
index eb7cbf8..f49eace 100644
--- a/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/DAOFactoryImpl.java
+++ b/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/DAOFactoryImpl.java
@@ -48,9 +48,11 @@
 import org.eclipse.om2m.persistence.eclipselink.internal.dao.RequestEntityDAO;
 import org.eclipse.om2m.persistence.eclipselink.internal.dao.SubscriptionDAO;
 import org.eclipse.om2m.persistence.eclipselink.internal.dao.UriMapperDAO;
+import org.eclipse.om2m.persistence.eclipselink.internal.dao.OldestDAO;
 import org.eclipse.om2m.persistence.service.DAO;
 import org.eclipse.om2m.persistence.service.DAOFactory;
 
+
 public class DAOFactoryImpl implements DAOFactory {
 
 	@Override
@@ -128,4 +130,9 @@
 		return new AccessControlOriginatorDAO();
 	}
 	
+	@Override
+	public DAO<ContentInstanceEntity> getOldestDAO() {
+		return new OldestDAO();
+	}
+	
 }
diff --git a/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/dao/OldestDAO.java b/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/dao/OldestDAO.java
new file mode 100644
index 0000000..983b162
--- /dev/null
+++ b/org.eclipse.om2m.persistence.eclipselink/src/main/java/org/eclipse/om2m/persistence/eclipselink/internal/dao/OldestDAO.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Sensinov (www.sensinov.com)
+ * 41 Rue de la découverte 31676 Labège - 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:
+ *     Mahdi Ben Alaya - benalaya@sensinov.com
+ *
+ * New contributors :
+ *******************************************************************************/
+package org.eclipse.om2m.persistence.eclipselink.internal.dao;
+
+import java.util.List;
+
+import javax.persistence.Query;
+
+import org.eclipse.om2m.commons.constants.DBEntities;
+import org.eclipse.om2m.commons.entities.ContentInstanceEntity;
+import org.eclipse.om2m.persistence.eclipselink.internal.DBTransactionJPAImpl;
+import org.eclipse.om2m.persistence.service.DBTransaction;
+
+/**
+ * DAO for the content instance entity
+ *
+ */
+public class OldestDAO extends AbstractDAO<ContentInstanceEntity> {
+
+	@Override
+	public void create(DBTransaction dbTransaction,
+			ContentInstanceEntity resource) {
+		// NOT AVAILABLE
+	}
+	
+	@Override
+	public ContentInstanceEntity find(DBTransaction dbTransaction, Object id) {
+		ContentInstanceEntity result = null;
+
+		DBTransactionJPAImpl transaction = (DBTransactionJPAImpl) dbTransaction;
+		String req = "SELECT r FROM " + DBEntities.CONTENTINSTANCE_ENTITY
+				+ " r WHERE r.parentID = '"+ id + "'";
+		
+		Query q = transaction.getEm().createQuery(req);
+		List<ContentInstanceEntity> resultList = q.setMaxResults(1).getResultList();
+		if (resultList.size() == 1) {
+			result = resultList.get(0);
+		}
+		return result;
+	}
+
+	@Override
+	public void delete(DBTransaction dbTransaction,	ContentInstanceEntity resource) {
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.om2m.persistence.service/src/main/java/org/eclipse/om2m/persistence/service/DAOFactory.java b/org.eclipse.om2m.persistence.service/src/main/java/org/eclipse/om2m/persistence/service/DAOFactory.java
index 0f973d5..103ae7c 100644
--- a/org.eclipse.om2m.persistence.service/src/main/java/org/eclipse/om2m/persistence/service/DAOFactory.java
+++ b/org.eclipse.om2m.persistence.service/src/main/java/org/eclipse/om2m/persistence/service/DAOFactory.java
@@ -69,4 +69,6 @@
 
 	public abstract DAO<AccessControlOriginatorEntity> getAccessControlOriginatorDAO();
 	
+	public abstract DAO<ContentInstanceEntity> getOldestDAO();
+	
 }
\ No newline at end of file
diff --git a/org.eclipse.om2m.site.asn-cse/om2m.product b/org.eclipse.om2m.site.asn-cse/om2m.product
index 8e2aed7..81900e7 100644
--- a/org.eclipse.om2m.site.asn-cse/om2m.product
+++ b/org.eclipse.om2m.site.asn-cse/om2m.product
@@ -91,7 +91,7 @@
       <property name="org.eclipse.om2m.dbDriver" value="org.h2.Driver" />
       <property name="org.eclipse.om2m.dbPassword" value="om2m" />
       <property name="org.eclipse.om2m.dbReset" value="false" />
-      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/asndb" />
+      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/asndb;MULTI_THREADED=1" />
       <property name="org.eclipse.om2m.dbUser" value="om2m" />
       <property name="org.eclipse.om2m.globalContext" value="" />
       <property name="org.eclipse.om2m.guestRequestingEntity" value="guest:guest" />
diff --git a/org.eclipse.om2m.site.in-cse/om2m.product b/org.eclipse.om2m.site.in-cse/om2m.product
index 47305cb..502e1a0 100644
--- a/org.eclipse.om2m.site.in-cse/om2m.product
+++ b/org.eclipse.om2m.site.in-cse/om2m.product
@@ -93,7 +93,7 @@
       <property name="org.eclipse.om2m.dbDriver" value="org.h2.Driver" />
       <property name="org.eclipse.om2m.dbPassword" value="om2m" />
       <property name="org.eclipse.om2m.dbReset" value="false" />
-      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/indb" />
+      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/indb;MULTI_THREADED=1" />
       <property name="org.eclipse.om2m.dbUser" value="om2m" />
       <property name="org.eclipse.om2m.globalContext" value="" />
       <property name="org.eclipse.om2m.guestRequestingEntity" value="guest:guest" />
diff --git a/org.eclipse.om2m.site.mn-cse/om2m.product b/org.eclipse.om2m.site.mn-cse/om2m.product
index 3b8723b..b219aff 100644
--- a/org.eclipse.om2m.site.mn-cse/om2m.product
+++ b/org.eclipse.om2m.site.mn-cse/om2m.product
@@ -88,7 +88,7 @@
       <property name="org.eclipse.om2m.dbDriver" value="org.h2.Driver" />
       <property name="org.eclipse.om2m.dbPassword" value="om2m" />
       <property name="org.eclipse.om2m.dbReset" value="false" />
-      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/mndb" />
+      <property name="org.eclipse.om2m.dbUrl" value="jdbc:h2:./database/mndb;MULTI_THREADED=1" />
       <property name="org.eclipse.om2m.dbUser" value="om2m" />
       <property name="org.eclipse.om2m.globalContext" value="" />
       <property name="org.eclipse.om2m.guestRequestingEntity" value="guest:guest" />