blob: 4ccc9be00df2b3876335c6f4cc3ce6158ca2060d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2016 Orange.
* 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
*******************************************************************************/
package org.eclipse.om2m.ipe.sdt;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.constants.ResponseStatusCode;
import org.eclipse.om2m.commons.resource.AbstractFlexContainer;
import org.eclipse.om2m.commons.resource.CustomAttribute;
import org.eclipse.om2m.commons.resource.ResponsePrimitive;
import org.eclipse.om2m.commons.resource.flexcontainerspec.FlexContainerFactory;
import org.eclipse.om2m.ipe.sdt.flexcontainerservice.ModuleFlexContainerService;
import org.eclipse.om2m.sdt.Action;
import org.eclipse.om2m.sdt.DataPoint;
import org.eclipse.om2m.sdt.Module;
import org.eclipse.om2m.sdt.Property;
import org.eclipse.om2m.sdt.datapoints.ValuedDataPoint;
import org.eclipse.om2m.sdt.exceptions.AccessException;
import org.eclipse.om2m.sdt.exceptions.DataPointException;
public class SDTModuleAdaptor {
private static Log logger = LogFactory.getLog(SDTModuleAdaptor.class);
private static final String SEP = "/";
private static final String SDT_IPE_SUBSCRIPTION_NAME = "SDT_IPE_SUBSCRIPTION";
private final boolean hasToBeAnnounced;
private final Module module;
private final String parentLocation;
private final String resourceLocation;
private final String announceCseId;
private final Map<String, SDTActionAdaptor> actions;
private ModuleFlexContainerService moduleFlexContainerService;
private ModuleSDTListener moduleSDTListener;
public SDTModuleAdaptor(final Module pModule, final String pParentLocation, final String pAnnounceCseId, final boolean hasToBeAnnounced) {
this.module = pModule;
this.hasToBeAnnounced = hasToBeAnnounced;
this.parentLocation = pParentLocation;
this.resourceLocation = this.parentLocation + SEP + this.module.getName();
this.announceCseId = pAnnounceCseId;
actions = new HashMap<>();
}
/**
* Publish the Module into the SDT tree. A new FlexContainer is created to
* represent the SDT Module. FlexContainer is located under parentLocation.
*
* @return true if the FlexContainer has been successfully published
*/
@SuppressWarnings("unchecked")
public boolean publishModuleIntoOM2MTree() {
logger.info("publishModuleFromOM2MTree(name=" + this.module.getName()
+ ", parentLocation=" + parentLocation + ")");
AbstractFlexContainer flexContainer = FlexContainerFactory.getSpecializationFlexContainer(this.module.getShortDefinitionName());
flexContainer.setName(this.module.getName());
flexContainer.setContainerDefinition(this.module.getDefinition());
flexContainer.setLongName(this.module.getLongDefinitionName());
flexContainer.setShortName(this.module.getShortDefinitionName());
if (hasToBeAnnounced) {
flexContainer.getAnnounceTo().add(SEP + announceCseId);
}
// labels
flexContainer.getLabels().add("name/" + this.module.getName());
flexContainer.getLabels().add("pid/" + this.module.getPid());
flexContainer.getLabels().add("device.id/" + this.module.getOwner().getId());
flexContainer.getLabels().add("device.name/" + this.module.getOwner().getName());
flexContainer.getLabels().add("object.type/module");
flexContainer.getLabels().add("cntDef/" + this.module.getDefinition());
flexContainer.getLabels().add("OTB.CATEGORY/Read");
flexContainer.getLabels().add("OTB.CATEGORY/Write");
flexContainer.getLabels().add("OTB.CATEGORY/Notify");
/// each DataPoint is a custom attribute
for (DataPoint dp : module.getDataPoints()) {
CustomAttribute customAttribute = new CustomAttribute();
String customAttributeName = dp.getShortName();
if (customAttributeName == null) {
customAttributeName = dp.getName();
}
customAttribute.setShortName(customAttributeName);
try {
customAttribute.setValue(((ValuedDataPoint<Object>) dp).toStringValue());
customAttribute.setLongName(dp.getLongName());
customAttribute.setType(dp.getDataType().getTypeChoice().getOneM2MType());
} catch (DataPointException e) {
// how to handle this exception?
// should we stop module publishing step in oneM2M tree ?
// should we continue to publish module in oneM2M tree ?
logger.info("Error reading datapoint " + dp + ": " + e.getMessage());
} catch (AccessException e) {
// how to handle this exception?
// should we stop module publishing step in oneM2M tree ?
// should we continue to publish module in oneM2M tree ?
logger.info("Error accessing datapoint " + dp + ": " + e.getMessage());
} catch (Exception e) {
logger.error("Error in datapoint " + dp, e);
}
logger.info("add DataPoint customAttribute(" + customAttribute + ")");
flexContainer.getCustomAttributes().add(customAttribute);
}
// SDT properties are customAttribute of the module FlexContainer
for (Property sdtProperty : module.getProperties()) {
if (sdtProperty.getType() != null) {
if ((sdtProperty.getValue() == null) && (sdtProperty.isOptional())) {
continue;
}
CustomAttribute caForSdtProperty = new CustomAttribute();
caForSdtProperty.setShortName(sdtProperty.getShortName());
caForSdtProperty.setValue(sdtProperty.getValue());
logger.info("add Property customAttribute(" + caForSdtProperty + ")");
flexContainer.getCustomAttributes().add(caForSdtProperty);
}
}
logger.info("customAttributes: " + flexContainer.getCustomAttributes());
ResponsePrimitive resp = CseUtil.sendCreateFlexContainerRequest(flexContainer,
parentLocation);
if (! resp.getResponseStatusCode().equals(ResponseStatusCode.CREATED)) {
logger.error("publishModuleFromOM2MTree(name=" + this.module.getName()
+ ", parentLocation=" + parentLocation + ") : failed to publish:" + resp.getContent(),
null);
return false;
}
AbstractFlexContainer createdFlexContainer = (AbstractFlexContainer) resp.getContent();
// create a ModuleFlexContainerService
moduleFlexContainerService = new ModuleFlexContainerService(module,
createdFlexContainer.getResourceID());
moduleFlexContainerService.register();
// publish actions
for (Action action : module.getActions()) {
SDTActionAdaptor actionAdaptor = new SDTActionAdaptor(action,
resourceLocation, module, announceCseId, hasToBeAnnounced);
if (actionAdaptor.publishActionIntoOM2MTree()) {
actions.put(action.getName(), actionAdaptor);
} else {
// in case of any error, unpublish all oneM2M resource related to this module
unpublishModuleFromOM2MTree();
return false;
}
}
moduleSDTListener = new ModuleSDTListener(module, resourceLocation);
moduleSDTListener.register();
return true;
}
public void unpublishModuleFromOM2MTree() {
logger.info("unpublishModuleFromOM2MTree(name=" + this.module.getName()
+ ", location=" + resourceLocation + ")");
moduleSDTListener.unregister();
moduleSDTListener = null;
for (SDTActionAdaptor sdtActionAdaptor : actions.values()) {
sdtActionAdaptor.unpublishActionFromOM2MTree();
}
actions.clear();
if (moduleFlexContainerService != null) {
moduleFlexContainerService.unregister();
}
// remove Module FlexContainer
CseUtil.sendDeleteRequest(resourceLocation);
}
}