ODTN manual testing tool for OpenConfig configuration

- ONOS-7567

Example:
onos> odtn-manual-test ENABLE_TRANSCEIVER
JSON:
{
  "openconfig-platform:component" : [ {
    "name" : "TRANSCEIVER_1_1_4_1",
    "openconfig-platform-transceiver:transceiver" : {
      "config" : {
        "enabled" : "true"
      }
    },
    "config" : {
      "name" : "TRANSCEIVER_1_1_4_1"
    }
  } ]
}
XML:
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
      <component xmlns="http://openconfig.net/yang/platform" xc:operation="merge">
        <name>TRANSCEIVER_1_1_4_1</name>
        <transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
          <config>
            <enabled>true</enabled>
          </config>
        </transceiver>
        <config>
          <name>TRANSCEIVER_1_1_4_1</name>
        </config>
      </component>
    </config>
  </edit-config>
</rpc>

Change-Id: Ief5f1a1933fb00a2118bd941d8c5f0310ed9c815
diff --git a/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/OpticalChannel.java b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/OpticalChannel.java
new file mode 100644
index 0000000..9d813e5
--- /dev/null
+++ b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/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.cli.impl.sub;
+
+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/src/main/java/org/onosproject/odtn/cli/impl/sub/PlainPlatform.java b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/PlainPlatform.java
new file mode 100644
index 0000000..74beaa6
--- /dev/null
+++ b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/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.cli.impl.sub;
+
+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/src/main/java/org/onosproject/odtn/cli/impl/sub/Transceiver.java b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/Transceiver.java
new file mode 100644
index 0000000..9d55408
--- /dev/null
+++ b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/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.cli.impl.sub;
+
+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/src/main/java/org/onosproject/odtn/cli/impl/sub/package-info.java b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/package-info.java
new file mode 100644
index 0000000..ca8433c
--- /dev/null
+++ b/apps/odtn/src/main/java/org/onosproject/odtn/cli/impl/sub/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.
+ */
+/**
+ * sub-package for ODTN related CLI.
+ */
+package org.onosproject.odtn.cli.impl.sub;