1acf6dfe073464d353695a0796732ce03f58f8a1
[onosfw.git] /
1 /*
2  * Copyright 2014 Open Networking Laboratory
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onosproject.net.intent.constraint;
17
18 import com.google.common.annotations.Beta;
19 import com.google.common.base.MoreObjects;
20 import com.google.common.collect.ImmutableList;
21 import org.onosproject.net.DeviceId;
22 import org.onosproject.net.Link;
23 import org.onosproject.net.Path;
24 import org.onosproject.net.intent.Constraint;
25 import org.onosproject.net.resource.link.LinkResourceService;
26
27 import java.util.Collections;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Objects;
31
32 import static com.google.common.base.Preconditions.checkArgument;
33 import static com.google.common.base.Preconditions.checkNotNull;
34
35 /**
36  * Constraint that evaluates elements passed through in order.
37  */
38 @Beta
39 public class WaypointConstraint implements Constraint {
40
41     private final List<DeviceId> waypoints;
42
43     /**
44      * Creates a new waypoint constraint.
45      *
46      * @param waypoints waypoints
47      */
48     public WaypointConstraint(DeviceId... waypoints) {
49         checkNotNull(waypoints, "waypoints cannot be null");
50         checkArgument(waypoints.length > 0, "length of waypoints should be more than 0");
51         this.waypoints = ImmutableList.copyOf(waypoints);
52     }
53
54     // Constructor for serialization
55     private WaypointConstraint() {
56         this.waypoints = Collections.emptyList();
57     }
58
59     public List<DeviceId> waypoints() {
60         return waypoints;
61     }
62
63     @Override
64     public double cost(Link link, LinkResourceService resourceService) {
65         // Always consider the number of hops
66         return 1;
67     }
68
69     @Override
70     public boolean validate(Path path, LinkResourceService resourceService) {
71         LinkedList<DeviceId> waypoints = new LinkedList<>(this.waypoints);
72         DeviceId current = waypoints.poll();
73         // This is safe because Path class ensures the number of links are more than 0
74         Link firstLink = path.links().get(0);
75         if (firstLink.src().elementId().equals(current)) {
76             current = waypoints.poll();
77         }
78
79         for (Link link : path.links()) {
80             if (link.dst().elementId().equals(current)) {
81                 current = waypoints.poll();
82                 // Empty waypoints means passing through all waypoints in the specified order
83                 if (current == null) {
84                     return true;
85                 }
86             }
87         }
88
89         return false;
90     }
91
92     @Override
93     public int hashCode() {
94         return Objects.hash(waypoints);
95     }
96
97     @Override
98     public boolean equals(Object obj) {
99         if (this == obj) {
100             return true;
101         }
102
103         if (!(obj instanceof WaypointConstraint)) {
104             return false;
105         }
106
107         final WaypointConstraint that = (WaypointConstraint) obj;
108         return Objects.equals(this.waypoints, that.waypoints);
109     }
110
111     @Override
112     public String toString() {
113         return MoreObjects.toStringHelper(this)
114                 .add("waypoints", waypoints)
115                 .toString();
116     }
117 }