diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
index 2ff3a49..7ea9934 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
@@ -18,8 +18,10 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
 
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -34,8 +36,15 @@
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelService;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Path;
 import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyEdge;
 import org.onosproject.pce.pceservice.api.PceService;
+import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.DistributedSet;
 import org.onosproject.store.service.Serializer;
@@ -43,6 +52,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Implementation of PCE service.
  */
@@ -66,6 +77,15 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected StorageService storageService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PathService pathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
     private ApplicationId appId;
 
     /**
@@ -92,6 +112,36 @@
         log.info("Stopped");
     }
 
+    /**
+     * Returns an edge-weight capable of evaluating links on the basis of the
+     * specified constraints.
+     *
+     * @param constraints path constraints
+     * @return edge-weight function
+     */
+    private LinkWeight weight(List<Constraint> constraints) {
+        return new TeConstraintBasedLinkWeight(constraints);
+    }
+
+    /**
+     * Computes a path between two devices.
+     *
+     * @param src ingress device
+     * @param dst egress device
+     * @param constraints path constraints
+     * @return computed path based on constraints
+     */
+    protected Set<Path> computePath(DeviceId src, DeviceId dst, List<Constraint> constraints) {
+        if (pathService == null) {
+            return null;
+        }
+        Set<Path> paths = pathService.getPaths(src, dst, weight(constraints));
+        if (!paths.isEmpty()) {
+            return paths;
+        }
+        return null;
+    }
+
     //[TODO:] handle requests in queue
     @Override
     public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
@@ -103,8 +153,8 @@
         checkNotNull(lspType);
 
         // TODO: compute and setup path.
-
-        return true;
+        //TODO: gets the path based on constraints and creates a tunnel in network via tunnel manager
+        return computePath(src, dst, constraints) != null ? true : false;
     }
 
 
@@ -159,4 +209,44 @@
         return value;
     }
 
+    protected class TeConstraintBasedLinkWeight implements LinkWeight {
+
+        private final List<Constraint> constraints;
+
+        /**
+         * Creates a new edge-weight function capable of evaluating links
+         * on the basis of the specified constraints.
+         *
+         * @param constraints path constraints
+         */
+        public TeConstraintBasedLinkWeight(List<Constraint> constraints) {
+            if (constraints == null) {
+                this.constraints = Collections.emptyList();
+            } else {
+                this.constraints = ImmutableList.copyOf(constraints);
+            }
+        }
+
+        @Override
+        public double weight(TopologyEdge edge) {
+            if (!constraints.iterator().hasNext()) {
+                //Takes default cost/hopcount as 1 if no constraints specified
+                return 1.0;
+            }
+
+            Iterator<Constraint> it = constraints.iterator();
+            double cost = 1;
+
+            //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
+            while (it.hasNext() && cost > 0) {
+                Constraint constraint = it.next();
+                if (constraint instanceof CapabilityConstraint) {
+                    cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
+                } else {
+                    cost = constraint.cost(edge.link(), resourceService::isAvailable);
+                }
+            }
+            return cost;
+        }
+    }
 }
\ No newline at end of file
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CapabilityConstraint.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CapabilityConstraint.java
new file mode 100644
index 0000000..a479c38
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CapabilityConstraint.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.pce.pceservice.constraint;
+
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intent.ResourceContext;
+import org.onosproject.net.intent.constraint.BooleanConstraint;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Constraint that evaluates whether devices satisfies capability.
+ */
+public final class CapabilityConstraint extends BooleanConstraint {
+
+    private final CapabilityType capabilityType;
+    public static final String PCECC_CAPABILITY = "pceccCapability";
+    public static final String SR_CAPABILITY = "srCapability";
+    public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
+    public static final String LSRID = "lsrId";
+    public static final String L3 = "L3";
+    public static final String TRUE = "true";
+
+    /**
+     * Represents about capability type.
+     */
+    public enum CapabilityType {
+        /**
+         * Signifies that path is created via signaling mode.
+         */
+        WITH_SIGNALLING(0),
+
+        /**
+         * Signifies that path is created via SR mode.
+         */
+        SR_WITHOUT_SIGNALLING(1),
+
+        /**
+         * Signifies that path is created via without signaling and without SR mode.
+         */
+        WITHOUT_SIGNALLING_AND_WITHOUT_SR(2);
+
+        int value;
+
+        /**
+         * Assign val with the value as the capability type.
+         *
+         * @param val capability type
+         */
+        CapabilityType(int val) {
+            value = val;
+        }
+
+        /**
+         * Returns value of capability type.
+         *
+         * @return capability type
+         */
+        public byte type() {
+            return (byte) value;
+        }
+    }
+
+    // Constructor for serialization
+    private CapabilityConstraint() {
+        capabilityType = null;
+    }
+
+    /**
+     * Creates a new capability constraint.
+     *
+     * @param capabilityType type of capability device supports
+     */
+    public CapabilityConstraint(CapabilityType capabilityType) {
+        this.capabilityType = capabilityType;
+    }
+
+    /**
+     * Creates a new capability constraint.
+     *
+     * @param capabilityType type of capability device supports
+     * @return instance of CapabilityConstraint for specified capability type
+     */
+    public static CapabilityConstraint of(CapabilityType capabilityType) {
+        return new CapabilityConstraint(capabilityType);
+    }
+
+    /**
+     * Obtains type of capability.
+     *
+     * @return type of capability
+     */
+    public CapabilityType capabilityType() {
+        return capabilityType;
+    }
+
+    /**
+     * Validates the link based on capability constraint.
+     *
+     * @param link to validate source and destination based on capability constraint
+     * @param deviceService instance of DeviceService
+     * @return true if link satisfies capability constraint otherwise false
+     */
+    public boolean isValidLink(Link link, DeviceService deviceService) {
+        if (deviceService == null) {
+            return false;
+        }
+
+        Device srcDevice = deviceService.getDevice(link.src().deviceId());
+        Device dstDevice = deviceService.getDevice(link.dst().deviceId());
+
+        //TODO: Usage of annotations are for transient solution. In future will be replaces with the
+        // network config service / Projection model.
+        // L3 device
+        if (srcDevice == null
+                || dstDevice == null
+                || srcDevice.annotations().value(AnnotationKeys.TYPE) == null
+                || dstDevice.annotations().value(AnnotationKeys.TYPE) == null
+                || !srcDevice.annotations().value(AnnotationKeys.TYPE).equals(L3)
+                || !dstDevice.annotations().value(AnnotationKeys.TYPE).equals(L3)) {
+            return false;
+        }
+
+        String scrLsrId = srcDevice.annotations().value(LSRID);
+        String dstLsrId = dstDevice.annotations().value(LSRID);
+
+        Device srcCapDevice = null;
+        Device dstCapDevice = null;
+
+        // Get Capability device
+        Iterable<Device> devices = deviceService.getAvailableDevices();
+        for (Device dev : devices) {
+            if (dev.annotations().value(LSRID).equals(scrLsrId)) {
+                srcCapDevice = dev;
+            } else if (dev.annotations().value(LSRID).equals(dstLsrId)) {
+                dstCapDevice = dev;
+            }
+        }
+
+        if (srcCapDevice == null || dstCapDevice == null) {
+            return false;
+        }
+
+        switch (capabilityType) {
+        case WITH_SIGNALLING:
+            return true;
+        case WITHOUT_SIGNALLING_AND_WITHOUT_SR:
+            if (srcCapDevice.annotations().value(PCECC_CAPABILITY) != null
+                    && dstCapDevice.annotations().value(PCECC_CAPABILITY) != null) {
+                return srcCapDevice.annotations().value(PCECC_CAPABILITY).equals(TRUE)
+                        && dstCapDevice.annotations().value(PCECC_CAPABILITY).equals(TRUE);
+            }
+            return false;
+        case SR_WITHOUT_SIGNALLING:
+            if (srcCapDevice.annotations().value(LABEL_STACK_CAPABILITY) != null
+                    && dstCapDevice.annotations().value(LABEL_STACK_CAPABILITY) != null
+                    && srcCapDevice.annotations().value(SR_CAPABILITY) != null
+                    && dstCapDevice.annotations().value(SR_CAPABILITY) != null) {
+                return srcCapDevice.annotations().value(LABEL_STACK_CAPABILITY).equals(TRUE)
+                        && dstCapDevice.annotations().value(LABEL_STACK_CAPABILITY).equals(TRUE)
+                        && srcCapDevice.annotations().value(SR_CAPABILITY).equals(TRUE)
+                        && dstCapDevice.annotations().value(SR_CAPABILITY).equals(TRUE);
+            }
+            return false;
+        default:
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isValid(Link link, ResourceContext context) {
+        return false;
+        //Do nothing instead using isValidLink needs device service to validate link
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(capabilityType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof CapabilityConstraint) {
+            CapabilityConstraint other = (CapabilityConstraint) obj;
+            return Objects.equals(this.capabilityType, other.capabilityType);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("capabilityType", capabilityType)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CostConstraint.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CostConstraint.java
new file mode 100644
index 0000000..229644d
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/CostConstraint.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.pce.pceservice.constraint;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.intent.ResourceContext;
+import org.onosproject.net.intent.Constraint;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Constraint that evaluates whether cost for a link is available, if yes return cost for that link.
+ */
+public final class CostConstraint implements Constraint {
+
+    /**
+     * Represents about cost types.
+     */
+    public enum Type {
+        /**
+         * Signifies that cost is IGP cost.
+         */
+        COST(1),
+
+        /**
+         * Signifies that cost is TE cost.
+         */
+        TE_COST(2);
+
+        int value;
+
+        /**
+         * Assign val with the value as the Cost type.
+         *
+         * @param val Cost type
+         */
+        Type(int val) {
+            value = val;
+        }
+
+        /**
+         * Returns value of Cost type.
+         *
+         * @return Cost type
+         */
+        public byte type() {
+            return (byte) value;
+        }
+    }
+
+    private final Type type;
+    public static final String TE_COST = "teCost";
+    public static final String COST = "cost";
+
+    // Constructor for serialization
+    private CostConstraint() {
+        this.type = null;
+    }
+
+    /**
+     * Creates a new cost constraint.
+     *
+     * @param type of a link
+     */
+    public CostConstraint(Type type) {
+        this.type = checkNotNull(type, "Type cannot be null");
+    }
+
+    /**
+     * Creates new CostConstraint with specified cost type.
+     *
+     * @param type of cost
+     * @return instance of CostConstraint
+     */
+    public static CostConstraint of(Type type) {
+        return new CostConstraint(type);
+    }
+
+    /**
+     * Returns the type of a cost specified in a constraint.
+     *
+     * @return required cost type
+     */
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof CostConstraint) {
+            CostConstraint other = (CostConstraint) obj;
+            return Objects.equals(this.type, other.type);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("type", type)
+                .toString();
+    }
+
+    @Override
+    public double cost(Link link, ResourceContext context) {
+        //TODO: Usage of annotations are for transient solution. In future will be replaces with the
+        // network config service / Projection model.
+        switch (type) {
+        case COST:
+            if (link.annotations().value(COST) != null) {
+                return Double.parseDouble(link.annotations().value(COST));
+            }
+
+            //If cost annotations absent return -1[It is not L3 device]
+            return -1;
+        case TE_COST:
+            if (link.annotations().value(TE_COST) != null) {
+                return Double.parseDouble(link.annotations().value(TE_COST));
+            }
+
+            //If TE cost annotations absent return -1[It is not L3 device]
+            return -1;
+        default:
+            return -1;
+        }
+    }
+
+    @Override
+    public boolean validate(Path path, ResourceContext context) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/SharedBandwidthConstraint.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/SharedBandwidthConstraint.java
new file mode 100644
index 0000000..2985f24
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/SharedBandwidthConstraint.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.pce.pceservice.constraint;
+
+import org.onlab.util.Bandwidth;
+import org.onosproject.net.Link;
+import org.onosproject.net.intent.ResourceContext;
+import org.onosproject.net.intent.constraint.BooleanConstraint;
+import org.onosproject.net.resource.Resources;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Constraint that evaluates whether links satisfies sharedbandwidth request.
+ */
+public final class SharedBandwidthConstraint extends BooleanConstraint {
+
+    private final List<Link> links;
+    private final Bandwidth sharedBwValue;
+    private final Bandwidth requestBwValue;
+    //temporary variable declared to hold changed bandwidth value
+    private Bandwidth changedBwValue;
+
+    // Constructor for serialization
+    private SharedBandwidthConstraint() {
+        links = null;
+        sharedBwValue = null;
+        requestBwValue = null;
+    }
+
+    /**
+     * Creates a new SharedBandwidth constraint.
+     *
+     * @param links shared links
+     * @param sharedBwValue shared bandwidth of the links
+     * @param requestBwValue requested bandwidth value
+     */
+    public SharedBandwidthConstraint(List<Link> links, Bandwidth sharedBwValue, Bandwidth requestBwValue) {
+        this.links = links;
+        this.sharedBwValue = sharedBwValue;
+        this.requestBwValue = requestBwValue;
+    }
+
+    /**
+     * Creates a new SharedBandwidth constraint.
+     *
+     * @param links shared links
+     * @param sharedBwValue shared bandwidth of the links
+     * @param requestBwValue requested bandwidth value
+     * @return SharedBandwidth instance
+     */
+    public static SharedBandwidthConstraint of(List<Link> links, Bandwidth sharedBwValue, Bandwidth requestBwValue) {
+        return new SharedBandwidthConstraint(links, sharedBwValue, requestBwValue);
+    }
+
+    /**
+     * Obtains shared links.
+     *
+     * @return shared links
+     */
+    public List<Link> links() {
+        return links;
+    }
+
+    /**
+     * Obtains shared bandwidth of the links.
+     *
+     * @return shared bandwidth
+     */
+    public Bandwidth sharedBwValue() {
+        return sharedBwValue;
+    }
+
+    /**
+     * Obtains requested bandwidth value.
+     *
+     * @return requested bandwidth value
+     */
+    public Bandwidth requestBwValue() {
+        return requestBwValue;
+    }
+
+    @Override
+    public boolean isValid(Link link, ResourceContext context) {
+        changedBwValue = requestBwValue;
+        if (links.contains(link)) {
+            changedBwValue = requestBwValue.isGreaterThan(sharedBwValue) ? requestBwValue.subtract(sharedBwValue)
+                    : Bandwidth.bps(0);
+        }
+
+        return Stream
+                .of(link.src(), link.dst())
+                .map(cp -> Resources.continuous(cp.deviceId(), cp.port(), Bandwidth.class).resource(
+                        changedBwValue.bps())).allMatch(context::isAvailable);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(requestBwValue, sharedBwValue, links);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof SharedBandwidthConstraint) {
+            SharedBandwidthConstraint other = (SharedBandwidthConstraint) obj;
+            return Objects.equals(this.requestBwValue, other.requestBwValue)
+                    && Objects.equals(this.sharedBwValue, other.sharedBwValue)
+                    && Objects.equals(this.links, other.links);
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("requestBwValue", requestBwValue)
+                .add("sharedBwValue", sharedBwValue)
+                .add("links", links)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/package-info.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/package-info.java
new file mode 100644
index 0000000..a788a42
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/constraint/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.
+ */
+
+/**
+ * Constraints for path computation for PCE service.
+ */
+package org.onosproject.pce.pceservice.constraint;
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java
new file mode 100644
index 0000000..446aea2
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java
@@ -0,0 +1,1032 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.pce.pceservice;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.AbstractGraphPathSearch;
+import org.onlab.graph.AdjacencyListsGraph;
+import org.onlab.graph.DijkstraGraphSearch;
+import org.onlab.graph.Graph;
+import org.onlab.graph.GraphPathSearch;
+import org.onlab.packet.ChassisId;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.Tools;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.Device.Type;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.resource.ContinuousResource;
+import org.onosproject.net.resource.ContinuousResourceId;
+import org.onosproject.net.resource.DiscreteResource;
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceConsumer;
+import org.onosproject.net.resource.ResourceId;
+import org.onosproject.net.resource.Resources;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.DefaultTopologyEdge;
+import org.onosproject.net.topology.DefaultTopologyVertex;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.TopologyEdge;
+import org.onosproject.net.topology.TopologyVertex;
+import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
+import org.onosproject.pce.pceservice.constraint.CostConstraint;
+import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
+import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
+import static com.google.common.collect.ImmutableSet.of;
+import static org.onosproject.net.resource.Resources.continuous;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
+import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
+
+/**
+ * Test for CSPF path computation.
+ */
+public class PathComputationTest {
+
+    private final MockPathResourceService resourceService = new MockPathResourceService();
+    private final MockDeviceService deviceService = new MockDeviceService();
+    private PceManager pceManager = new PceManager();
+    public static ProviderId providerId = new ProviderId("pce", "foo");
+    private static final String DEVICE1 = "D001";
+    private static final String DEVICE2 = "D002";
+    private static final String DEVICE3 = "D003";
+    private static final String DEVICE4 = "D004";
+    private static final String DEVICE5 = "D005";
+    public static final String PCEPDEVICE1 = "PD001";
+    public static final String PCEPDEVICE2 = "PD002";
+    public static final String PCEPDEVICE3 = "PD003";
+    public static final String PCEPDEVICE4 = "PD004";
+    private static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
+    private static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
+    private static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
+    private static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
+    private static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
+    private static final String ANNOTATION_COST = "cost";
+    private static final String ANNOTATION_TE_COST = "teCost";
+    private static final String UNKNOWN = "unknown";
+    public static final String LSRID = "lsrId";
+    public static final String L3 = "L3";
+    public static final String PCECC_CAPABILITY = "pceccCapability";
+    public static final String SR_CAPABILITY = "srCapability";
+    public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
+
+    @Before
+    public void startUp() {
+        pceManager.resourceService = resourceService;
+        pceManager.deviceService = deviceService;
+    }
+
+    /**
+     * Selects path computation algorithm.
+     *
+     * @return graph path search algorithm
+     */
+    private AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
+        return new DijkstraGraphSearch<>();
+    }
+
+    /**
+     * Returns link for two devices.
+     *
+     * @param device source device
+     * @param port source port
+     * @param device2 destination device
+     * @param port2 destination port
+     * @return link
+     */
+    private Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
+        ConnectPoint src = new ConnectPoint(DeviceId.deviceId(device), PortNumber.portNumber(port));
+        ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(device2), PortNumber.portNumber(port2));
+        Link curLink;
+        DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+        if (setCost) {
+            annotationBuilder.set(ANNOTATION_COST, String.valueOf(value));
+        } else {
+            annotationBuilder.set(ANNOTATION_TE_COST, String.valueOf(value));
+        }
+
+        //TODO:If cost not set cost : default value case
+        curLink = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
+                 .providerId(PathComputationTest.providerId).annotations(annotationBuilder.build()).build();
+        return curLink;
+    }
+
+    @After
+    public void tearDown() {
+        pceManager.resourceService = null;
+        pceManager.deviceService = null;
+    }
+
+    /**
+     * Returns an edge-weight capable of evaluating links on the basis of the
+     * specified constraints.
+     *
+     * @param constraints path constraints
+     * @return edge-weight function
+     */
+    private LinkWeight weight(List<Constraint> constraints) {
+        return new MockTeConstraintBasedLinkWeight(constraints);
+    }
+
+    private Set<Path> computePath(Link link1, Link link2, Link link3, Link link4, List<Constraint> constraints) {
+        Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4),
+                of(new DefaultTopologyEdge(D1, D2, link1),
+                   new DefaultTopologyEdge(D2, D4, link2),
+                   new DefaultTopologyEdge(D1, D3, link3),
+                   new DefaultTopologyEdge(D3, D4, link4)));
+
+        GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
+                graphSearch().search(graph, D1, D4, weight(constraints), ALL_PATHS);
+        ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
+        for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
+            builder.add(networkPath(path));
+        }
+        return builder.build();
+    }
+
+    private class MockDeviceService extends DeviceServiceAdapter {
+        List<Device> devices = new LinkedList<>();
+
+        private void addDevice(Device dev) {
+            devices.add(dev);
+        }
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            for (Device dev : devices) {
+                if (dev.id().equals(deviceId)) {
+                    return dev;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            return devices;
+        }
+    }
+
+    private class MockTeConstraintBasedLinkWeight implements LinkWeight {
+
+        private final List<Constraint> constraints;
+
+        /**
+         * Creates a new edge-weight function capable of evaluating links
+         * on the basis of the specified constraints.
+         *
+         * @param constraints path constraints
+         */
+        MockTeConstraintBasedLinkWeight(List<Constraint> constraints) {
+            if (constraints == null) {
+                this.constraints = Collections.emptyList();
+            } else {
+                this.constraints = ImmutableList.copyOf(constraints);
+            }
+        }
+
+        public double weight(TopologyEdge edge) {
+            if (!constraints.iterator().hasNext()) {
+                //Takes default cost/hopcount as 1 if no constraints specified
+                return 1.0;
+            }
+
+            Iterator<Constraint> it = constraints.iterator();
+            double cost = 1;
+
+            //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
+            while (it.hasNext() && cost > 0) {
+                Constraint constraint = it.next();
+                if (constraint instanceof CapabilityConstraint) {
+                    cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
+                } else {
+                    cost = constraint.cost(edge.link(), resourceService::isAvailable);
+                }
+            }
+            return cost;
+        }
+    }
+
+    private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
+        List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
+        return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
+    }
+
+    /**
+     * Test Resource service for path computation.
+     */
+    private class MockPathResourceService extends ResourceServiceAdapter {
+        private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
+        private Map<ResourceId, List<ResourceAllocation>> resourcesAllocations = new HashMap<>();
+
+        @Override
+        public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
+            for (Resource resource: resources) {
+                if (resource instanceof ContinuousResource) {
+                    List<ResourceAllocation> allocs = new LinkedList<>();
+                    allocs.add(new ResourceAllocation(resource, consumer));
+                    resourcesAllocations.put(resource.id(), allocs);
+                }
+            }
+            return resources.stream()
+                    .map(x -> new ResourceAllocation(x, consumer))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
+            if (id instanceof ContinuousResourceId) {
+                return resourcesAllocations.get(id);
+            }
+            DiscreteResource discrete = Resources.discrete((DiscreteResourceId) id).resource();
+            return Optional.ofNullable(assignment.get(discrete))
+                    .map(x -> ImmutableList.of(new ResourceAllocation(discrete, x)))
+                    .orElse(ImmutableList.of());
+        }
+
+        @Override
+        public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
+            return getAvailableResources(parent).stream()
+                    .filter(x -> x.isTypeOf(cls))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
+            return getAvailableResources(parent).stream()
+                    .filter(x -> x.isTypeOf(cls))
+                    .flatMap(x -> Tools.stream(x.valueAs(cls)))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public boolean isAvailable(Resource resource) {
+            if (resource instanceof DiscreteResource) {
+                return true;
+            }
+
+            if (resource instanceof ContinuousResource) {
+                List<ResourceAllocation> resalloc = resourcesAllocations.get(resource.id());
+
+                if ((resalloc != null) && (!resalloc.isEmpty())) {
+                    if (((ContinuousResource) resalloc.iterator().next().resource()).value()
+                            >= ((ContinuousResource) resource).value()) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * All links with different costs with L1-L2 as least cost path.
+     */
+    @Test
+    public void testpathComputationCase1() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Links with same cost 100 except link3.
+     */
+    @Test
+    public void testpathComputationCase2() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 100);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 1000);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 200));
+    }
+
+    /**
+     * Path which satisfy bandwidth as a constraint with 10bps.
+     */
+    @Test
+    public void testpathComputationCase3() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class)
+                .resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class)
+                .resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.src().port(), Bandwidth.class)
+                .resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class)
+                .resource(100));
+
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(10.0));
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(bandwidthConst);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Path which satisfy bandwidth as a constraint with 60bps.
+     */
+    @Test
+    public void testpathComputationCase4() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 50);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(60.0));
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(bandwidthConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Shared bandwidth as L1, L2 with its value 10 bps and bandwidth constraint as 20 bps.
+     */
+    @Test
+    public void testpathComputationCase5() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        List<Link> sharedLinks = new LinkedList<>();
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        sharedLinks.addAll(links);
+        SharedBandwidthConstraint sharedBw = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(10),
+                Bandwidth.bps(20.0));
+        constraints.add(sharedBw);
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Shared bandwidth as L1, L2 with its value 20 bps and bandwidth constraint as 10 bps.
+     */
+    @Test
+    public void testpathComputationCase6() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        List<Link> sharedLinks = new LinkedList<>();
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        CostConstraint costConst = CostConstraint.of(COST);
+        sharedLinks.addAll(links);
+        SharedBandwidthConstraint sharedBwConst = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(20),
+                Bandwidth.bps(10.0));
+        constraints.add(sharedBwConst);
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path without constraints.
+     */
+    @Test
+    public void testpathComputationCase7() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+        List<Constraint> constraints = new LinkedList<>();
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * With TeCost as a constraints.
+     */
+    @Test
+    public void testpathComputationCase8() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(tecostConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * With device supporting RSVP capability as a constraints.
+     */
+    @Test
+    public void testpathComputationCase9() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITH_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        constraints.add(tecostConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Devices supporting CR capability.
+     */
+    @Test
+    public void testpathComputationCase10() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        CostConstraint costConst = CostConstraint.of(COST);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Device supporting SR capability.
+     */
+    @Test
+    public void testpathComputationCase11() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        CostConstraint costConst = CostConstraint.of(COST);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path with TE and SR capability constraint.
+     */
+    @Test
+    public void testpathComputationCase12() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        constraints.add(capabilityConst);
+        constraints.add(tecostConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path with capability constraint and with default cost.
+     */
+    @Test
+    public void testpathComputationCase13() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Test case with empty constraints.
+     */
+    @Test
+    public void testpathComputationCase14() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        List<Constraint> constraints = new LinkedList<>();
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Test case with constraints as null.
+     */
+    @Test
+    public void testpathComputationCase15() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        List<Constraint> constraints = null;
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Path with cost constraint.
+     */
+    @Test
+    public void testpathComputationCase16() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
+        Link link5 = addLink(DEVICE4, 90, DEVICE5, 100, true, 20);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+        Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4, D5),
+                of(new DefaultTopologyEdge(D1, D2, link1),
+                   new DefaultTopologyEdge(D2, D4, link2),
+                   new DefaultTopologyEdge(D1, D3, link3),
+                   new DefaultTopologyEdge(D3, D4, link4),
+                   new DefaultTopologyEdge(D4, D5, link5)));
+
+        GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
+                graphSearch().search(graph, D1, D5, weight(constraints), ALL_PATHS);
+        ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
+        for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
+            builder.add(networkPath(path));
+        }
+
+        List<Link> links = new LinkedList<>();
+        links.add(link3);
+        links.add(link4);
+        links.add(link5);
+        assertThat(builder.build().iterator().next().links(), is(links));
+        assertThat(builder.build().iterator().next().cost(), is((double) 40));
+    }
+
+    /**
+     * D3 doesn't support capability constraint, so path is L1-L2.
+     */
+    @Test
+    public void testpathComputationCase17() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * L2 doesn't support cost constraint and D3 doesn't support capability constraint, both constraint fails hence no
+     * path.
+     */
+    @Test
+    public void testpathComputationCase18() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths, is(new HashSet<>()));
+    }
+
+    private void addDevice(String device, DefaultAnnotations.Builder builder) {
+        deviceService.addDevice(new DefaultDevice(ProviderId.NONE, deviceId(device), Type.ROUTER,
+        UNKNOWN, UNKNOWN, UNKNOWN,
+        UNKNOWN, new ChassisId(), builder.build()));
+    }
+}
\ No newline at end of file
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/ResourceServiceAdapter.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/ResourceServiceAdapter.java
new file mode 100644
index 0000000..791ca6e
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/ResourceServiceAdapter.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.pce.pceservice;
+
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceConsumer;
+import org.onosproject.net.resource.ResourceId;
+import org.onosproject.net.resource.ResourceListener;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceService;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Adapter for resource service for path computation.
+ */
+public class ResourceServiceAdapter implements ResourceService {
+
+    @Override
+    public void addListener(ResourceListener listener) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void removeListener(ResourceListener listener) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean release(List<ResourceAllocation> allocations) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean release(ResourceConsumer consumer) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isAvailable(Resource resource) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+}
