Add channel parameter to optical connectivity intent (ONOS-6670)

Change-Id: I3d61e28b82f845db025d21cc65e9240b6ee2b6cc
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/AddOpticalIntentCommand.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/AddOpticalIntentCommand.java
index 939493b..d26cfef 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/AddOpticalIntentCommand.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/cli/AddOpticalIntentCommand.java
@@ -18,13 +18,17 @@
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.apache.karaf.shell.commands.Option;
+import org.onlab.util.Spectrum;
 import org.onosproject.cli.app.AllApplicationNamesCompleter;
 import org.onosproject.cli.net.ConnectPointCompleter;
 import org.onosproject.cli.net.ConnectivityIntentCommand;
+import org.onosproject.net.ChannelSpacing;
 import org.onosproject.net.CltSignalType;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.GridType;
+import org.onosproject.net.OchSignal;
 import org.onosproject.net.OduSignalType;
 import org.onosproject.net.Port;
 import org.onosproject.net.device.DeviceService;
@@ -72,6 +76,12 @@
             required = false, multiValued = false)
     private boolean bidirectional = false;
 
+    @Option(name = "-c", aliases = "--channel",
+            description = "Optical channel in GHz to use for the intent (e.g., 193.1). " +
+            "Uses 50 GHz spaced DWDM channel plan by default.",
+            required = false, multiValued = false)
+    private Double channel;
+
 
     private ConnectPoint createConnectPoint(String devicePortString) {
         String[] splitted = devicePortString.split("/");
@@ -93,6 +103,16 @@
         return null;
     }
 
+    private OchSignal createOchSignal(Double channel) {
+        if (channel == null) {
+            return null;
+        }
+
+        ChannelSpacing spacing = ChannelSpacing.CHL_50GHZ;
+        int multiplier = (int) (Math.round(channel - Spectrum.CENTER_FREQUENCY.asHz() / spacing.frequency().asHz()));
+        return new OchSignal(GridType.DWDM, spacing, multiplier, 4);
+    }
+
     @Override
     protected void execute() {
         IntentService service = get(IntentService.class);
@@ -155,6 +175,7 @@
                     .dst(egress)
                     .signalType(signalType)
                     .bidirectional(bidirectional)
+                    .ochSignal(createOchSignal(channel))
                     .build();
         } else {
             print("Unable to create optical intent between connect points %s and %s", ingress, egress);
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 2609cf4..cbf670f 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -133,7 +133,7 @@
         Stream<Path> paths = getOpticalPaths(intent);
         Optional<Map.Entry<Path, List<OchSignal>>> found = paths
                 .map(path ->
-                        Maps.immutableEntry(path, findFirstAvailableLambda(path)))
+                        Maps.immutableEntry(path, findFirstAvailableLambda(intent, path)))
                 .filter(entry -> !entry.getValue().isEmpty())
                 .filter(entry -> convertToResources(entry.getKey(),
                         entry.getValue()).stream().allMatch(resourceService::isAvailable))
@@ -220,7 +220,11 @@
      * @param path the path
      * @return list of consecutive and available OChSignals
      */
-    private List<OchSignal> findFirstAvailableLambda(Path path) {
+    private List<OchSignal> findFirstAvailableLambda(OpticalConnectivityIntent intent, Path path) {
+        if (intent.ochSignal().isPresent()) {
+            return Collections.singletonList(intent.ochSignal().get());
+        }
+
         Set<OchSignal> lambdas = findCommonLambdas(path);
         if (lambdas.isEmpty()) {
             return Collections.emptyList();
diff --git a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
index 73a37cb..a3d0b9f 100644
--- a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
@@ -545,6 +545,7 @@
             builder.append('\n').append(format("src=%s, dst=%s", ci.getSrc(), ci.getDst()));
             builder.append('\n').append(format("signal type=%s", ci.getSignalType()));
             builder.append('\n').append(format("bidirectional=%s", ci.isBidirectional()));
+            builder.append('\n').append(format("ochSignal=%s", ci.ochSignal()));
         } else if (intent instanceof OpticalOduIntent) {
             OpticalOduIntent ci = (OpticalOduIntent) intent;
             builder.append('\n').append(format("src=%s, dst=%s", ci.getSrc(), ci.getDst()));
diff --git a/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java b/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
index 05efb15..940b4f3 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
@@ -19,10 +19,12 @@
 import com.google.common.base.MoreObjects;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.OchSignal;
 import org.onosproject.net.OduSignalType;
 import org.onosproject.net.ResourceGroup;
 
 import java.util.Collections;
+import java.util.Optional;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -36,6 +38,7 @@
     private final ConnectPoint dst;
     private final OduSignalType signalType;
     private final boolean isBidirectional;
+    private final Optional<OchSignal> ochSignal;
 
     /**
      * Creates an optical connectivity intent between the specified
@@ -47,34 +50,7 @@
      * @param dst the destination transponder port
      * @param signalType signal type
      * @param isBidirectional indicates if intent is unidirectional
-     * @param priority priority to use for flows from this intent
-     * @deprecated 1.9.1
-     */
-    @Deprecated
-    protected OpticalConnectivityIntent(ApplicationId appId,
-                                        Key key,
-                                        ConnectPoint src,
-                                        ConnectPoint dst,
-                                        OduSignalType signalType,
-                                        boolean isBidirectional,
-                                        int priority) {
-        super(appId, key, Collections.emptyList(), priority, null);
-        this.src = checkNotNull(src);
-        this.dst = checkNotNull(dst);
-        this.signalType = checkNotNull(signalType);
-        this.isBidirectional = isBidirectional;
-    }
-
-    /**
-     * Creates an optical connectivity intent between the specified
-     * connection points.
-     *
-     * @param appId application identification
-     * @param key intent key
-     * @param src the source transponder port
-     * @param dst the destination transponder port
-     * @param signalType signal type
-     * @param isBidirectional indicates if intent is unidirectional
+     * @param ochSignal optional OCh signal
      * @param priority priority to use for flows from this intent
      * @param resourceGroup resource group of this intent
      */
@@ -84,6 +60,7 @@
                                         ConnectPoint dst,
                                         OduSignalType signalType,
                                         boolean isBidirectional,
+                                        Optional<OchSignal> ochSignal,
                                         int priority,
                                         ResourceGroup resourceGroup) {
         super(appId, key, Collections.emptyList(), priority, resourceGroup);
@@ -91,6 +68,7 @@
         this.dst = checkNotNull(dst);
         this.signalType = checkNotNull(signalType);
         this.isBidirectional = isBidirectional;
+        this.ochSignal = ochSignal;
     }
 
     /**
@@ -111,6 +89,7 @@
         private ConnectPoint dst;
         private OduSignalType signalType;
         private boolean isBidirectional;
+        private Optional<OchSignal> ochSignal = Optional.empty();
 
         @Override
         public Builder appId(ApplicationId appId) {
@@ -177,6 +156,17 @@
         }
 
         /**
+         * Sets the OCh signal of the intent.
+         *
+         * @param ochSignal the lambda
+         * @return this builder
+         */
+        public Builder ochSignal(OchSignal ochSignal) {
+            this.ochSignal = Optional.ofNullable(ochSignal);
+            return this;
+        }
+
+        /**
          * Builds an optical connectivity intent from the accumulated parameters.
          *
          * @return point to point intent
@@ -190,6 +180,7 @@
                     dst,
                     signalType,
                     isBidirectional,
+                    ochSignal,
                     priority,
                     resourceGroup
             );
@@ -205,6 +196,7 @@
         this.dst = null;
         this.signalType = null;
         this.isBidirectional = false;
+        this.ochSignal = null;
     }
 
     /**
@@ -243,6 +235,15 @@
         return isBidirectional;
     }
 
+    /**
+     * Returns the OCh signal of the intent.
+     *
+     * @return the lambda
+     */
+    public Optional<OchSignal> ochSignal() {
+        return ochSignal;
+    }
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
@@ -255,6 +256,7 @@
                 .add("dst", dst)
                 .add("signalType", signalType)
                 .add("isBidirectional", isBidirectional)
+                .add("ochSignal", ochSignal)
                 .add("resourceGroup", resourceGroup())
                 .toString();
     }