[ODTN] refactoring of ADVA driver

Change-Id: I99095c09670ca4c6f96b60a6422f4542c78a9eb7
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/OpticalModulationCommand.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/OpticalModulationCommand.java
index 257ea11..625802a 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/OpticalModulationCommand.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/OpticalModulationCommand.java
@@ -59,7 +59,7 @@
     @Completion(OpticalConnectPointCompleter.class)
     private String connectPoint = null;
 
-    @Argument(index = 2, name = "value", description = "example: dp_qpsk, dp_8qam, dp_16qam",
+    @Argument(index = 2, name = "value", description = "example: dp_qpsk, dp_8qam, dp_16qam, dp_16qam_hybrid",
             required = false, multiValued = false)
     private String value = null;
 
@@ -98,9 +98,15 @@
                 long bitRate = 0;
                 if (value.equalsIgnoreCase(ModulationScheme.DP_QPSK.name())) {
                     bitRate = 100;
-                } else {
+                } else if (value.equalsIgnoreCase(ModulationScheme.DP_16QAM.name())) {
                     bitRate = 200;
+                } else if (value.equalsIgnoreCase(ModulationScheme.DP_16QAM_HYBRID.name())) {
+                    bitRate = 300;
+                } else {
+                    print(value + "is not correct setting for modulation");
+                    return;
                 }
+
                 checkNotNull(value);
                 Direction component = Direction.ALL;
                 modulationConfig.setModulationScheme(cp.port(), component, bitRate);
diff --git a/apps/roadm/web/roadm-gui/lib/port/port.component.html b/apps/roadm/web/roadm-gui/lib/port/port.component.html
index 18f8577..ca4cfe9 100644
--- a/apps/roadm/web/roadm-gui/lib/port/port.component.html
+++ b/apps/roadm/web/roadm-gui/lib/port/port.component.html
@@ -111,6 +111,7 @@
                                 <option value="DP_QPSK">DP_QPSK</option>
                                 <option value="DP_16QAM">DP_16QAM</option>
                                 <option value="DP_8QAM">DP_8QAM</option>
+				<option value="DP_16QAM_HYBRID">DP_16QAM_HYBRID</option>
                             </select>
                             <button type="submit">Submit</button>
                         </form>
diff --git a/core/api/src/main/java/org/onosproject/net/ModulationScheme.java b/core/api/src/main/java/org/onosproject/net/ModulationScheme.java
index fe54c44..5001552 100644
--- a/core/api/src/main/java/org/onosproject/net/ModulationScheme.java
+++ b/core/api/src/main/java/org/onosproject/net/ModulationScheme.java
@@ -21,6 +21,7 @@
 
     DP_QPSK,
     DP_8QAM,
-    DP_16QAM
+    DP_16QAM,
+    DP_16QAM_HYBRID
 
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaFlowRuleProgrammable.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaFlowRuleProgrammable.java
index 36690a8..fbfa5d7 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaFlowRuleProgrammable.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaFlowRuleProgrammable.java
@@ -44,9 +44,7 @@
         sb.append(
                     "<components xmlns='http://openconfig.net/yang/platform'>"
                   + "<component>"
-                  + "<config>"
                   + "<name>" + optChannel + "</name>"
-                  + "</config>"
                   + "<optical-channel xmlns='http://openconfig.net/yang/terminal-device'>"
                   + "<config>"
                   + "<frequency>" + (long) freq.asMHz() + "</frequency>"
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaModulationOpenConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaModulationOpenConfig.java
new file mode 100644
index 0000000..db32593
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaModulationOpenConfig.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2019-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.
+ *
+ * This work was partially supported by EC H2020 project METRO-HAUL (761727).
+ */
+package org.onosproject.drivers.odtn;
+
+
+import org.onosproject.net.ModulationScheme;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.onosproject.net.PortNumber;
+import org.onosproject.netconf.DatastoreId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/*
+ * Driver Implementation of the ModulationConfig via openconfig for ADVA  based terminal devices.
+ */
+public class AdvaModulationOpenConfig<T> extends TerminalDeviceModulationConfig<T> {
+
+    public static Logger log = LoggerFactory.getLogger(AdvaModulationOpenConfig.class);
+
+    /**
+     * Construct a rpc target power message.
+     *
+     * @return RPC payload
+     */
+    @Override
+    public DatastoreId getDataStoreId() {
+        return DatastoreId.RUNNING;
+    }
+
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param name for optical channel name
+     * @return RPC payload
+     */
+    @Override
+    public StringBuilder createModulationFilterRequestRpc(String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<name>").append(name).append("</name>");
+        return rpc;
+    }
+
+    /*
+     *
+     * Parse filtering string from port and component.
+     * @param portNumber Port Number
+     * @param component port component (optical-channel)
+     * @param bitRate bitRate in bps
+     * @return filtering string in xml format
+
+     */
+    @Override
+    public String modulationEditConfigRequestRpc(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                                 Object component, long bitRate, String modulation) {
+        if (component != null) {
+            // This is an edit-config operation.
+            String portName = state.ocName(modulationConfig, portNumber); //oc1/0
+            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
+            sb.append("<component>");
+            sb.append("<name>").append(portName).append("</name>");
+            sb.append("<config>");
+            sb.append("<name>").append(portName).append("</name>");
+            sb.append("</config>");
+            sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
+                .append("<config>")
+                .append("<optical-channel-config xmlns=\"http://www.advaoptical.com/openconfig/terminal-device-dev\">")
+                .append("<modulation>")
+                .append(modulation)
+                .append("</modulation>")
+                .append("</optical-channel-config>")
+                .append("</config>")
+                .append("</optical-channel>");
+            sb.append("</component>");
+            sb.append("</components>");
+            return sb.toString();
+        } else {
+            log.error("Cannot process the component {}.", component.getClass());
+            return null;
+        }
+    }
+
+    @Override
+    public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
+        String modulation = null;
+        String editConfig = null;
+        if (bitRate <= BitRate.GBPS_100.value) {
+            modulation = "dp-qpsk";
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        } else if (bitRate == BitRate.GBPS_200.value) { // check if bitrate is greater than 100 Gig
+            modulation = "dp-16qam";
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        } else if (bitRate == BitRate.GBPS_300.value) {
+            modulation = "dp-p-16-16qam-hybrid";
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
+            state.setModulationRpc(port, component, editConfig);
+        }
+    }
+
+    @Override
+    public ModulationScheme modulationSchemeType(String modulationScheme) {
+        /*Used for Internal Testing */
+        //String modulationScheme="DP16QAM";
+        ModulationScheme modulation;
+        if (modulationScheme.equalsIgnoreCase("dp-16qam")) {
+            modulation = ModulationScheme.DP_16QAM;
+        } else if (modulationScheme.equalsIgnoreCase("dp-8-qam")) {
+            modulation = ModulationScheme.DP_8QAM;
+        } else if (modulationScheme.equalsIgnoreCase("dp-p-16-16qam-hybrid")) {
+            modulation = ModulationScheme.DP_16QAM_HYBRID;
+        } else {
+            modulation = ModulationScheme.DP_QPSK;
+        }
+        return modulation;
+    }
+    @Override
+        public Optional<ModulationScheme> getModulation(XMLConfiguration conf) {
+        HierarchicalConfiguration config =
+                        conf.configurationAt("data/components/component/optical-channel/config/optical-channel-config");
+
+                String modulationScheme = String.valueOf(config.getString("modulation"));
+
+        return Optional.of(modulationSchemeType(modulationScheme));
+    }
+
+    /*
+     *
+     * Set the ComponentType to invoke proper methods for different template T.
+     * @param component the component.
+     */
+    void checkState(Object component) {
+        String clsName = component.getClass().getName();
+        switch (clsName) {
+            case "org.onosproject.net.Direction":
+                state = ComponentType.DIRECTION;
+                break;
+            case "org.onosproject.net.OchSignal":
+                state = ComponentType.OCHSIGNAL;
+                break;
+            default:
+                log.error("Cannot parse the component type {}.", clsName);
+                log.error("The component content is {}.", component.toString());
+        }
+
+        state.terminalDevice = this;
+    }
+}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDeviceDiscovery.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDeviceDiscovery.java
index a61efe2..1acf404 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDeviceDiscovery.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDeviceDiscovery.java
@@ -26,6 +26,7 @@
 import org.onosproject.drivers.utilities.XmlConfigParser;
 import org.onosproject.net.ChannelSpacing;
 import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.OchSignal;
@@ -60,7 +61,7 @@
 
 /**
  * Driver Implementation of the DeviceDescrption discovery for OpenConfig
- * terminal devices.
+ * ADVA FSP3000C platform terminal devices.
  *
  */
 public class AdvaTerminalDeviceDiscovery
@@ -147,7 +148,7 @@
                                             Device.Type.TERMINAL_DEVICE,
                                             "ADVA",
                                             "FSP3000C",
-                                            "3.1",
+                                            "4.5.2",
                                             "",
                                             new ChassisId("1"));
     }
@@ -282,6 +283,7 @@
              annotations.putIfAbsent(PORT_TYPE, OdtnPortType.CLIENT.value());
              annotations.putIfAbsent(ONOS_PORT_INDEX, portNum.toString());
              annotations.putIfAbsent(CONNECTION_ID, connectionId);
+             annotations.putIfAbsent(AnnotationKeys.PORT_NAME, description);
 
              builder.withPortNumber(PortNumber.portNumber(portNum));
              builder.type(Type.PACKET);
@@ -300,6 +302,7 @@
              annotations.putIfAbsent(ONOS_PORT_INDEX, portNum.toString());
              annotations.putIfAbsent(CONNECTION_ID, connectionId);
              annotations.put(OdtnDeviceDescriptionDiscovery.OC_NAME, "optch " + description);
+             annotations.putIfAbsent(AnnotationKeys.PORT_NAME, "optch " + description);
 
              OchSignal signalId = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1);
              return OchPortHelper.ochPortDescription(
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDevicePowerConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDevicePowerConfig.java
index 17eaf92..2b4db74 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDevicePowerConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/AdvaTerminalDevicePowerConfig.java
@@ -23,7 +23,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.PowerConfig;
 import org.slf4j.Logger;
-
+import org.onosproject.netconf.DatastoreId;
 import java.util.Optional;
 
 import static org.slf4j.LoggerFactory.getLogger;
@@ -44,18 +44,24 @@
      */
     @Override
     public Optional<Range<Double>> getTargetPowerRange(PortNumber port, Object component) {
-        double targetMin = -30;
-        double targetMax = 1;
+        double targetMin = -6;
+        double targetMax = 4;
         return Optional.of(Range.open(targetMin, targetMax));
     }
 
     @Override
     public Optional<Range<Double>> getInputPowerRange(PortNumber port, Object component) {
-        double targetMin = -30;
-        double targetMax = 1;
+        double targetMin = -6;
+        double targetMax = 4;
         return Optional.of(Range.open(targetMin, targetMax));
     }
 
+    @Override
+      public DatastoreId getDataStoreId() {
+        return DatastoreId.RUNNING;
+    }
+
+
     /**
      * Construct a rpc target power message.
      *
@@ -69,11 +75,9 @@
         rpc.append("<component>");
         if (power != null) {
             // This is an edit-config operation.
-            rpc.append("<config>")
-                    .append("<name>")
+                    rpc.append("<name>")
                     .append(name)
                     .append("</name>")
-                    .append("</config>")
                     .append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
                     .append("<config>")
                     .append("<target-output-power>")
@@ -88,4 +92,5 @@
         }
         return rpc;
     }
+
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
index cdc2a9c..7771419 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
@@ -60,6 +60,7 @@
 
 
     public enum BitRate {
+        GBPS_300(300),       //300 Gbps
         GBPS_200(200),      // 200 Gbps
         GBPS_100(100),        // 100 Gbps
         GBPS_40(40),          // 40 Gbps
diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
index f3a4ba8..7f47295 100644
--- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
+++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
@@ -246,7 +246,7 @@
     <behaviour api="org.onosproject.net.behaviour.PowerConfig"
 	       impl="org.onosproject.drivers.odtn.AdvaTerminalDevicePowerConfig"/>
     <behaviour api="org.onosproject.net.behaviour.ModulationConfig"
-               impl="org.onosproject.drivers.odtn.CassiniModulationOpenConfig"/>
+               impl="org.onosproject.drivers.odtn.AdvaModulationOpenConfig"/>
     </driver>
 
     <driver name="gnmi-openconfig-terminal-device" manufacturer="OpenConfig" hwVersion="Unknown" swVersion="gNMI">