Reorganizing ODTN app structure
- separated code which could be referenced from drivers
Change-Id: Ic2c0ae0507abc626771dfaf7a8fc18b5a715cc30
diff --git a/apps/odtn/api/BUCK b/apps/odtn/api/BUCK
new file mode 100644
index 0000000..c3cdf13
--- /dev/null
+++ b/apps/odtn/api/BUCK
@@ -0,0 +1,34 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//lib:JACKSON',
+ '//lib:onos-yang-model',
+ '//lib:onos-yang-runtime',
+ '//models/tapi:onos-models-tapi',
+ '//models/openconfig:onos-models-openconfig',
+ '//apps/yang:onos-apps-yang',
+]
+
+TEST_DEPS = [
+ '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+ deps = COMPILE_DEPS,
+ test_deps = TEST_DEPS,
+)
+
+APPS = [
+ 'org.onosproject.yang',
+ 'org.onosproject.models.tapi',
+ 'org.onosproject.models.openconfig',
+]
+
+# TODO probably bucklet, etc. should escape title & description
+onos_app (
+ app_name = 'org.onosproject.odtn-api',
+ title = 'ODTN API & Utilities Application',
+ category = 'Traffic Steering',
+ url = 'http://onosproject.org',
+ description = 'ODTN API & Utilities Application',
+ required_apps = APPS,
+)
diff --git a/apps/odtn/api/pom.xml b/apps/odtn/api/pom.xml
new file mode 100644
index 0000000..1d971fc
--- /dev/null
+++ b/apps/odtn/api/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2018 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-apps-odtn</artifactId>
+ <version>1.14.0-SNAPSHOT</version>
+ </parent>
+
+
+ <artifactId>onos-apps-odtn-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>ONOS ODTN API</description>
+ <url>http://onosproject.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <onos.version>${project.version}</onos.version>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-yang-runtime</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-models-tapi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-models-openconfig</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-osgi</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <scope>test</scope>
+ <classifier>tests</classifier>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-scr-srcdescriptor</id>
+ <goals>
+ <goal>scr</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <supportedProjectTypes>
+ <supportedProjectType>bundle</supportedProjectType>
+ <supportedProjectType>war</supportedProjectType>
+ </supportedProjectTypes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>cfg</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>cfg</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>swagger</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>swagger</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>app</id>
+ <phase>package</phase>
+ <goals>
+ <goal>app</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/ConfigurableTransceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/ConfigurableTransceiver.java
new file mode 100644
index 0000000..a94f597
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/ConfigurableTransceiver.java
@@ -0,0 +1,40 @@
+/*
+ * 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.behaviour;
+
+import java.util.List;
+
+import org.onosproject.net.driver.HandlerBehaviour;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Behaviour for Transceiver.
+ */
+@Beta
+public interface ConfigurableTransceiver extends HandlerBehaviour {
+
+ /**
+ * Generate configuration to enable/disable transceiver.
+ *
+ * @param componentName to enable/disable
+ * @param enable or disable
+ * @return XML documents (List to handle configuration with multiple-roots)
+ */
+ // return type and how component get specified are likely to change in future
+ @Beta
+ List<CharSequence> enable(String componentName, boolean enable);
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java
new file mode 100644
index 0000000..e8657ea
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/OdtnDeviceDescriptionDiscovery.java
@@ -0,0 +1,45 @@
+/*
+ * 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.behaviour;
+
+import java.util.List;
+
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.PortDescription;
+
+/**
+ * DeviceDescriptionDiscovery used in ODTN.
+ *
+ * Just declaring certain Annotations will be required.
+ */
+public interface OdtnDeviceDescriptionDiscovery
+ extends DeviceDescriptionDiscovery {
+
+ /**
+ * Annotations key, which stores OpenConfig component name.
+ */
+ String OC_NAME = "oc-name";
+
+ /**
+ * Annotations key, which stores OpenConfig component type.
+ */
+ String OC_TYPE = "oc-type";
+
+ // overriding just to make checkstyle happy
+ @Override
+ List<PortDescription> discoverPortDetails();
+
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java
new file mode 100644
index 0000000..ae14e07
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java
@@ -0,0 +1,47 @@
+/*
+ * 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.behaviour;
+
+import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
+import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
+import static org.onosproject.odtn.utils.YangToolUtil.toResourceData;
+import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
+
+import java.util.List;
+
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.odtn.utils.openconfig.Transceiver;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ResourceId;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Plain OpenConfig based implementation.
+ */
+public class PlainTransceiver extends AbstractHandlerBehaviour
+ implements ConfigurableTransceiver {
+
+ @Override
+ public List<CharSequence> enable(String componentName, boolean enable) {
+ List<DataNode> nodes = Transceiver.enable(componentName, enable);
+
+ ResourceId empty = ResourceId.builder().build();
+ return Lists.transform(nodes,
+ node -> toCharSequence(toXmlCompositeStream(toCompositeData(toResourceData(empty, node)))));
+ }
+
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/package-info.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/package-info.java
new file mode 100644
index 0000000..85c8df6
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * ODTN Behaviours.
+ */
+package org.onosproject.odtn.behaviour;
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/package-info.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/package-info.java
new file mode 100644
index 0000000..4171daf
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * ODTN (Open and Disaggregated Transport Networks).
+ */
+package org.onosproject.odtn;
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java
new file mode 100644
index 0000000..3f097fc
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java
@@ -0,0 +1,310 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.DefaultResourceData;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.DefaultCompositeData;
+import org.onosproject.yang.runtime.DefaultRuntimeContext;
+import org.onosproject.yang.runtime.RuntimeContext;
+import org.onosproject.yang.runtime.YangRuntimeService;
+import org.slf4j.Logger;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.google.common.annotations.Beta;
+import com.google.common.io.CharSource;
+import com.google.common.io.CharStreams;
+
+@Beta
+@Component(immediate = true)
+public class YangToolUtil {
+ private static final Logger log = getLogger(YangToolUtil.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected YangRuntimeService yangRuntimeService;
+ protected static YangRuntimeService yrs;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ModelConverter modelConverter;
+ protected static ModelConverter converter;
+
+ @Activate
+ protected void activate() {
+ yrs = yangRuntimeService;
+ converter = modelConverter;
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Stopped");
+ }
+
+ protected static void initStaticContext() {
+ if (yrs == null) {
+ yrs = DefaultServiceDirectory.getService(YangRuntimeService.class);
+ }
+ if (converter == null) {
+ converter = DefaultServiceDirectory.getService(ModelConverter.class);
+ }
+ }
+
+ /**
+ * Converts XML Document into CharSequence.
+ *
+ * @param xmlInput to convert
+ * @return CharSequence
+ */
+ public static CharSequence toCharSequence(Document xmlInput) {
+ return toCharSequence(xmlInput, true);
+ }
+
+ /**
+ * Converts XML Document into CharSequence.
+ *
+ * @param xmlInput to convert
+ * @param omitXmlDecl or not
+ * @return CharSequence
+ */
+ public static CharSequence toCharSequence(Document xmlInput, boolean omitXmlDecl) {
+ try {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ if (omitXmlDecl) {
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ }
+ StringWriter writer = new StringWriter();
+ transformer.transform(new DOMSource(xmlInput), new StreamResult(writer));
+ return writer.getBuffer();
+ } catch (TransformerException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts JsonNode into CharSequence.
+ *
+ * @param jsonInput to convert
+ * @return CharSequence
+ */
+ public static CharSequence toCharSequence(JsonNode jsonInput) {
+ checkNotNull(jsonInput);
+ ObjectMapper mapper = new ObjectMapper();
+ // TODO following pretty printing option should be removed
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+
+ try {
+ return mapper.writerWithDefaultPrettyPrinter()
+ .writeValueAsString(jsonInput);
+ } catch (JsonProcessingException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts UTF-8 CompositeStream into CharSequence.
+ *
+ * @param utf8Input to convert
+ * @return CharSequence
+ */
+ public static CharSequence toCharSequence(CompositeStream utf8Input) {
+ StringBuilder s = new StringBuilder();
+ try {
+ CharStreams.copy(new InputStreamReader(utf8Input.resourceData(), UTF_8), s);
+ return s;
+ } catch (IOException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts JSON CompositeStream into JsonNode.
+ *
+ * @param jsonInput to convert
+ * @return JsonNode
+ */
+ public static JsonNode toJsonNode(CompositeStream jsonInput) {
+ ObjectMapper mapper = new ObjectMapper();
+ try {
+ return mapper.readTree(jsonInput.resourceData());
+ } catch (IOException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts XML CompositeStream into XML Document.
+ *
+ * @param xmlInput to convert
+ * @return Document
+ */
+ public static Document toDocument(CompositeStream xmlInput) {
+ try {
+ return DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder()
+ .parse(new InputSource(new InputStreamReader(xmlInput.resourceData(), UTF_8)));
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts XML source into XML Document.
+ *
+ * @param xmlInput to convert
+ * @return Document
+ */
+ public static Document toDocument(CharSource xmlInput) {
+ try {
+ return DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder()
+ .parse(new InputSource(xmlInput.openStream()));
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ log.error("Exception thrown", e);
+ return null;
+ }
+ }
+
+ /**
+ * Converts CompositeData into XML CompositeStream.
+ *
+ * @param input CompositeData to convert
+ * @return XML CompositeStream
+ */
+ public static CompositeStream toXmlCompositeStream(CompositeData input) {
+ initStaticContext();
+ RuntimeContext yrtContext = new DefaultRuntimeContext.Builder()
+ .setDataFormat("xml")
+ // Following does not have any effect?
+ //.addAnnotation(XMLNS_XC_ANNOTATION)
+ .build();
+ CompositeStream xml = yrs.encode(input, yrtContext);
+ return xml;
+ }
+
+ /**
+ * Converts CompositeData into JSON CompositeStream.
+ *
+ * @param input CompositeData to convert
+ * @return JSON CompositeStream
+ */
+ public static CompositeStream toJsonCompositeStream(CompositeData input) {
+ initStaticContext();
+ RuntimeContext yrtContext = new DefaultRuntimeContext.Builder()
+ .setDataFormat("JSON")
+ .build();
+ CompositeStream xml = yrs.encode(input, yrtContext);
+ return xml;
+ }
+
+ /**
+ * Converts ResourceData into CompositeData.
+ *
+ * @param input ResourceData to convert
+ * @return CompositeData
+ */
+ public static CompositeData toCompositeData(ResourceData input) {
+ CompositeData.Builder builder =
+ DefaultCompositeData.builder();
+ builder.resourceData(input);
+ // remove, merge, replace, ...
+ //builder.addAnnotatedNodeInfo(info)
+
+ return builder.build();
+ }
+
+ /**
+ * Converts DataNode into ResourceData.
+ *
+ * @param resourceId pointing to parent of {@code dataNode}, YANG-wise.
+ * @param dataNode to convert, must be InnerNode
+ * @return ResourceData
+ */
+ public static ResourceData toResourceData(ResourceId resourceId, DataNode dataNode) {
+ DefaultResourceData.Builder builder = DefaultResourceData.builder();
+ builder.resourceId(checkNotNull(resourceId));
+ if (dataNode instanceof InnerNode) {
+ ((InnerNode) dataNode).childNodes().values().forEach(builder::addDataNode);
+ } else {
+ log.error("Unexpected DataNode encountered {}", dataNode);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Converts ModelObject into a DataNode.
+ *
+ * @param input ModelOject
+ * @return DataNode
+ */
+ public static DataNode toDataNode(ModelObject input) {
+ initStaticContext();
+ ModelObjectData modelData = DefaultModelObjectData.builder()
+ .addModelObject(input)
+ .identifier(null)
+ .build();
+
+ ResourceData rnode = converter.createDataNode(modelData);
+ if (rnode.dataNodes().isEmpty()) {
+ log.error("input did not result in any datanode. {}", input);
+ return null;
+ }
+ return rnode.dataNodes().get(0);
+ }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpticalChannel.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpticalChannel.java
new file mode 100644
index 0000000..2784706
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpticalChannel.java
@@ -0,0 +1,68 @@
+/*
+ * 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.openconfig;
+
+import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.DefaultComponents;
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.Component;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20170708.openconfigterminaldevice.components.component.DefaultAugmentedOcPlatformComponent;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20170708.openconfigterminaldevice.terminalopticalchanneltop.DefaultOpticalChannel;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20170708.openconfigterminaldevice.terminalopticalchanneltop.opticalchannel.Config;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20170708.openconfigterminaldevice.terminalopticalchanneltop.opticalchannel.DefaultConfig;
+import org.onosproject.yang.gen.v1.openconfigtransporttypes.rev20170816.openconfigtransporttypes.FrequencyType;
+import org.onosproject.yang.model.DataNode;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Utility methods dealing with OpenConfig optical-channel.
+ * <p>
+ * Split into classes for the purpose of avoiding "Config" class collisions.
+ */
+@Beta
+public abstract class OpticalChannel {
+
+ public static List<DataNode> preconf(String componentName) {
+
+ DefaultComponents components = new DefaultComponents();
+
+ Component component = PlainPlatform.componentWithName(componentName);
+ components.addToComponent(component);
+
+ // augmented 'component' shim
+ DefaultAugmentedOcPlatformComponent acomponent = new DefaultAugmentedOcPlatformComponent();
+
+ DefaultOpticalChannel channel = new DefaultOpticalChannel();
+
+ Config config = new DefaultConfig();
+ // TODO make these configurable
+ config.frequency(FrequencyType.of(BigInteger.valueOf(191500000)));
+ config.targetOutputPower(BigDecimal.valueOf(0.0));
+
+ channel.config(config);
+ acomponent.opticalChannel(channel);
+ component.addAugmentation(acomponent);
+
+ return ImmutableList.of(toDataNode(components));
+ }
+
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/PlainPlatform.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/PlainPlatform.java
new file mode 100644
index 0000000..0997632
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/PlainPlatform.java
@@ -0,0 +1,45 @@
+/*
+ * 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.openconfig;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.Component;
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.DefaultComponent;
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.component.Config;
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.component.DefaultConfig;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Utility methods dealing with OpenConfig component.
+ * <p>
+ * Split into classes for the purpose of avoiding "Config" class collisions.
+ */
+@Beta
+public abstract class PlainPlatform {
+
+ public static Component componentWithName(String componentName) {
+ checkNotNull(componentName, "componentName cannot be null");
+
+ Component component = new DefaultComponent();
+ component.name(componentName);
+ Config config = new DefaultConfig();
+ config.name(componentName);
+ component.config(config);
+ return component;
+ }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java
new file mode 100644
index 0000000..66ca6cd
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java
@@ -0,0 +1,86 @@
+/*
+ * 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.openconfig;
+
+import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
+
+import java.util.List;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.DefaultComponents;
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.Component;
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.components.component.DefaultAugmentedOcPlatformComponent;
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.porttransceivertop.DefaultTransceiver;
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.porttransceivertop.transceiver.Config;
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.porttransceivertop.transceiver.DefaultConfig;
+import org.onosproject.yang.gen.v1.openconfigtransporttypes.rev20170816.openconfigtransporttypes.Eth100GbaseLr4;
+import org.onosproject.yang.gen.v1.openconfigtransporttypes.rev20170816.openconfigtransporttypes.Qsfp28;
+import org.onosproject.yang.model.DataNode;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Utility methods dealing with OpenConfig transceiver.
+ * <p>
+ * Split into classes for the purpose of avoiding "Config" class collisions.
+ */
+@Beta
+public abstract class Transceiver {
+
+ public static List<DataNode> enable(String componentName, boolean enable) {
+
+ DefaultComponents components = new DefaultComponents();
+
+ Component component = PlainPlatform.componentWithName(componentName);
+ components.addToComponent(component);
+
+ // augmented 'component' shim
+ DefaultAugmentedOcPlatformComponent tcomponent = new DefaultAugmentedOcPlatformComponent();
+
+ DefaultTransceiver transceiver = new DefaultTransceiver();
+
+ Config configt = new DefaultConfig();
+ configt.enabled(enable); // phase 1.0 flag
+ transceiver.config(configt);
+ tcomponent.transceiver(transceiver);
+ component.addAugmentation(tcomponent);
+
+ return ImmutableList.of(toDataNode(components));
+ }
+
+ public static List<DataNode> preconf(String componentName) {
+ DefaultComponents components = new DefaultComponents();
+
+ Component component = PlainPlatform.componentWithName(componentName);
+ components.addToComponent(component);
+
+ // augmented 'component' shim
+ DefaultAugmentedOcPlatformComponent tcomponent = new DefaultAugmentedOcPlatformComponent();
+
+ DefaultTransceiver transceiver = new DefaultTransceiver();
+
+ Config configt = new DefaultConfig();
+ // TODO make these configurable
+ configt.formFactorPreconf(Qsfp28.class);
+ configt.ethernetPmdPreconf(Eth100GbaseLr4.class);
+ transceiver.config(configt);
+ tcomponent.transceiver(transceiver);
+ component.addAugmentation(tcomponent);
+
+ return ImmutableList.of(toDataNode(components));
+ }
+
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/package-info.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/package-info.java
new file mode 100644
index 0000000..3b83083
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * Utilities to deal with onos-yang-tools OpenConfig objects..
+ */
+package org.onosproject.odtn.utils.openconfig;
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/package-info.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/package-info.java
new file mode 100644
index 0000000..4f15f89
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * Utilities developed for ODTN.
+ */
+package org.onosproject.odtn.utils;