blob: f742268d5098d202ad966a5688f8d29721c2dcae [file] [log] [blame]
/*
* Copyright 2018-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.odtn.utils.tapi;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.NotImplementedException;
import org.onlab.util.XmlString;
import org.onosproject.config.DynamicConfigService;
import org.onosproject.config.FailedException;
import org.onosproject.config.Filter;
import org.onosproject.yang.gen.v1.tapicommon.rev20181016.tapicommon.Uuid;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultModelObjectData;
import org.onosproject.yang.model.DefaultResourceData;
import org.onosproject.yang.model.ModelConverter;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ModelObjectId;
import org.onosproject.yang.model.ResourceData;
import static org.onlab.osgi.DefaultServiceDirectory.getService;
import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
import org.onosproject.yang.model.ResourceId;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Utility abstract class to deal with TAPI ModelObject with DCS.
*
* @param <T> modelObject to be dealt with
*/
public abstract class TapiObjectHandler<T extends ModelObject> {
public static final String ONOS_CP = "onos-cp";
public static final String DEVICE_ID = "device-id";
public static final String ODTN_PORT_TYPE = "odtn-port-type";
protected final Logger log = getLogger(getClass());
protected ModelConverter modelConverter;
protected DynamicConfigService dcs;
protected T obj;
/**
* Get modelObject uuid.
*
* @return Uuid
*/
public Uuid getId() {
return getIdDetail();
}
/**
* Generate and set modelObject uuid.
*/
public void setId() {
Uuid uuid = Uuid.of(UUID.randomUUID().toString());
setIdDetail(uuid);
}
/**
* Set modelObject uuid.
*
* @param uuid Uuid
*/
public void setId(Uuid uuid) {
setIdDetail(uuid);
}
/**
* Get modelObject uuid, to be implemented in sub classes.
*
* @return Uuid
*/
protected abstract Uuid getIdDetail();
/**
* Set modelObject uuid, to be implemented in sub classes.
*
* @param uuid Uuid
*/
protected abstract void setIdDetail(Uuid uuid);
/**
* Generate DCS modelObjectId for parent node.
*
* @return ModelObjectId of parent node
*/
public abstract ModelObjectId getParentModelObjectId();
/**
* Get modelObject instance.
*
* @return ModelObject of target node
*/
public T getModelObject() {
return obj;
}
/**
* Set modelObject instance.
*
* @param newObj ModelObject to be set
*/
public void setModelObject(T newObj) {
obj = newObj;
}
/**
* Get modelObjectData instance.
*
* @return ModelObjectData of target node
*/
public ModelObjectData getModelObjectData() {
ModelObject obj = getModelObject();
ModelObjectId objId = getParentModelObjectId();
return DefaultModelObjectData.builder()
.addModelObject(obj)
.identifier(objId)
.build();
}
/**
* Get modelObjectData instance for child node.
* <p>
* This modelObjectData is needed for read / update / delete operation
* to extract ResourceId of this modelObject itself.
* It's just workaround, fix in DCS needed.
*
* @return ModelObjectData of build target
*/
public ModelObjectData getChildModelObjectData() {
throw new NotImplementedException();
}
/**
* Get DataNode instance.
*
* @return DataNode of target node
*/
public DataNode getDataNode() {
ResourceData rData = toResourceData(getModelObjectData());
if (rData.dataNodes().size() > 1) {
throw new IllegalStateException("Multiple dataNode found.");
}
return rData.dataNodes().get(0);
}
/**
* Read modelObject from Dcs store.
*
* @return ModelObject
*/
public T read() {
return readOnDcs();
}
/**
* Add modelObject to Dcs store.
*/
public void add() {
createOnDcs();
}
/**
* Delete modelObject from Dcs store.
*/
public void remove() {
deleteOnDcs();
}
private void dcsSetup() {
dcs = getService(DynamicConfigService.class);
modelConverter = getService(ModelConverter.class);
}
@SuppressWarnings("unchecked")
private T readOnDcs() {
dcsSetup();
ResourceData rData1 = toResourceData(getChildModelObjectData());
ResourceData rData2 = toResourceData(getModelObjectData());
DataNode rNode = dcs.readNode(rData1.resourceId(), Filter.builder().build());
obj = toModelObject(rNode, rData2.resourceId());
return obj;
}
private void createOnDcs() {
dcsSetup();
ResourceData rData = toResourceData(getModelObjectData());
addResourceDataToDcs(rData, rData.resourceId());
}
private void deleteOnDcs() {
dcsSetup();
ResourceData rData = toResourceData(getChildModelObjectData());
dcs.deleteNode(rData.resourceId());
}
private void addResourceDataToDcs(ResourceData input, ResourceId rid) {
if (input == null || input.dataNodes() == null) {
return;
}
List<DataNode> dataNodes = input.dataNodes();
for (DataNode node : dataNodes) {
try {
dcs.createNode(rid, node);
} catch (FailedException e) {
log.warn("Failed to add resource", e);
}
}
}
@SuppressWarnings("unchecked")
protected T toModelObject(DataNode rNode, ResourceId rId) {
dcsSetup();
ResourceData rData = toResourceData(rNode, rId);
ModelObjectData modelObjectData = modelConverter.createModel(rData);
if (modelObjectData.modelObjects().size() > 1) {
throw new IllegalStateException("Multiple modelObject found.");
}
return (T) modelObjectData.modelObjects().get(0);
}
private ResourceData toResourceData(DataNode rNode, ResourceId rId) {
return DefaultResourceData.builder()
.addDataNode(rNode)
.resourceId(rId)
.build();
}
private ResourceData toResourceData(ModelObjectData data) {
dcsSetup();
ResourceData rData = modelConverter.createDataNode(data);
// for debug
CharSequence strNode = toCharSequence(toXmlCompositeStream(toCompositeData(rData)));
log.debug("XML:\n{}", XmlString.prettifyXml(strNode));
return rData;
}
}