Repository: eclipse/leshan
Pull request #640 (2019-01-16 17:54:12)

Add a way to support choose custom Id at client side.
This PR aims to implement one part of needs expressed in #597.

With it, you can choose your instance id at iniatialization
```java
ObjectsInitializer objInitializer = new ObjectsInitializer();
objInitializer.setInstancesForObject(OBJECT_ID, new YourInstanceEnabler(myInstanceId));
```

And you can create your own factory which chooses the id generation :
```java
BaseInstanceEnablerFactory yourInstanceEnablerFactory = new BaseInstanceEnablerFactory() {

    @Override
    public LwM2mInstanceEnabler create() {
        return new YourInstanceEnabler();
    }

    @Override
    protected int getNewInstanceId(Collection<Integer> alreadyUsedIdentifier) {
       // implement your way to choose instance id here.
       return yourId;
    }
};
objInitializer.setFactoryForObject(OBJECT_ID, yourInstanceEnablerFactory);   
```


Patch:
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnabler.java
index a5290c64..70c0280d 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnabler.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnabler.java
@@ -31,6 +31,24 @@ import org.eclipse.leshan.core.response.WriteResponse;
 public class BaseInstanceEnabler implements LwM2mInstanceEnabler {
 
     private List<ResourceChangedListener> listeners = new ArrayList<>();
+    private Integer id = null;
+
+    public BaseInstanceEnabler() {
+    }
+
+    public BaseInstanceEnabler(int id) {
+        setId(id);
+    }
+
+    @Override
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    @Override
+    public Integer getId() {
+        return id;
+    }
 
     @Override
     public void addResourceChangedListener(ResourceChangedListener listener) {
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnablerFactory.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnablerFactory.java
new file mode 100644
index 00000000..65f3a8ac
--- /dev/null
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseInstanceEnablerFactory.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * 
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *    http://www.eclipse.org/org/documents/edl-v10.html.
+ * 
+ * Contributors:
+ *     Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.leshan.client.resource;
+
+import java.util.Collection;
+
+import org.eclipse.leshan.core.model.ObjectModel;
+
+public abstract class BaseInstanceEnablerFactory implements LwM2mInstanceEnablerFactory {
+
+    @Override
+    public LwM2mInstanceEnabler create(ObjectModel model, Integer id, Collection<Integer> alreadyUsedIdentifier) {
+        // generate a new id if needed
+        if (id == null) {
+            id = getNewInstanceId(alreadyUsedIdentifier);
+        }
+
+        // create new instance
+        LwM2mInstanceEnabler instance = create(model);
+
+        // set id if not already done
+        if (instance.getId() == null) {
+            instance.setId(id);
+        } else {
+            // check id is well set
+            if (instance.getId() != id) {
+                throw new IllegalStateException(
+                        String.format("instance id should be %d but was %d", id, instance.getId()));
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * generate a new valid instance id
+     * 
+     * @param alreadyUsedIdentifier a collection of id already used
+     * @return an id which is not contained in <code>alreadyUsedIdentifier</code>
+     */
+    protected int getNewInstanceId(Collection<Integer> alreadyUsedIdentifier) {
+        return generateNewInstanceId(alreadyUsedIdentifier);
+    }
+
+    /**
+     * Create a new instance enabler.
+     * 
+     * @param model of this instance (CAN NOT be null).
+     * @return the new instance enabler
+     */
+    public abstract LwM2mInstanceEnabler create(ObjectModel model);
+
+    public static int generateNewInstanceId(Collection<Integer> alreadyUsedIdentifier) {
+        if (alreadyUsedIdentifier.isEmpty()) {
+            return 0;
+        } else {
+            return java.util.Collections.max(alreadyUsedIdentifier) + 1;
+        }
+    }
+}
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseObjectEnabler.java
index 478d081b..97e361f0 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseObjectEnabler.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/BaseObjectEnabler.java
@@ -89,18 +89,10 @@ public abstract class BaseObjectEnabler implements LwM2mObjectEnabler {
     @Override
     public synchronized CreateResponse create(ServerIdentity identity, CreateRequest request) {
         if (!identity.isSystem()) {
-            // we can not create new instance on single object
-            if (objectModel != null && !objectModel.multiple) {
-                return CreateResponse.methodNotAllowed();
-            }
-
             if (id == LwM2mId.SECURITY) {
                 return CreateResponse.notFound();
             }
         }
-
-        // TODO we could do a validation of request.getObjectInstance() by comparing with resourceSpec information.
-
         return doCreate(request);
     }
 
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java
index 3b5e089e..9bb847b7 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnabler.java
@@ -47,6 +47,19 @@ import org.eclipse.leshan.core.response.WriteResponse;
  */
 public interface LwM2mInstanceEnabler {
 
+    /**
+     * @return the id of this instance.
+     */
+    Integer getId();
+
+    /**
+     * Set this id of this instance. It should be called only by
+     * {@link LwM2mInstanceEnablerFactory#create(ObjectModel, Integer, java.util.Collection)}.
+     * 
+     * @param id this id of this instance.
+     */
+    void setId(int id);
+
     /**
      * Adds a callback handler that gets notified about changes to any of this LWM2M object instance's resources.
      * 
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnablerFactory.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnablerFactory.java
index f78cd073..916ad11d 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnablerFactory.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mInstanceEnablerFactory.java
@@ -15,9 +15,21 @@
  *******************************************************************************/
 package org.eclipse.leshan.client.resource;
 
+import java.util.Collection;
+
 import org.eclipse.leshan.core.model.ObjectModel;
 
 public interface LwM2mInstanceEnablerFactory {
 
-    LwM2mInstanceEnabler create(ObjectModel model);
+    /**
+     * Create a new instance enabler.
+     * 
+     * @param model of this instance (CAN NOT be null).
+     * @param id of this instance or NULL if the id MUST be generated by the factory.
+     * @param alreadyUsedIdentifier a collection of id already in used. The new instance MUST NOT use an id contained in
+     *        this collection. It CAN be NULL if id is NOT NULL.
+     * 
+     * @return the new instance enabler
+     */
+    LwM2mInstanceEnabler create(ObjectModel model, Integer id, Collection<Integer> alreadyUsedIdentifier);
 }
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java
index f29c0d75..5d7d9640 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectEnabler.java
@@ -103,25 +103,36 @@ public class ObjectEnabler extends BaseObjectEnabler {
 
     @Override
     protected CreateResponse doCreate(CreateRequest request) {
-        Integer instanceId = request.getInstanceId();
-        if (instanceId == null) {
-            // the client is in charge to generate the id of the new instance
-            if (instances.isEmpty()) {
+        Integer instanceId = request.getInstanceId(); // instanceId CAN be NULL
+
+        // check instance id is valid
+        if (instanceId != null) {
+            if (instances.containsKey(instanceId)) {
+                return CreateResponse.badRequest("Target already exists");
+            }
+            if (!getObjectModel().multiple && instanceId != 0) {
+                return CreateResponse.badRequest("id must be 0 for single instance");
+            }
+        } else {
+            // default 0 instance id for single instance object
+            if (!getObjectModel().multiple) {
                 instanceId = 0;
-            } else {
-                instanceId = Collections.max(instances.keySet()) + 1;
             }
         }
 
-        LwM2mInstanceEnabler newInstance = instanceFactory.create(getObjectModel());
+        // create the new instance
+        LwM2mInstanceEnabler newInstance = instanceFactory.create(getObjectModel(), instanceId, instances.keySet());
 
+        // add/write resource
         for (LwM2mResource resource : request.getResources()) {
             newInstance.write(resource.getId(), resource);
         }
-        instances.put(instanceId, newInstance);
-        listenInstance(newInstance, instanceId);
 
-        return CreateResponse.success(new LwM2mPath(request.getPath().getObjectId(), instanceId).toString());
+        // add new instance to this object
+        instances.put(newInstance.getId(), newInstance);
+        listenInstance(newInstance, newInstance.getId());
+
+        return CreateResponse.success(new LwM2mPath(request.getPath().getObjectId(), newInstance.getId()).toString());
     }
 
     @Override
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectsInitializer.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectsInitializer.java
index e2e82a88..87960deb 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectsInitializer.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/ObjectsInitializer.java
@@ -29,7 +29,7 @@ import org.eclipse.leshan.util.Validate;
 
 public class ObjectsInitializer {
 
-    protected LwM2mInstanceEnablerFactory defaultFactory = new LwM2mInstanceEnablerFactory() {
+    protected LwM2mInstanceEnablerFactory defaultFactory = new BaseInstanceEnablerFactory() {
         @Override
         public LwM2mInstanceEnabler create(ObjectModel model) {
             SimpleInstanceEnabler simpleInstanceEnabler = new SimpleInstanceEnabler();
@@ -84,8 +84,15 @@ public class ObjectsInitializer {
         Validate.notNull(instances);
         Validate.notEmpty(instances);
 
-        if (instances.length > 1 && !objectModel.multiple)
-            throw new IllegalArgumentException("Cannot set more than one instance for the single Object " + objectId);
+        if (!objectModel.multiple) {
+            if (instances.length > 1)
+                throw new IllegalArgumentException(
+                        "Cannot set more than one instance for the single Object " + objectId);
+            if (instances[0].getId() != null && instances[0].getId() != 0)
+                throw new IllegalArgumentException(String.format(
+                        "Invalid instance id for single object %d : single object instance should have an id equals to 0",
+                        objectId));
+        }
 
         this.instances.put(objectId, instances);
     }
@@ -154,8 +161,13 @@ public class ObjectsInitializer {
     protected ObjectEnabler createNodeEnabler(ObjectModel objectModel) {
         Map<Integer, LwM2mInstanceEnabler> instances = new HashMap<>();
         LwM2mInstanceEnabler[] newInstances = createInstances(objectModel);
-        for (int i = 0; i < newInstances.length; i++) {
-            instances.put(i, newInstances[i]);
+        for (LwM2mInstanceEnabler instance : newInstances) {
+            // set id if not already set
+            if (instance.getId() == null) {
+                int id = BaseInstanceEnablerFactory.generateNewInstanceId(instances.keySet());
+                instance.setId(id);
+            }
+            instances.put(instance.getId(), instance);
         }
         return new ObjectEnabler(objectModel.id, objectModel, instances, getFactoryFor(objectModel),
                 getContentFormat(objectModel.id));
@@ -177,14 +189,14 @@ public class ObjectsInitializer {
             // we create instance from class only for single object
             if (!objectModel.multiple) {
                 LwM2mInstanceEnablerFactory instanceFactory = getFactoryFor(objectModel);
-                newInstances = new LwM2mInstanceEnabler[] { instanceFactory.create(objectModel) };
+                newInstances = new LwM2mInstanceEnabler[] { instanceFactory.create(objectModel, 0, null) };
             }
         }
         return newInstances;
     }
 
     protected LwM2mInstanceEnablerFactory getClassFactory(final Class<? extends LwM2mInstanceEnabler> clazz) {
-        LwM2mInstanceEnablerFactory factory = new LwM2mInstanceEnablerFactory() {
+        LwM2mInstanceEnablerFactory factory = new BaseInstanceEnablerFactory() {
             @Override
             public LwM2mInstanceEnabler create(ObjectModel model) {
                 try {
diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/SimpleInstanceEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/SimpleInstanceEnabler.java
index 54f8c80f..b84a5392 100644
--- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/SimpleInstanceEnabler.java
+++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/SimpleInstanceEnabler.java
@@ -39,6 +39,13 @@ public class SimpleInstanceEnabler extends BaseInstanceEnabler {
     protected Map<Integer, LwM2mResource> resources = new HashMap<>();
     protected ObjectModel objectModel;
 
+    public SimpleInstanceEnabler() {
+    }
+
+    public SimpleInstanceEnabler(int id) {
+        super(id);
+    }
+
     @Override
     public ReadResponse read(int resourceid) {
         if (resources.containsKey(resourceid)) {


Test patch:
diff --git a/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/BaseInstanceEnablerFactoryTest.java b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/BaseInstanceEnablerFactoryTest.java
new file mode 100644
index 00000000..dbffdb64
--- /dev/null
+++ b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/BaseInstanceEnablerFactoryTest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * 
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *    http://www.eclipse.org/org/documents/edl-v10.html.
+ * 
+ * Contributors:
+ *     Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.leshan.client.util;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.leshan.LwM2mId;
+import org.eclipse.leshan.client.resource.BaseInstanceEnablerFactory;
+import org.eclipse.leshan.client.resource.LwM2mInstanceEnabler;
+import org.eclipse.leshan.client.resource.SimpleInstanceEnabler;
+import org.eclipse.leshan.core.model.LwM2mModel;
+import org.eclipse.leshan.core.model.ObjectLoader;
+import org.eclipse.leshan.core.model.ObjectModel;
+import org.junit.Test;
+
+public class BaseInstanceEnablerFactoryTest {
+
+    public static final LwM2mModel model = new LwM2mModel(ObjectLoader.loadDefault());
+    public static List<Integer> emptyList = Collections.emptyList();
+
+    @Test(expected = IllegalStateException.class)
+    public void create_instance_with_unexpected_id() {
+        final int id = 2;
+
+        BaseInstanceEnablerFactory badInstanceEnablerFactory = new BaseInstanceEnablerFactory() {
+
+            @Override
+            public LwM2mInstanceEnabler create(ObjectModel model) {
+                // do no respect the contract and set a bad id;
+                return new SimpleInstanceEnabler(id + 1);
+            }
+        };
+
+        badInstanceEnablerFactory.create(model.getObjectModel(LwM2mId.ACCESS_CONTROL), id, emptyList);
+    }
+
+    @Test
+    public void create_instance() {
+        BaseInstanceEnablerFactory instanceEnablerFactory = new BaseInstanceEnablerFactory() {
+
+            @Override
+            public LwM2mInstanceEnabler create(ObjectModel model) {
+                return new SimpleInstanceEnabler();
+            }
+        };
+
+        List<Integer> alreadyUsedIds = Arrays.asList(2, 3, 5, 6);
+        LwM2mInstanceEnabler instance = instanceEnablerFactory.create(model.getObjectModel(LwM2mId.ACCESS_CONTROL),
+                null, alreadyUsedIds);
+        assertNotNull("instance id is not set", instance.getId());
+        assertFalse("new id must not be already used", alreadyUsedIds.contains(instance.getId()));
+    }
+}
diff --git a/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/LinkFormatHelperTest.java b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/LinkFormatHelperTest.java
index d6f2e5c9..c0128c48 100644
--- a/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/LinkFormatHelperTest.java
+++ b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/LinkFormatHelperTest.java
@@ -24,8 +24,8 @@ import java.util.Map;
 
 import org.eclipse.leshan.Link;
 import org.eclipse.leshan.client.resource.BaseInstanceEnabler;
+import org.eclipse.leshan.client.resource.BaseInstanceEnablerFactory;
 import org.eclipse.leshan.client.resource.LwM2mInstanceEnabler;
-import org.eclipse.leshan.client.resource.LwM2mInstanceEnablerFactory;
 import org.eclipse.leshan.client.resource.LwM2mObjectEnabler;
 import org.eclipse.leshan.client.resource.ObjectEnabler;
 import org.eclipse.leshan.client.resource.SimpleInstanceEnabler;
@@ -122,8 +122,8 @@ public class LinkFormatHelperTest {
         Map<Integer, LwM2mInstanceEnabler> instancesMap = new HashMap<>();
         instancesMap.put(0, new BaseInstanceEnabler());
         instancesMap.put(1, new BaseInstanceEnabler());
-        objectEnablers
-                .add(new ObjectEnabler(6, getVersionedObjectModel(6, "2.0"), instancesMap, null, ContentFormat.DEFAULT));
+        objectEnablers.add(
+                new ObjectEnabler(6, getVersionedObjectModel(6, "2.0"), instancesMap, null, ContentFormat.DEFAULT));
 
         Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null);
         String strLinks = Link.serialize(links);
@@ -136,8 +136,8 @@ public class LinkFormatHelperTest {
         List<LwM2mObjectEnabler> objectEnablers = new ArrayList<>();
 
         Map<Integer, LwM2mInstanceEnabler> instancesMap = new HashMap<>();
-        objectEnablers
-                .add(new ObjectEnabler(6, getVersionedObjectModel(6, "2.0"), instancesMap, null, ContentFormat.DEFAULT));
+        objectEnablers.add(
+                new ObjectEnabler(6, getVersionedObjectModel(6, "2.0"), instancesMap, null, ContentFormat.DEFAULT));
 
         Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null);
         String strLinks = Link.serialize(links);
@@ -172,7 +172,7 @@ public class LinkFormatHelperTest {
      */
     private LwM2mObjectEnabler createObjectEnabler(ObjectModel objectModel) {
         // create factory
-        LwM2mInstanceEnablerFactory factory = new LwM2mInstanceEnablerFactory() {
+        BaseInstanceEnablerFactory factory = new BaseInstanceEnablerFactory() {
             @Override
             public LwM2mInstanceEnabler create(ObjectModel model) {
                 SimpleInstanceEnabler simpleInstanceEnabler = new SimpleInstanceEnabler();
@@ -183,7 +183,9 @@ public class LinkFormatHelperTest {
 
         // create first instance
         Map<Integer, LwM2mInstanceEnabler> instances = new HashMap<>();
-        instances.put(0, factory.create(objectModel));
+        LwM2mInstanceEnabler instance = factory.create(objectModel);
+        instance.setId(0);
+        instances.put(0, instance);
 
         // create objectEnabler
         return new ObjectEnabler(objectModel.id, objectModel, instances, factory, ContentFormat.TLV);
diff --git a/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/ObjectsInitializerTest.java b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/ObjectsInitializerTest.java
new file mode 100644
index 00000000..9d30fc4f
--- /dev/null
+++ b/leshan-client-core/src/test/java/org/eclipse/leshan/client/util/ObjectsInitializerTest.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * 
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *    http://www.eclipse.org/org/documents/edl-v10.html.
+ * 
+ * Contributors:
+ *     Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.leshan.client.util;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.leshan.LwM2mId;
+import org.eclipse.leshan.client.resource.BaseInstanceEnabler;
+import org.eclipse.leshan.client.resource.LwM2mInstanceEnabler;
+import org.eclipse.leshan.client.resource.LwM2mObjectEnabler;
+import org.eclipse.leshan.client.resource.ObjectsInitializer;
+import org.junit.Test;
+
+public class ObjectsInitializerTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void set_single_instance_with_not_0_id() {
+        int bad_id = 10; // single instance should have a 0 id
+
+        ObjectsInitializer objectsInitializer = new ObjectsInitializer();
+        objectsInitializer.setInstancesForObject(LwM2mId.DEVICE, new BaseInstanceEnabler(bad_id));
+    }
+
+    @Test
+    public void set_instances_with_custom_id() {
+        List<Integer> expectedIds = Arrays.asList(10, 20);
+
+        LwM2mInstanceEnabler[] acls = new LwM2mInstanceEnabler[expectedIds.size()];
+        for (int i = 0; i < acls.length; i++) {
+            LwM2mInstanceEnabler dummyACL = new BaseInstanceEnabler(expectedIds.get(i));
+            acls[i] = dummyACL;
+        }
+
+        ObjectsInitializer objectsInitializer = new ObjectsInitializer();
+        objectsInitializer.setInstancesForObject(LwM2mId.ACCESS_CONTROL, acls);
+        LwM2mObjectEnabler AclObject = objectsInitializer.create(LwM2mId.ACCESS_CONTROL);
+
+        List<Integer> availableInstanceIds = AclObject.getAvailableInstanceIds();
+        assertTrue("Bad instance id", availableInstanceIds.containsAll(expectedIds));
+    }
+}
diff --git a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/CreateTest.java b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/CreateTest.java
index acaae87f..a4686544 100644
--- a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/CreateTest.java
+++ b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/CreateTest.java
@@ -185,7 +185,7 @@ public class CreateTest {
                 new CreateRequest(3, new LwM2mResource[] { LwM2mSingleResource.newIntegerResource(3, 123) }));
 
         // verify result
-        assertEquals(ResponseCode.METHOD_NOT_ALLOWED, response.getCode());
+        assertEquals(ResponseCode.BAD_REQUEST, response.getCode());
         assertNotNull(response.getCoapResponse());
         assertThat(response.getCoapResponse(), is(instanceOf(Response.class)));
     }