Move wavelength selection logic to OpticalConnectivityIntentCompiler

Now, LinkResourceManager doesn't have a logic to select lambda(s)

Change-Id: I008d770f4f142f3d67afa734e50bd8761a0aafd2
diff --git a/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java b/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
index 5153aeb..e61e87e 100644
--- a/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
@@ -20,6 +20,7 @@
 import java.util.Set;
 import java.util.Objects;
 
+import com.google.common.annotations.Beta;
 import org.onlab.util.Bandwidth;
 import org.onosproject.net.Link;
 import org.onosproject.net.intent.Constraint;
@@ -114,13 +115,22 @@
          * Adds lambda request.
          *
          * @return self
+         * @deprecated in Emu Release
          */
+        @Deprecated
         @Override
         public Builder addLambdaRequest() {
             resources.add(new LambdaResourceRequest());
             return this;
         }
 
+        @Beta
+        @Override
+        public LinkResourceRequest.Builder addLambdaRequest(LambdaResource lambda) {
+            resources.add(new LambdaResourceRequest(lambda));
+            return this;
+        }
+
         /**
          * Adds Mpls request.
          *
diff --git a/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java b/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
index b0391f5..acda18b 100644
--- a/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
@@ -15,15 +15,50 @@
  */
 package org.onosproject.net.resource.link;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import org.onosproject.net.resource.ResourceRequest;
 import org.onosproject.net.resource.ResourceType;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Representation of a request for lambda resource.
  */
 public class LambdaResourceRequest implements ResourceRequest {
 
+    private final LambdaResource lambda;
+
+    /**
+     * Constructs a request specifying the given lambda.
+     *
+     * @param lambda lambda to be requested
+     */
+    @Beta
+    public LambdaResourceRequest(LambdaResource lambda) {
+        this.lambda = checkNotNull(lambda);
+    }
+
+    /**
+     * Constructs a request asking an arbitrary available lambda.
+     *
+     * @deprecated in Emu Release
+     */
+    @Deprecated
+    public LambdaResourceRequest() {
+        this.lambda = null;
+    }
+
+    /**
+     * Returns the lambda this request expects.
+     *
+     * @return the lambda this request expects
+     */
+    @Beta
+    public LambdaResource lambda() {
+        return lambda;
+    }
+
     @Override
     public ResourceType type() {
         return ResourceType.LAMBDA;
diff --git a/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java b/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
index 00c8e8a..1478231 100644
--- a/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.net.resource.link;
 
+import com.google.common.annotations.Beta;
 import org.onosproject.net.Link;
 import org.onosproject.net.intent.Constraint;
 import org.onosproject.net.intent.IntentId;
@@ -57,10 +58,21 @@
          * Adds lambda request.
          *
          * @return self
+         * @deprecated in Emu Release
          */
+        @Deprecated
         Builder addLambdaRequest();
 
         /**
+         * Adds lambda request.
+         *
+         * @param lambda lambda to be requested
+         * @return self
+         */
+        @Beta
+        Builder addLambdaRequest(LambdaResource lambda);
+
+        /**
          * Adds MPLS request.
          *
          * @return self
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 88f94c0..e4df227 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -16,6 +16,9 @@
 package org.onosproject.net.intent.impl.compiler;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -45,6 +48,7 @@
 import org.onosproject.net.resource.link.DefaultLinkResourceRequest;
 import org.onosproject.net.resource.link.LambdaResource;
 import org.onosproject.net.resource.link.LambdaResourceAllocation;
+import org.onosproject.net.resource.link.LambdaResourceRequest;
 import org.onosproject.net.resource.link.LinkResourceAllocations;
 import org.onosproject.net.resource.link.LinkResourceRequest;
 import org.onosproject.net.resource.link.LinkResourceService;
@@ -54,6 +58,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -194,11 +199,19 @@
      * @return first available lambda resource allocation
      */
     private LinkResourceAllocations assignWavelength(Intent intent, Path path) {
-        LinkResourceRequest.Builder request =
-                DefaultLinkResourceRequest.builder(intent.id(), path.links())
-                .addLambdaRequest();
+        Set<LambdaResource> lambdas = findCommonLambdasOverLinks(path.links());
+        if (lambdas.isEmpty()) {
+            return null;
+        }
 
-        LinkResourceAllocations allocations = linkResourceService.requestResources(request.build());
+        LambdaResource minLambda = findFirstLambda(lambdas);
+
+        LinkResourceRequest request =
+                DefaultLinkResourceRequest.builder(intent.id(), path.links())
+                .addLambdaRequest(minLambda)
+                .build();
+
+        LinkResourceAllocations allocations = linkResourceService.requestResources(request);
 
         if (!checkWavelengthContinuity(allocations, path)) {
             linkResourceService.releaseResources(allocations);
@@ -208,6 +221,23 @@
         return allocations;
     }
 
+    private Set<LambdaResource> findCommonLambdasOverLinks(List<Link> links) {
+        return links.stream()
+                .map(x -> ImmutableSet.copyOf(linkResourceService.getAvailableResources(x)))
+                .map(x -> Sets.filter(x, req -> req instanceof LambdaResourceRequest))
+                .map(x -> Iterables.transform(x, req -> (LambdaResourceRequest) req))
+                .map(x -> Iterables.transform(x, LambdaResourceRequest::lambda))
+                .map(x -> (Set<LambdaResource>) ImmutableSet.copyOf(x))
+                .reduce(Sets::intersection)
+                .orElse(Collections.emptySet());
+    }
+
+    private LambdaResource findFirstLambda(Set<LambdaResource> lambdas) {
+        return lambdas.stream()
+                .findFirst()
+                .get();
+    }
+
     /**
      * Checks wavelength continuity constraint across path, i.e., an identical lambda is used on all links.
      * @return true if wavelength continuity is met, false otherwise
diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java b/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java
index e5575c7..5b2b0fb 100644
--- a/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.net.resource.impl;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -32,7 +31,6 @@
 import org.onosproject.net.resource.link.BandwidthResourceAllocation;
 import org.onosproject.net.resource.link.BandwidthResourceRequest;
 import org.onosproject.net.resource.link.DefaultLinkResourceAllocations;
-import org.onosproject.net.resource.link.LambdaResource;
 import org.onosproject.net.resource.link.LambdaResourceAllocation;
 import org.onosproject.net.resource.link.LambdaResourceRequest;
 import org.onosproject.net.resource.link.LinkResourceAllocations;
@@ -47,7 +45,6 @@
 import org.onosproject.net.resource.link.MplsLabelResourceRequest;
 import org.slf4j.Logger;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -55,7 +52,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.security.AppGuard.checkPermission;
 import static org.slf4j.LoggerFactory.getLogger;
 import static org.onosproject.security.AppPermission.Type.*;
@@ -87,42 +83,6 @@
         log.info("Stopped");
     }
 
-    /**
-     * Returns available lambdas on specified link.
-     *
-     * @param link the link
-     * @return available lambdas on specified link
-     */
-    private Set<LambdaResource> getAvailableLambdas(Link link) {
-        checkNotNull(link);
-        Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
-        if (resAllocs == null) {
-            return Collections.emptySet();
-        }
-        Set<LambdaResource> lambdas = new HashSet<>();
-        for (ResourceAllocation res : resAllocs) {
-            if (res.type() == ResourceType.LAMBDA) {
-                lambdas.add(((LambdaResourceAllocation) res).lambda());
-            }
-        }
-        return lambdas;
-    }
-
-
-    /**
-     * Returns available lambdas on specified links.
-     *
-     * @param links the links
-     * @return available lambdas on specified links
-     */
-    private Collection<LambdaResource> getAvailableLambdas(Iterable<Link> links) {
-        checkNotNull(links);
-        return ImmutableList.copyOf(links).stream()
-                .map(this::getAvailableLambdas)
-                .reduce(Sets::intersection)
-                .orElse(Collections.emptySet());
-    }
-
 
     /**
      * Returns available MPLS label on specified link.
@@ -162,14 +122,8 @@
                 allocs.add(new BandwidthResourceAllocation(br.bandwidth()));
                 break;
             case LAMBDA:
-                Iterator<LambdaResource> lambdaIterator =
-                        getAvailableLambdas(req.links()).iterator();
-                if (lambdaIterator.hasNext()) {
-                    allocs.add(new LambdaResourceAllocation(lambdaIterator.next()));
-                } else {
-                    log.info("Failed to allocate lambda resource.");
-                    return null;
-                }
+                LambdaResourceRequest lr = (LambdaResourceRequest) r;
+                allocs.add(new LambdaResourceAllocation(lr.lambda()));
                 break;
             case MPLS_LABEL:
                 for (Link link : req.links()) {
@@ -256,7 +210,8 @@
                         ((BandwidthResourceAllocation) alloc).bandwidth()));
                 break;
             case LAMBDA:
-                result.add(new LambdaResourceRequest());
+                result.add(new LambdaResourceRequest(
+                        ((LambdaResourceAllocation) alloc).lambda()));
                 break;
             case MPLS_LABEL:
                 result.add(new MplsLabelResourceRequest());