diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClient.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClient.java index f0a5cca1d9..ecdf87fbc4 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClient.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClient.java @@ -47,6 +47,7 @@ import org.eclipse.leshan.client.send.DataSenderManager; import org.eclipse.leshan.client.send.SendService; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.link.LinkSerializer; import org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributeParser; import org.eclipse.leshan.core.node.LwM2mNode; @@ -84,14 +85,14 @@ public LeshanClient(String endpoint, List objectEn List dataSenders, List trustStore, RegistrationEngineFactory engineFactory, BootstrapConsistencyChecker checker, Map additionalAttributes, Map bsAdditionalAttributes, LwM2mEncoder encoder, LwM2mDecoder decoder, - ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, + ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, LinkFormatHelper linkFormatHelper, LwM2mAttributeParser attributeParser, LwM2mClientEndpointsProvider endpointsProvider) { Validate.notNull(endpoint); Validate.notEmpty(objectEnablers); Validate.notNull(checker); - objectTree = createObjectTree(objectEnablers); + objectTree = createObjectTree(objectEnablers, linkFormatHelper); List errors = checker.checkconfig(objectTree.getObjectEnablers()); if (errors != null) { throw new IllegalArgumentException( @@ -101,7 +102,7 @@ public LeshanClient(String endpoint, List objectEn this.endpointsProvider = endpointsProvider; rootEnabler = createRootEnabler(objectTree); observers = createClientObserverDispatcher(); - bootstrapHandler = createBoostrapHandler(objectTree, checker); + bootstrapHandler = createBoostrapHandler(objectTree, checker, linkFormatHelper); ClientEndpointToolbox toolbox = new ClientEndpointToolbox(decoder, encoder, linkSerializer, objectTree.getModel(), attributeParser); @@ -111,11 +112,11 @@ public LeshanClient(String endpoint, List objectEn engine = engineFactory.createRegistratioEngine(endpoint, objectTree, endpointsManager, requestSender, bootstrapHandler, observers, additionalAttributes, bsAdditionalAttributes, - getSupportedContentFormat(decoder, encoder), sharedExecutor); + getSupportedContentFormat(decoder, encoder), sharedExecutor, linkFormatHelper); DownlinkRequestReceiver requestReceiver = createRequestReceiver(bootstrapHandler, rootEnabler, objectTree, engine); - createRegistrationUpdateHandler(engine, endpointsManager, bootstrapHandler, objectTree); + createRegistrationUpdateHandler(engine, endpointsManager, bootstrapHandler, objectTree, linkFormatHelper); endpointsProvider.init(objectTree, requestReceiver, toolbox); } @@ -124,8 +125,9 @@ protected LwM2mRootEnabler createRootEnabler(LwM2mObjectTree tree) { return new RootEnabler(tree); } - protected LwM2mObjectTree createObjectTree(List objectEnablers) { - return new LwM2mObjectTree(this, objectEnablers); + protected LwM2mObjectTree createObjectTree(List objectEnablers, + LinkFormatHelper linkFormatHelper) { + return new LwM2mObjectTree(this, linkFormatHelper, objectEnablers); } protected DataSenderManager createDataSenderManager(List dataSenders, LwM2mRootEnabler rootEnabler, @@ -148,8 +150,9 @@ public void onUnexpectedError(Throwable unexpectedError) { return observer; } - protected BootstrapHandler createBoostrapHandler(LwM2mObjectTree objectTree, BootstrapConsistencyChecker checker) { - return new BootstrapHandler(objectTree.getObjectEnablers(), checker); + protected BootstrapHandler createBoostrapHandler(LwM2mObjectTree objectTree, BootstrapConsistencyChecker checker, + LinkFormatHelper linkFormatHelper) { + return new BootstrapHandler(objectTree.getObjectEnablers(), checker, linkFormatHelper); } protected DownlinkRequestReceiver createRequestReceiver(BootstrapHandler bootstrapHandler, @@ -167,8 +170,10 @@ protected UplinkRequestSender createRequestSender(LwM2mClientEndpointsProvider e } protected RegistrationUpdateHandler createRegistrationUpdateHandler(RegistrationEngine engine, - EndpointsManager endpointsManager, BootstrapHandler bootstrapHandler, LwM2mObjectTree objectTree) { - RegistrationUpdateHandler registrationUpdateHandler = new RegistrationUpdateHandler(engine, bootstrapHandler); + EndpointsManager endpointsManager, BootstrapHandler bootstrapHandler, LwM2mObjectTree objectTree, + LinkFormatHelper linkFormatHelper) { + RegistrationUpdateHandler registrationUpdateHandler = new RegistrationUpdateHandler(engine, bootstrapHandler, + linkFormatHelper); registrationUpdateHandler.listen(objectTree); return registrationUpdateHandler; } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java index 7926e31680..7c01f5df6f 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/LeshanClientBuilder.java @@ -36,6 +36,8 @@ import org.eclipse.leshan.client.resource.LwM2mObjectEnabler; import org.eclipse.leshan.client.resource.ObjectsInitializer; import org.eclipse.leshan.client.send.DataSender; +import org.eclipse.leshan.client.util.LinkFormatHelper; +import org.eclipse.leshan.core.LwM2m.LwM2mVersion; import org.eclipse.leshan.core.LwM2mId; import org.eclipse.leshan.core.link.DefaultLinkSerializer; import org.eclipse.leshan.core.link.LinkSerializer; @@ -79,6 +81,8 @@ public class LeshanClientBuilder { private LwM2mClientEndpointsProvider endpointsProvider; + private LinkFormatHelper linkFormatHelper; + /** * Creates a new instance for setting the configuration options for a {@link LeshanClient} instance. * @@ -168,6 +172,14 @@ public LeshanClientBuilder setLinkSerializer(LinkSerializer linkSerializer) { return this; } + /** + * Set the Link Format Helper. + */ + public LeshanClientBuilder setLinkFormatHelper(LinkFormatHelper linkFormatHelper) { + this.linkFormatHelper = linkFormatHelper; + return this; + } + /** * Set the {@link LwM2mAttributeParser} used to parse {@link LwM2mAttribute} from {@link WriteAttributesRequest}. *

@@ -282,6 +294,8 @@ public LeshanClient build() { decoder = new DefaultLwM2mDecoder(); if (linkSerializer == null) linkSerializer = new DefaultLinkSerializer(); + if (linkFormatHelper == null) + linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_1); if (attributeParser == null) attributeParser = new DefaultLwM2mAttributeParser(); if (engineFactory == null) { @@ -293,7 +307,7 @@ public LeshanClient build() { return createLeshanClient(endpoint, objectEnablers, dataSenders, this.trustStore, engineFactory, bootstrapConsistencyChecker, additionalAttributes, bsAdditionalAttributes, encoder, decoder, executor, - linkSerializer, attributeParser, endpointsProvider); + linkSerializer, linkFormatHelper, attributeParser, endpointsProvider); } /** @@ -315,6 +329,7 @@ public LeshanClient build() { * @param decoder used to decode response payload. * @param sharedExecutor an optional shared executor. * @param linkSerializer a serializer {@link LinkSerializer} used to serialize a CoRE Link. + * @param linkFormatHelper a helper used to create Link Object from ObjectTree. * @param attributeParser a {@link LwM2mAttributeParser} used to parse {@link LwM2mAttribute} from * {@link WriteAttributesRequest}. * @@ -324,10 +339,10 @@ protected LeshanClient createLeshanClient(String endpoint, List dataSenders, List trustStore, RegistrationEngineFactory engineFactory, BootstrapConsistencyChecker checker, Map additionalAttributes, Map bsAdditionalAttributes, LwM2mEncoder encoder, LwM2mDecoder decoder, - ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, + ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, LinkFormatHelper linkFormatHelper, LwM2mAttributeParser attributeParser, LwM2mClientEndpointsProvider endpointsProvider) { return new LeshanClient(endpoint, objectEnablers, dataSenders, trustStore, engineFactory, checker, additionalAttributes, bsAdditionalAttributes, encoder, decoder, sharedExecutor, linkSerializer, - attributeParser, endpointsProvider); + linkFormatHelper, attributeParser, endpointsProvider); } } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/RegistrationUpdateHandler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/RegistrationUpdateHandler.java index 73c5303863..a327f57c17 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/RegistrationUpdateHandler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/RegistrationUpdateHandler.java @@ -37,10 +37,13 @@ public class RegistrationUpdateHandler { private final RegistrationEngine engine; private final BootstrapHandler bsHandler; + private final LinkFormatHelper linkFormatHelper; - public RegistrationUpdateHandler(RegistrationEngine engine, BootstrapHandler bsHandler) { + public RegistrationUpdateHandler(RegistrationEngine engine, BootstrapHandler bsHandler, + LinkFormatHelper linkFormatHelper) { this.engine = engine; this.bsHandler = bsHandler; + this.linkFormatHelper = linkFormatHelper; } public void listen(final LwM2mObjectTree objecTree) { @@ -49,28 +52,28 @@ public void listen(final LwM2mObjectTree objecTree) { public void objectInstancesRemoved(LwM2mObjectEnabler object, int... instanceIds) { if (!bsHandler.isBootstrapping()) engine.triggerRegistrationUpdate(new RegistrationUpdate( - LinkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); + linkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); } @Override public void objectInstancesAdded(LwM2mObjectEnabler object, int... instanceIds) { if (!bsHandler.isBootstrapping()) engine.triggerRegistrationUpdate(new RegistrationUpdate( - LinkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); + linkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); } @Override public void objectRemoved(LwM2mObjectEnabler object) { if (!bsHandler.isBootstrapping()) engine.triggerRegistrationUpdate(new RegistrationUpdate( - LinkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); + linkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); } @Override public void objectAdded(LwM2mObjectEnabler object) { if (!bsHandler.isBootstrapping()) engine.triggerRegistrationUpdate(new RegistrationUpdate( - LinkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); + linkFormatHelper.getClientDescription(objecTree.getObjectEnablers().values(), null, null))); } @Override diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/bootstrap/BootstrapHandler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/bootstrap/BootstrapHandler.java index 29492bbc04..d778641dab 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/bootstrap/BootstrapHandler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/bootstrap/BootstrapHandler.java @@ -46,11 +46,14 @@ public class BootstrapHandler { private volatile List lastConsistencyError = null; private final Map objects; - private BootstrapConsistencyChecker checker; + private final BootstrapConsistencyChecker checker; + private final LinkFormatHelper linkFormatHelper; - public BootstrapHandler(Map objectEnablers, BootstrapConsistencyChecker checker) { + public BootstrapHandler(Map objectEnablers, BootstrapConsistencyChecker checker, + LinkFormatHelper linkFormatHelper) { objects = objectEnablers; this.checker = checker; + this.linkFormatHelper = linkFormatHelper; } public synchronized SendableResponse finished(ServerIdentity server, @@ -143,7 +146,7 @@ public BootstrapDiscoverResponse discover(ServerIdentity identity, BootstrapDisc LwM2mPath path = request.getPath(); if (path.isRoot()) { // Manage discover on object - LwM2mLink[] ObjectLinks = LinkFormatHelper.getBootstrapClientDescription(objects.values()); + LwM2mLink[] ObjectLinks = linkFormatHelper.getBootstrapClientDescription(objects.values()); return BootstrapDiscoverResponse.success(ObjectLinks); } return BootstrapDiscoverResponse.badRequest("invalid path"); diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java index c6a91a21b3..1adfde4e54 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java @@ -118,6 +118,7 @@ private static enum Status { private final BootstrapHandler bootstrapHandler; private final EndpointsManager endpointsManager; private final LwM2mClientObserver observer; + private final LinkFormatHelper linkFormatHelper; // tasks stuff private boolean started = false; @@ -134,11 +135,13 @@ public DefaultRegistrationEngine(String endpoint, LwM2mObjectTree objectTree, En ScheduledExecutorService executor, long requestTimeoutInMs, long deregistrationTimeoutInMs, int bootstrapSessionTimeoutInSec, int retryWaitingTimeInMs, Integer communicationPeriodInMs, boolean reconnectOnUpdate, boolean resumeOnConnect, boolean useQueueMode, - ContentFormat preferredContentFormat, Set supportedContentFormats) { + ContentFormat preferredContentFormat, Set supportedContentFormats, + LinkFormatHelper linkFormatHelper) { this.endpoint = endpoint; this.objectEnablers = objectTree.getObjectEnablers(); this.bootstrapHandler = bootstrapState; this.endpointsManager = endpointsManager; + this.linkFormatHelper = linkFormatHelper; this.observer = observer; this.additionalAttributes = additionalAttributes; this.bsAdditionalAttributes = bsAdditionalAttributes; @@ -317,7 +320,7 @@ private Status register(ServerIdentity server) throws InterruptedException { LwM2mVersion lwM2mVersion = LwM2mVersion.lastSupported(); EnumSet supportedBindingMode = ServersInfoExtractor .getDeviceSupportedBindingMode(objectEnablers.get(LwM2mId.DEVICE), 0); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers.values(), null, + Link[] links = linkFormatHelper.getClientDescription(objectEnablers.values(), null, ContentFormat.getOptionalContentFormatForClient(supportedContentFormats, lwM2mVersion)); request = new RegisterRequest(endpoint, dmInfo.lifetime, lwM2mVersion.toString(), supportedBindingMode, diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngineFactory.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngineFactory.java index a441626518..7e1f4864c5 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngineFactory.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngineFactory.java @@ -24,6 +24,7 @@ import org.eclipse.leshan.client.observer.LwM2mClientObserver; import org.eclipse.leshan.client.request.UplinkRequestSender; import org.eclipse.leshan.client.resource.LwM2mObjectTree; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.request.ContentFormat; /** @@ -51,11 +52,12 @@ public RegistrationEngine createRegistratioEngine(String endpoint, LwM2mObjectTr EndpointsManager endpointsManager, UplinkRequestSender requestSender, BootstrapHandler bootstrapState, LwM2mClientObserver observer, Map additionalAttributes, Map bsAdditionalAttributes, Set supportedContentFormat, - ScheduledExecutorService sharedExecutor) { + ScheduledExecutorService sharedExecutor, LinkFormatHelper linkFormatHelper) { return new DefaultRegistrationEngine(endpoint, objectTree, endpointsManager, requestSender, bootstrapState, observer, additionalAttributes, bsAdditionalAttributes, sharedExecutor, requestTimeoutInMs, deregistrationTimeoutInMs, bootstrapSessionTimeoutInSec, retryWaitingTimeInMs, communicationPeriodInMs, - reconnectOnUpdate, resumeOnConnect, queueMode, preferredContentFormat, supportedContentFormat); + reconnectOnUpdate, resumeOnConnect, queueMode, preferredContentFormat, supportedContentFormat, + linkFormatHelper); } /** diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/RegistrationEngineFactory.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/RegistrationEngineFactory.java index 2f54163e19..7807b492ce 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/RegistrationEngineFactory.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/RegistrationEngineFactory.java @@ -24,6 +24,7 @@ import org.eclipse.leshan.client.observer.LwM2mClientObserver; import org.eclipse.leshan.client.request.UplinkRequestSender; import org.eclipse.leshan.client.resource.LwM2mObjectTree; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.request.ContentFormat; /** @@ -35,5 +36,5 @@ RegistrationEngine createRegistratioEngine(String endpoint, LwM2mObjectTree obje EndpointsManager endpointsManager, UplinkRequestSender requestSender, BootstrapHandler bootstrapState, LwM2mClientObserver observer, Map additionalAttributes, Map bsAdditionalAttributes, Set supportedContentFormat, - ScheduledExecutorService sharedExecutor); + ScheduledExecutorService sharedExecutor, LinkFormatHelper linkFormatHelper); } 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 8dca123245..1db5ae7e9e 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 @@ -77,12 +77,12 @@ public abstract class BaseObjectEnabler implements LwM2mObjectEnabler { protected final ObjectModel objectModel; private LwM2mClient lwm2mClient; + private LinkFormatHelper linkFormatHelper; public BaseObjectEnabler(int id, ObjectModel objectModel) { this.id = id; this.objectModel = objectModel; this.transactionalListener = createTransactionListener(); - } protected TransactionalObjectListener createTransactionListener() { @@ -396,7 +396,7 @@ protected DiscoverResponse doDiscover(ServerIdentity identity, DiscoverRequest r LwM2mPath path = request.getPath(); if (path.isObject()) { // Manage discover on object - LwM2mLink[] ObjectLinks = LinkFormatHelper.getObjectDescription(this, null); + LwM2mLink[] ObjectLinks = linkFormatHelper.getObjectDescription(this, null); return DiscoverResponse.success(ObjectLinks); } else if (path.isObjectInstance()) { @@ -404,7 +404,7 @@ protected DiscoverResponse doDiscover(ServerIdentity identity, DiscoverRequest r if (!getAvailableInstanceIds().contains(path.getObjectInstanceId())) return DiscoverResponse.notFound(); - LwM2mLink[] instanceLink = LinkFormatHelper.getInstanceDescription(this, path.getObjectInstanceId(), null); + LwM2mLink[] instanceLink = linkFormatHelper.getInstanceDescription(this, path.getObjectInstanceId(), null); return DiscoverResponse.success(instanceLink); } else if (path.isResource()) { @@ -419,7 +419,7 @@ protected DiscoverResponse doDiscover(ServerIdentity identity, DiscoverRequest r if (!getAvailableResourceIds(path.getObjectInstanceId()).contains(path.getResourceId())) return DiscoverResponse.notFound(); - LwM2mLink resourceLink = LinkFormatHelper.getResourceDescription(this, path.getObjectInstanceId(), + LwM2mLink resourceLink = linkFormatHelper.getResourceDescription(this, path.getObjectInstanceId(), path.getResourceId(), null); return DiscoverResponse.success(new LwM2mLink[] { resourceLink }); } @@ -441,7 +441,7 @@ protected BootstrapDiscoverResponse doDiscover(ServerIdentity identity, Bootstra LwM2mPath path = request.getPath(); if (path.isObject()) { // Manage discover on object - LwM2mLink[] ObjectLinks = LinkFormatHelper.getBootstrapObjectDescription(this); + LwM2mLink[] ObjectLinks = linkFormatHelper.getBootstrapObjectDescription(this); return BootstrapDiscoverResponse.success(ObjectLinks); } return BootstrapDiscoverResponse.badRequest("invalid path"); @@ -518,8 +518,9 @@ public synchronized void endTransaction(byte level) { } @Override - public void setLwM2mClient(LwM2mClient client) { + public void init(LwM2mClient client, LinkFormatHelper linkFormatHelper) { this.lwm2mClient = client; + this.linkFormatHelper = linkFormatHelper; } public LwM2mClient getLwm2mClient() { diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java index 9ca4fa9aa9..0eeb23cb0f 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectEnabler.java @@ -21,6 +21,7 @@ import org.eclipse.leshan.client.LwM2mClient; import org.eclipse.leshan.client.resource.listener.ObjectListener; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.Startable; import org.eclipse.leshan.core.Stoppable; @@ -105,7 +106,7 @@ public interface LwM2mObjectEnabler { void removeListener(ObjectListener listener); - void setLwM2mClient(LwM2mClient client); + void init(LwM2mClient client, LinkFormatHelper linkFormatHelper); void beginTransaction(byte level); diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java index 69ff58c9cc..aaeb371364 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/resource/LwM2mObjectTree.java @@ -25,6 +25,7 @@ import org.eclipse.leshan.client.LwM2mClient; import org.eclipse.leshan.client.resource.listener.ObjectListener; import org.eclipse.leshan.client.resource.listener.ObjectsListener; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.Startable; import org.eclipse.leshan.core.Stoppable; @@ -46,11 +47,12 @@ public class LwM2mObjectTree implements Startable, Stoppable, Destroyable { protected final ConcurrentHashMap objectEnablers = new ConcurrentHashMap<>(); protected final LwM2mModel model; - public LwM2mObjectTree(LwM2mClient client, LwM2mObjectEnabler... enablers) { - this(client, Arrays.asList(enablers)); + public LwM2mObjectTree(LwM2mClient client, LinkFormatHelper linkFormatHelper, LwM2mObjectEnabler... enablers) { + this(client, linkFormatHelper, Arrays.asList(enablers)); } - public LwM2mObjectTree(LwM2mClient client, Collection enablers) { + public LwM2mObjectTree(LwM2mClient client, LinkFormatHelper linkFormatHelper, + Collection enablers) { for (LwM2mObjectEnabler enabler : enablers) { LwM2mObjectEnabler previousEnabler = objectEnablers.putIfAbsent(enabler.getId(), enabler); if (previousEnabler != null) { @@ -60,7 +62,7 @@ public LwM2mObjectTree(LwM2mClient client, Collection request) { } @Override - public void setLwM2mClient(LwM2mClient client) { - super.setLwM2mClient(client); + public void init(LwM2mClient client, LinkFormatHelper linkFormatHelper) { + super.init(client, linkFormatHelper); for (LwM2mInstanceEnabler instanceEnabler : instances.values()) { instanceEnabler.setLwM2mClient(client); } diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/util/LinkFormatHelper.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/util/LinkFormatHelper.java index 756dc9f650..f07d38454c 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/util/LinkFormatHelper.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/util/LinkFormatHelper.java @@ -39,6 +39,7 @@ import org.eclipse.leshan.core.link.lwm2m.MixedLwM2mLink; import org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttribute; import org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributes; +import org.eclipse.leshan.core.model.LwM2mCoreObjectVersionRegistry; import org.eclipse.leshan.core.model.LwM2mModel; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.node.LwM2mObject; @@ -53,12 +54,16 @@ * An Utility class which help to generate @{link Link} from {@link LwM2mObjectEnabler} and {@link LwM2mModel}.
* Used for register and discover payload. */ -public final class LinkFormatHelper { +public class LinkFormatHelper { - private LinkFormatHelper() { + protected LwM2mCoreObjectVersionRegistry versionRegistry = new LwM2mCoreObjectVersionRegistry(); + protected LwM2mVersion version; + + public LinkFormatHelper(LwM2mVersion version) { + this.version = version; } - public static Link[] getClientDescription(Collection objectEnablers, String rootPath, + public Link[] getClientDescription(Collection objectEnablers, String rootPath, List supportedContentFormats) { List links = new ArrayList<>(); @@ -99,7 +104,7 @@ public int compare(LwM2mObjectEnabler o1, LwM2mObjectEnabler o2) { return links.toArray(new Link[] {}); } - public static LwM2mLink[] getBootstrapClientDescription(Collection objectEnablers) { + public LwM2mLink[] getBootstrapClientDescription(Collection objectEnablers) { List links = new ArrayList<>(); // TODO should be version 1.1 ? links.add(new LwM2mLink("/", LwM2mPath.ROOTPATH, @@ -115,7 +120,7 @@ public static LwM2mLink[] getBootstrapClientDescription(Collection>> extractOscoreAttributes( + private Map>> extractOscoreAttributes( Collection objectEnablers) { Map>> oscoreAttributes = new HashMap<>(); for (LwM2mObjectEnabler objectEnabler : objectEnablers) { @@ -147,7 +152,7 @@ private static Map>> extractOscoreAttributes( return oscoreAttributes; } - public static LwM2mLink[] getObjectDescription(LwM2mObjectEnabler objectEnabler, String rootPath) { + public LwM2mLink[] getObjectDescription(LwM2mObjectEnabler objectEnabler, String rootPath) { List links = new ArrayList<>(); // create link for "object" @@ -162,7 +167,7 @@ public static LwM2mLink[] getObjectDescription(LwM2mObjectEnabler objectEnabler, return links.toArray(new LwM2mLink[links.size()]); } - public static LwM2mLink[] getBootstrapObjectDescription(LwM2mObjectEnabler objectEnabler) { + public LwM2mLink[] getBootstrapObjectDescription(LwM2mObjectEnabler objectEnabler) { List links = new ArrayList<>(); links.add(new LwM2mLink("/", LwM2mPath.ROOTPATH, // TODO should be version 1.1 ? @@ -173,7 +178,7 @@ public static LwM2mLink[] getBootstrapObjectDescription(LwM2mObjectEnabler objec return links.toArray(new LwM2mLink[] {}); } - private static List getBootstrapObjectDescriptionWithoutRoot(LwM2mObjectEnabler objectEnabler, + protected List getBootstrapObjectDescriptionWithoutRoot(LwM2mObjectEnabler objectEnabler, Map>> oscoreAttributesByInstanceId) { List links = new ArrayList<>(); @@ -233,8 +238,7 @@ private static List getBootstrapObjectDescriptionWithoutRoot(LwM2mObj return links; } - public static LwM2mLink[] getInstanceDescription(LwM2mObjectEnabler objectEnabler, int instanceId, - String rootPath) { + public LwM2mLink[] getInstanceDescription(LwM2mObjectEnabler objectEnabler, int instanceId, String rootPath) { List links = new ArrayList<>(); // create link for "instance" @@ -247,13 +251,13 @@ public static LwM2mLink[] getInstanceDescription(LwM2mObjectEnabler objectEnable return links.toArray(new LwM2mLink[links.size()]); } - public static LwM2mLink getResourceDescription(LwM2mObjectEnabler objectEnabler, int instanceId, int resourceId, + public LwM2mLink getResourceDescription(LwM2mObjectEnabler objectEnabler, int instanceId, int resourceId, String rootPath) { // create link for "resource" return new LwM2mLink(rootPath, new LwM2mPath(objectEnabler.getId(), instanceId, resourceId)); } - private static List> getObjectAttributes(ObjectModel objectModel) { + protected List> getObjectAttributes(ObjectModel objectModel) { Version version = getVersion(objectModel); if (version == null) { return null; @@ -264,7 +268,7 @@ private static List> getObjectAttributes(ObjectModel objectMod return attributes; } - private static Version getVersion(ObjectModel objectModel) { + protected Version getVersion(ObjectModel objectModel) { if (StringUtils.isEmpty(objectModel.version) || ObjectModel.DEFAULT_VERSION.equals(objectModel.version)) { return null; } 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 62ac00031e..1e79b524ea 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 @@ -59,7 +59,8 @@ public class LinkFormatHelperTest { public void encode_objectModel_to_linkObject_without_root_path() { ObjectModel locationModel = getObjectModel(6); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), null); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), null); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(",,,,,,,,", strLinks); @@ -69,7 +70,8 @@ public void encode_objectModel_to_linkObject_without_root_path() { public void encode_objectModel_to_linkObject_with_simple_root_path() { ObjectModel locationModel = getObjectModel(6); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/rp"); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/rp"); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals( @@ -81,7 +83,8 @@ public void encode_objectModel_to_linkObject_with_simple_root_path() { public void encode_objectModel_to_linkObject_with_empty_root_path() { ObjectModel locationModel = getObjectModel(6); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), ""); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), ""); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(",,,,,,,,", strLinks); @@ -91,7 +94,8 @@ public void encode_objectModel_to_linkObject_with_empty_root_path() { public void encode_objectModel_to_linkObject_with_explicit_empty_root_path() { ObjectModel locationModel = getObjectModel(6); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/"); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/"); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(",,,,,,,,", strLinks); @@ -101,7 +105,8 @@ public void encode_objectModel_to_linkObject_with_explicit_empty_root_path() { public void encode_objectModel_to_linkObject_with_version2_0() { ObjectModel locationModel = getVersionedObjectModel(6, "2.0"); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/"); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/"); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";ver=2.0,,,,,,,,", strLinks); @@ -111,7 +116,8 @@ public void encode_objectModel_to_linkObject_with_version2_0() { public void encode_objectModel_to_linkObject_with_explicit_complex_root_path() { ObjectModel locationModel = getObjectModel(6); - Link[] links = LinkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/r/t"); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getObjectDescription(createObjectEnabler(locationModel), "/r/t"); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals( @@ -127,7 +133,8 @@ public void encode_client_description_with_version_1_0() { instancesMap.put(0, new BaseInstanceEnabler()); objectEnablers.add(createObjectEnabler(getObjectModel(6), instancesMap)); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null, null); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getClientDescription(objectEnablers, null, null); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";rt=\"oma.lwm2m\",", strLinks); @@ -142,7 +149,8 @@ public void encode_client_description_with_version_2_0() { instancesMap.put(1, new BaseInstanceEnabler()); objectEnablers.add(createObjectEnabler(getVersionedObjectModel(6, "2.0"), instancesMap)); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null, null); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getClientDescription(objectEnablers, null, null); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";rt=\"oma.lwm2m\",;ver=2.0,,", strLinks); @@ -155,7 +163,8 @@ public void encode_client_description_with_version_2_0_no_instances() { Map instancesMap = new HashMap<>(); objectEnablers.add(createObjectEnabler(getVersionedObjectModel(6, "2.0"), instancesMap)); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null, null); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getClientDescription(objectEnablers, null, null); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";rt=\"oma.lwm2m\",;ver=2.0", strLinks); @@ -167,7 +176,8 @@ public void encode_1_content_format() throws LinkParseException { Map instancesMap = Collections.emptyMap(); objectEnablers.add(createObjectEnabler(getVersionedObjectModel(6, "1.0"), instancesMap)); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null, Arrays.asList(ContentFormat.TLV)); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getClientDescription(objectEnablers, null, Arrays.asList(ContentFormat.TLV)); assertArrayEquals(parser.parseCoreLinkFormat(";rt=\"oma.lwm2m\";ct=11542,".getBytes()), links); } @@ -178,7 +188,8 @@ public void encode_several_content_format() throws LinkParseException { Map instancesMap = Collections.emptyMap(); objectEnablers.add(createObjectEnabler(getVersionedObjectModel(6, "1.0"), instancesMap)); - Link[] links = LinkFormatHelper.getClientDescription(objectEnablers, null, + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getClientDescription(objectEnablers, null, Arrays.asList(ContentFormat.TLV, ContentFormat.JSON, ContentFormat.OPAQUE)); assertArrayEquals(parser.parseCoreLinkFormat(";rt=\"oma.lwm2m\";ct=\"11542 11543 42\",".getBytes()), @@ -191,7 +202,8 @@ public void encode_bootstrap_object() { instancesMap.put(0, new BaseInstanceEnabler()); LwM2mObjectEnabler objectEnabler = createObjectEnabler(getObjectModel(3), instancesMap); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,", strLinks); @@ -202,7 +214,8 @@ public void encode_bootstrap_object_with_version_and_no_instance() { Map instancesMap = new HashMap<>(); LwM2mObjectEnabler objectEnabler = createObjectEnabler(getVersionedObjectModel(3, "2.0"), instancesMap); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,;ver=2.0", strLinks); @@ -214,7 +227,8 @@ public void encode_bootstrap_object_with_version_and_instance() { instancesMap.put(0, new BaseInstanceEnabler()); LwM2mObjectEnabler objectEnabler = createObjectEnabler(getVersionedObjectModel(3, "2.0"), instancesMap); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,;ver=2.0,", strLinks); @@ -226,7 +240,8 @@ public void encode_bootstrap_server_object() { instancesMap.put(0, new Server(333, 120)); LwM2mObjectEnabler objectEnabler = createObjectEnabler(getObjectModel(1), instancesMap); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,;ssid=333", strLinks); @@ -238,7 +253,8 @@ public void encode_bootstrap_server_object_with_version() { instancesMap.put(0, new Server(333, 120)); LwM2mObjectEnabler objectEnabler = createObjectEnabler(getVersionedObjectModel(1, "2.0"), instancesMap); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,;ver=2.0,;ssid=333", strLinks); @@ -254,7 +270,8 @@ public void encode_bootstrap_security_object() { LwM2mObjectEnabler objectEnabler = new ObjectEnabler(0, getObjectModel(0), instancesMap, null, ContentFormat.DEFAULT); - Link[] links = LinkFormatHelper.getBootstrapObjectDescription(objectEnabler); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapObjectDescription(objectEnabler); String strLinks = serializer.serializeCoreLinkFormat(links); assertEquals(";lwm2m=1.0,;ssid=111;uri=\"coap://localhost:11\"," // @@ -296,7 +313,8 @@ public void encode_bootstrap_root() { LwM2mObjectEnabler deviceObjectEnabler = createObjectEnabler(getObjectModel(3), deviceInstances); objectEnablers.add(deviceObjectEnabler); - Link[] links = LinkFormatHelper.getBootstrapClientDescription(objectEnablers); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapClientDescription(objectEnablers); String strLinks = serializer.serializeCoreLinkFormat(links); // TODO : handle version correctly @@ -341,7 +359,8 @@ public void encode_bootstrap_root_with_oscore() { LwM2mObjectEnabler oscoreObjectEnabler = createObjectEnabler(getObjectModel(21, "2.0"), oscoreInstances); objectEnablers.add(oscoreObjectEnabler); - Link[] links = LinkFormatHelper.getBootstrapClientDescription(objectEnablers); + LinkFormatHelper linkFormatHelper = new LinkFormatHelper(LwM2mVersion.V1_0); + Link[] links = linkFormatHelper.getBootstrapClientDescription(objectEnablers); String strLinks = serializer.serializeCoreLinkFormat(links); // TODO : handle version correctly diff --git a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClient.java b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClient.java index 4cad4a0224..3510527e55 100644 --- a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClient.java +++ b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClient.java @@ -42,6 +42,7 @@ import org.eclipse.leshan.client.resource.LwM2mObjectEnabler; import org.eclipse.leshan.client.send.DataSender; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.link.LinkSerializer; import org.eclipse.leshan.core.link.lwm2m.attributes.LwM2mAttributeParser; import org.eclipse.leshan.core.node.codec.LwM2mDecoder; @@ -61,11 +62,11 @@ public LeshanTestClient(String endpoint, List obje List dataSenders, List trustStore, RegistrationEngineFactory engineFactory, BootstrapConsistencyChecker checker, Map additionalAttributes, Map bsAdditionalAttributes, LwM2mEncoder encoder, LwM2mDecoder decoder, - ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, + ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, LinkFormatHelper linkFormatHelper, LwM2mAttributeParser attributeParser, LwM2mClientEndpointsProvider endpointsProvider) { super(endpoint, objectEnablers, dataSenders, trustStore, engineFactory, checker, additionalAttributes, - bsAdditionalAttributes, encoder, decoder, sharedExecutor, linkSerializer, attributeParser, - endpointsProvider); + bsAdditionalAttributes, encoder, decoder, sharedExecutor, linkSerializer, linkFormatHelper, + attributeParser, endpointsProvider); // Store some internal attribute this.endpointName = endpoint; diff --git a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java index 699e2cd9d2..3a00298a79 100644 --- a/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java +++ b/leshan-integration-tests/src/test/java/org/eclipse/leshan/integration/tests/util/LeshanTestClientBuilder.java @@ -58,6 +58,7 @@ import org.eclipse.leshan.client.send.DataSender; import org.eclipse.leshan.client.send.ManualDataSender; import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.client.util.LinkFormatHelper; import org.eclipse.leshan.core.CertificateUsage; import org.eclipse.leshan.core.LwM2mId; import org.eclipse.leshan.core.endpoint.Protocol; @@ -219,7 +220,7 @@ protected LeshanTestClient createLeshanClient(String endpoint, List dataSenders, List trustStore, RegistrationEngineFactory engineFactory, BootstrapConsistencyChecker checker, Map additionalAttributes, Map bsAdditionalAttributes, LwM2mEncoder encoder, LwM2mDecoder decoder, - ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, + ScheduledExecutorService sharedExecutor, LinkSerializer linkSerializer, LinkFormatHelper linkFormatHelper, LwM2mAttributeParser attributeParser, LwM2mClientEndpointsProvider endpointsProvider) { String endpointName; if (this.endpointName != null) { @@ -233,7 +234,7 @@ protected LeshanTestClient createLeshanClient(String endpoint, List