Hongtao Yin
Committed by Gerrit Code Review

Updated calendar server code. Added intent for bi-dirctional path. Added latency…

… as one more parameter in constraints.

Added exception catch for parsing parameters.

Fixed Jenkins checking errors.

Use intent key and 2way intent P2P setup.

Change-Id: Ib2bd25deb793b2a34179cbf8794ca5aa3e427f91
...@@ -15,42 +15,50 @@ ...@@ -15,42 +15,50 @@
15 */ 15 */
16 package org.onosproject.calendar; 16 package org.onosproject.calendar;
17 17
18 -import java.net.URI; 18 +import org.onlab.packet.Ethernet;
19 -import java.util.concurrent.CountDownLatch; 19 +import org.onlab.rest.BaseResource;
20 -import java.util.concurrent.TimeUnit; 20 +import org.onlab.util.Tools;
21 - 21 +import org.onosproject.core.ApplicationId;
22 +import org.onosproject.core.CoreService;
22 import org.onosproject.net.ConnectPoint; 23 import org.onosproject.net.ConnectPoint;
23 import org.onosproject.net.DeviceId; 24 import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.HostId;
26 +import org.onosproject.net.flow.DefaultTrafficSelector;
27 +import org.onosproject.net.flow.TrafficSelector;
28 +import org.onosproject.net.flow.TrafficTreatment;
29 +import org.onosproject.net.intent.ConnectivityIntent;
30 +import org.onosproject.net.intent.Constraint;
31 +import org.onosproject.net.intent.HostToHostIntent;
24 import org.onosproject.net.intent.Intent; 32 import org.onosproject.net.intent.Intent;
25 import org.onosproject.net.intent.IntentEvent; 33 import org.onosproject.net.intent.IntentEvent;
26 import org.onosproject.net.intent.IntentListener; 34 import org.onosproject.net.intent.IntentListener;
27 import org.onosproject.net.intent.IntentService; 35 import org.onosproject.net.intent.IntentService;
28 import org.onosproject.net.intent.IntentState; 36 import org.onosproject.net.intent.IntentState;
29 -import org.onlab.rest.BaseResource; 37 +import org.onosproject.net.intent.Key;
38 +import org.onosproject.net.intent.TwoWayP2PIntent;
39 +import org.onosproject.net.intent.constraint.BandwidthConstraint;
40 +import org.onosproject.net.intent.constraint.LatencyConstraint;
41 +import org.onosproject.net.resource.Bandwidth;
42 +import org.slf4j.Logger;
30 43
31 -import javax.ws.rs.POST;
32 import javax.ws.rs.DELETE; 44 import javax.ws.rs.DELETE;
45 +import javax.ws.rs.POST;
46 +import javax.ws.rs.PUT;
33 import javax.ws.rs.PathParam; 47 import javax.ws.rs.PathParam;
34 import javax.ws.rs.core.Response; 48 import javax.ws.rs.core.Response;
35 - 49 +import java.net.URI;
36 -import org.onosproject.core.ApplicationId; 50 +import java.time.Duration;
37 -import org.onosproject.core.CoreService; 51 +import java.time.temporal.ChronoUnit;
38 -import org.onosproject.net.flow.DefaultTrafficSelector; 52 +import java.util.LinkedList;
39 -import org.onosproject.net.flow.TrafficSelector; 53 +import java.util.List;
40 -import org.onosproject.net.flow.TrafficTreatment; 54 +import java.util.concurrent.CountDownLatch;
41 -import org.onosproject.net.intent.PointToPointIntent; 55 +import java.util.concurrent.TimeUnit;
42 -import org.onlab.packet.Ethernet;
43 56
44 import static org.onosproject.net.PortNumber.portNumber; 57 import static org.onosproject.net.PortNumber.portNumber;
45 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder; 58 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
46 - 59 +import static org.onosproject.net.intent.IntentState.*;
47 -import static org.onosproject.net.intent.IntentState.FAILED;
48 -import static org.onosproject.net.intent.IntentState.INSTALLED;
49 -import static org.onosproject.net.intent.IntentState.WITHDRAWN;
50 import static org.slf4j.LoggerFactory.getLogger; 60 import static org.slf4j.LoggerFactory.getLogger;
51 61
52 -import org.slf4j.Logger;
53 -
54 /** 62 /**
55 * Web resource for triggering calendared intents. 63 * Web resource for triggering calendared intents.
56 */ 64 */
...@@ -58,80 +66,262 @@ import org.slf4j.Logger; ...@@ -58,80 +66,262 @@ import org.slf4j.Logger;
58 public class BandwidthCalendarResource extends BaseResource { 66 public class BandwidthCalendarResource extends BaseResource {
59 67
60 private static final Logger log = getLogger(BandwidthCalendarResource.class); 68 private static final Logger log = getLogger(BandwidthCalendarResource.class);
61 - private static final long TIMEOUT = 5; // seconds 69 + private static final long TIMEOUT = 10; // seconds
70 +
71 + private static final String INVALID_PARAMETER = "INVALID_PARAMETER\n";
72 + private static final String OPERATION_INSTALLED = "INSTALLED\n";
73 + private static final String OPERATION_FAILED = "FAILED\n";
74 + private static final String OPERATION_WITHDRAWN = "WITHDRAWN\n";
62 75
63 - @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}") 76 + /**
77 + * Setup a bi-directional path with constraints between switch to switch.
78 + * Switch is identified by DPID.
79 + *
80 + * @param src the path source (DPID or hostID)
81 + * @param dst the path destination (DPID or hostID)
82 + * @param srcPort the source port (-1 if src/dest is a host)
83 + * @param dstPort the destination port (-1 if src/dest is a host)
84 + * @param bandwidth the bandwidth (mbps) requirement for the path
85 + * @param latency the latency (micro sec) requirement for the path
86 + * @return intent key if successful,
87 + * server error message or "FAILED" if failed to create or submit intent
88 + */
89 + @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}/{latency}")
64 @POST 90 @POST
65 - public Response createIntent(@PathParam("src") String src, 91 + // TODO could allow applications to provide optional key
92 + // ... if you do, you will need to change from LongKeys to StringKeys
93 + public Response setupPath(@PathParam("src") String src,
94 + @PathParam("dst") String dst,
95 + @PathParam("srcPort") String srcPort,
96 + @PathParam("dstPort") String dstPort,
97 + @PathParam("bandwidth") String bandwidth,
98 + @PathParam("latency") String latency) {
99 +
100 + log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} " +
101 + "BW = {} latency = {}",
102 + src, srcPort, dst, dstPort, bandwidth, latency);
103 +
104 + if (src == null || dst == null || srcPort == null || dstPort == null) {
105 + return Response.ok(INVALID_PARAMETER).build();
106 + }
107 +
108 + Long bandwidthL = 0L;
109 + Long latencyL = 0L;
110 + try {
111 + bandwidthL = Long.parseLong(bandwidth, 10);
112 + latencyL = Long.parseLong(latency, 10);
113 + } catch (Exception e) {
114 + return Response.ok(INVALID_PARAMETER).build();
115 + }
116 +
117 + Intent intent = createIntent(null, src, dst, srcPort, dstPort, bandwidthL, latencyL);
118 + try {
119 + if (submitIntent(intent)) {
120 + return Response.ok(intent.key() + "\n").build();
121 + } else {
122 + return Response.ok(OPERATION_FAILED).build();
123 + }
124 + } catch (Exception e) {
125 + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
126 + }
127 + }
128 +
129 + /**
130 + * Modify a bi-directional path's bandwidth.
131 + *
132 + * @param intentKey the path intent key
133 + * @param src the path source (DPID or hostID)
134 + * @param dst the path destination (DPID or hostID)
135 + * @param srcPort the source port (-1 if src/dest is a host)
136 + * @param dstPort the destination port (-1 if src/dest is a host)
137 + * @param bandwidth the bandwidth (mbps) requirement for the path
138 + * @return @return Intent state, "INSTALLED", if successful,
139 + * server error message or "FAILED" if failed to modify any direction intent
140 + */
141 + @javax.ws.rs.Path("/{intentKey}/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}")
142 + @PUT
143 + public Response modifyBandwidth(@PathParam("intentKey") String intentKey,
144 + @PathParam("src") String src,
66 @PathParam("dst") String dst, 145 @PathParam("dst") String dst,
67 @PathParam("srcPort") String srcPort, 146 @PathParam("srcPort") String srcPort,
68 @PathParam("dstPort") String dstPort, 147 @PathParam("dstPort") String dstPort,
69 @PathParam("bandwidth") String bandwidth) { 148 @PathParam("bandwidth") String bandwidth) {
70 149
71 - log.info("Receiving Create Intent request..."); 150 + log.info("Modify bw for intentKey = {}; src = {}; dst = {};" +
72 - log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} BW = {}", 151 + "srcPort = {}; dstPort = {}; with new bandwidth = {}",
73 - src, srcPort, dst, dstPort, bandwidth); 152 + intentKey, src, dst, srcPort, dstPort, bandwidth);
153 +
154 + if (src == null || dst == null || srcPort == null || dstPort == null) {
155 + return Response.ok(INVALID_PARAMETER).build();
156 + }
157 +
158 + Long bandwidthL = 0L;
159 + try {
160 + bandwidthL = Long.parseLong(bandwidth, 10);
161 + } catch (Exception e) {
162 + return Response.ok(INVALID_PARAMETER).build();
163 + }
74 164
75 IntentService service = get(IntentService.class); 165 IntentService service = get(IntentService.class);
166 + Intent originalIntent
167 + = service.getIntent(Key.of(Tools.fromHex(intentKey.replace("0x", "")), appId()));
76 168
77 - ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); 169 + if (originalIntent == null) {
78 - ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort)); 170 + return Response.status(Response.Status.NOT_FOUND).build();
171 + }
172 +
173 + // get the latency constraint from the original intent
174 + Long latencyL = 0L;
175 + if (originalIntent instanceof ConnectivityIntent) {
176 + ConnectivityIntent connectivityIntent = (ConnectivityIntent) originalIntent;
177 + for (Constraint constraint : connectivityIntent.constraints()) {
178 + if (constraint instanceof LatencyConstraint) {
179 + latencyL = ((LatencyConstraint) constraint).latency().get(ChronoUnit.MICROS);
180 + }
181 + }
182 + }
183 +
184 + Intent newIntent = createIntent(originalIntent.key(), src, dst,
185 + srcPort, dstPort, bandwidthL, latencyL);
186 + try {
187 + if (submitIntent(newIntent)) {
188 + return Response.ok(OPERATION_INSTALLED).build();
189 + } else {
190 + return Response.ok(OPERATION_FAILED).build();
191 + }
192 + } catch (Exception e) {
193 + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
194 + }
195 + }
196 +
197 +
198 + /**
199 + * Create an Intent for a bidirectional path with constraints.
200 + *
201 + * @param key optional intent key
202 + * @param src the path source (DPID or hostID)
203 + * @param dst the path destination (DPID or hostID)
204 + * @param srcPort the source port (-1 if src/dest is a host)
205 + * @param dstPort the destination port (-1 if src/dest is a host)
206 + * @param bandwidth the bandwidth (mbps) requirement for the path
207 + * @param latency the latency (micro sec) requirement for the path
208 + * @return the appropriate intent
209 + */
210 + private Intent createIntent(Key key,
211 + String src,
212 + String dst,
213 + String srcPort,
214 + String dstPort,
215 + Long bandwidth,
216 + Long latency) {
79 217
80 TrafficSelector selector = buildTrafficSelector(); 218 TrafficSelector selector = buildTrafficSelector();
81 TrafficTreatment treatment = builder().build(); 219 TrafficTreatment treatment = builder().build();
82 220
83 - PointToPointIntent intentP2P = 221 + final Constraint constraintBandwidth =
84 - new PointToPointIntent(appId(), selector, treatment, 222 + new BandwidthConstraint(Bandwidth.mbps(bandwidth));
85 - srcPoint, dstPoint); 223 + final Constraint constraintLatency =
224 + new LatencyConstraint(Duration.of(latency, ChronoUnit.MICROS));
225 + final List<Constraint> constraints = new LinkedList<>();
226 +
227 + constraints.add(constraintBandwidth);
228 + constraints.add(constraintLatency);
229 +
230 + if (srcPort.equals("-1")) {
231 + HostId srcPoint = HostId.hostId(src);
232 + HostId dstPoint = HostId.hostId(dst);
233 + return new HostToHostIntent(appId(), key, srcPoint, dstPoint,
234 + selector, treatment, constraints);
235 + } else {
236 + ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
237 + ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
238 + return new TwoWayP2PIntent(appId(), key, srcPoint, dstPoint,
239 + selector, treatment, constraints);
240 + }
241 + }
242 +
243 +
244 + /**
245 + * Synchronously submits an intent to the Intent Service.
246 + *
247 + * @param intent intent to submit
248 + * @return true if operation succeed, false otherwise
249 + */
250 + private boolean submitIntent(Intent intent)
251 + throws InterruptedException {
252 + IntentService service = get(IntentService.class);
86 253
87 CountDownLatch latch = new CountDownLatch(1); 254 CountDownLatch latch = new CountDownLatch(1);
88 - InternalIntentListener listener = new InternalIntentListener(intentP2P, service, latch); 255 + InternalIntentListener listener = new InternalIntentListener(intent, service, latch);
89 service.addListener(listener); 256 service.addListener(listener);
90 - service.submit(intentP2P); 257 + service.submit(intent);
91 - try { 258 + log.info("Submitted Calendar App intent and waiting: {}", intent);
92 - if (latch.await(TIMEOUT, TimeUnit.SECONDS)) { 259 + if (latch.await(TIMEOUT, TimeUnit.SECONDS) &&
93 - log.info("Submitted Calendar App intent: src = {}; dst = {}; " + 260 + listener.getState() == INSTALLED) {
94 - "srcPort = {}; dstPort = {}; intentID = {}", 261 + return true;
95 - src, dst, srcPort, dstPort, intentP2P.id());
96 - String reply = intentP2P.id() + " " + listener.getState() + "\n";
97 - return Response.ok(reply).build();
98 - }
99 - } catch (InterruptedException e) {
100 - log.warn("Interrupted while waiting for intent {} status", intentP2P.id());
101 } 262 }
102 - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); 263 + return false;
103 } 264 }
104 265
105 - @javax.ws.rs.Path("/cancellation/{intentId}") 266 + /**
267 + * Remove a bi-directional path with created intent key.
268 + *
269 + * @param intentKey the string key for the intent to remove
270 + * @return Intent state, "WITHDRAWN", if successful,
271 + * server error message or FAILED" if any direction intent remove failed
272 + */
273 + @javax.ws.rs.Path("/{intentKey}")
106 @DELETE 274 @DELETE
107 - public Response withdrawIntent(@PathParam("intentId") String intentId) { 275 + public Response removePath(@PathParam("intentKey") String intentKey) {
108 - log.info("Receiving Teardown request for {}", intentId); 276 +
109 - IntentService service = get(IntentService.class); 277 + log.info("Receiving tear down request for {}", intentKey);
110 - // TODO: there needs to be an app id and key here 278 +
111 - /* 279 + if (intentKey == null) {
112 - Intent intent = service.getIntent(IntentId.valueOf(Long.parseLong(intentId))); 280 + return Response.ok(INVALID_PARAMETER).build();
113 - if (intent != null) {
114 - service.withdraw(intent);
115 - String reply = "ok\n";
116 - return Response.ok(reply).build();
117 } 281 }
118 - */ 282 +
283 + IntentService service = get(IntentService.class);
284 + Intent intent = service.getIntent(Key.of(Tools.fromHex(intentKey.replace("0x", "")), appId()));
285 +
286 + if (intent == null) {
119 return Response.status(Response.Status.NOT_FOUND).build(); 287 return Response.status(Response.Status.NOT_FOUND).build();
120 } 288 }
121 289
122 - @javax.ws.rs.Path("/modification/{intentId}/{bandwidth}") 290 + try {
123 - @POST 291 + if (withdrawIntent(intent)) {
124 - public Response modifyBandwidth(@PathParam("intentId") String intentId, 292 + return Response.ok(OPERATION_WITHDRAWN).build();
125 - @PathParam("bandwidth") String bandwidth) { 293 + } else {
294 + return Response.ok(OPERATION_FAILED).build();
295 + }
296 + } catch (Exception e) {
297 + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
298 + }
299 + }
126 300
127 - log.info("Receiving Modify request..."); 301 + /**
128 - log.info("Modify bw for intentId = {} with new bandwidth = {}", intentId, bandwidth); 302 + * Synchronously withdraws an intent to the Intent Service.
303 + *
304 + * @param intent intent to submit
305 + * @return true if operation succeed, false otherwise
306 + */
307 + private boolean withdrawIntent(Intent intent)
308 + throws InterruptedException {
309 + IntentService service = get(IntentService.class);
129 310
130 - String reply = "ok\n"; 311 + CountDownLatch latch = new CountDownLatch(1);
131 - return Response.ok(reply).build(); 312 + InternalIntentListener listener = new InternalIntentListener(intent, service, latch);
313 + service.addListener(listener);
314 + service.withdraw(intent);
315 + log.info("Withdrawing intent and waiting: {}", intent);
316 + if (latch.await(TIMEOUT, TimeUnit.SECONDS) &&
317 + listener.getState() == WITHDRAWN) {
318 + return true;
319 + }
320 + return false;
132 } 321 }
133 322
134 - private TrafficSelector buildTrafficSelector() { 323 +
324 + private static TrafficSelector buildTrafficSelector() {
135 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); 325 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
136 Short ethType = Ethernet.TYPE_IPV4; 326 Short ethType = Ethernet.TYPE_IPV4;
137 327
...@@ -140,7 +330,7 @@ public class BandwidthCalendarResource extends BaseResource { ...@@ -140,7 +330,7 @@ public class BandwidthCalendarResource extends BaseResource {
140 return selectorBuilder.build(); 330 return selectorBuilder.build();
141 } 331 }
142 332
143 - private DeviceId deviceId(String dpid) { 333 + private static DeviceId deviceId(String dpid) {
144 return DeviceId.deviceId(URI.create("of:" + dpid)); 334 return DeviceId.deviceId(URI.create("of:" + dpid));
145 } 335 }
146 336
...@@ -168,10 +358,10 @@ public class BandwidthCalendarResource extends BaseResource { ...@@ -168,10 +358,10 @@ public class BandwidthCalendarResource extends BaseResource {
168 state = service.getIntentState(intent.key()); 358 state = service.getIntentState(intent.key());
169 if (state == INSTALLED || state == FAILED || state == WITHDRAWN) { 359 if (state == INSTALLED || state == FAILED || state == WITHDRAWN) {
170 latch.countDown(); 360 latch.countDown();
171 - }
172 service.removeListener(this); 361 service.removeListener(this);
173 } 362 }
174 } 363 }
364 + }
175 365
176 public IntentState getState() { 366 public IntentState getState() {
177 return state; 367 return state;
......
1 +/*
2 + * Copyright 2015 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;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import com.google.common.collect.ImmutableList;
20 +import org.onosproject.core.ApplicationId;
21 +import org.onosproject.net.ConnectPoint;
22 +import org.onosproject.net.HostId;
23 +import org.onosproject.net.Link;
24 +import org.onosproject.net.flow.DefaultTrafficSelector;
25 +import org.onosproject.net.flow.DefaultTrafficTreatment;
26 +import org.onosproject.net.flow.TrafficSelector;
27 +import org.onosproject.net.flow.TrafficTreatment;
28 +import org.onosproject.net.intent.constraint.LinkTypeConstraint;
29 +
30 +import java.util.Collections;
31 +import java.util.List;
32 +
33 +import static com.google.common.base.Preconditions.checkNotNull;
34 +
35 +/**
36 + * Abstraction of bidirectional connectivity between two points in the network.
37 + */
38 +public final class TwoWayP2PIntent extends ConnectivityIntent {
39 +
40 + private final ConnectPoint one;
41 + private final ConnectPoint two;
42 +
43 + /**
44 + * Creates a new host-to-host intent with the supplied host pair and no
45 + * other traffic selection or treatment criteria.
46 + *
47 + * @param appId application identifier
48 + * @param one first host
49 + * @param two second host
50 + * @throws NullPointerException if {@code one} or {@code two} is null.
51 + */
52 + public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two) {
53 + this(appId, one, two,
54 + DefaultTrafficSelector.builder().build(),
55 + DefaultTrafficTreatment.builder().build(),
56 + ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)));
57 + }
58 +
59 + /**
60 + * Creates a new host-to-host intent with the supplied host pair.
61 + *
62 + * @param appId application identifier
63 + * @param one first host
64 + * @param two second host
65 + * @param selector action
66 + * @param treatment ingress port
67 + * @throws NullPointerException if {@code one} or {@code two} is null.
68 + */
69 + public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two,
70 + TrafficSelector selector,
71 + TrafficTreatment treatment) {
72 + this(appId, one, two, selector, treatment,
73 + ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)));
74 + }
75 +
76 + /**
77 + * Creates a new host-to-host intent with the supplied host pair.
78 + *
79 + * @param appId application identifier
80 + * @param one first host
81 + * @param two second host
82 + * @param selector action
83 + * @param treatment ingress port
84 + * @param constraints optional prioritized list of path selection constraints
85 + * @throws NullPointerException if {@code one} or {@code two} is null.
86 + */
87 + public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two,
88 + TrafficSelector selector,
89 + TrafficTreatment treatment,
90 + List<Constraint> constraints) {
91 + this(appId, null, one, two, selector, treatment, constraints);
92 + }
93 + /**
94 + * Creates a new host-to-host intent with the supplied host pair.
95 + *
96 + * @param appId application identifier
97 + * @param key intent key
98 + * @param one first host
99 + * @param two second host
100 + * @param selector action
101 + * @param treatment ingress port
102 + * @param constraints optional prioritized list of path selection constraints
103 + * @throws NullPointerException if {@code one} or {@code two} is null.
104 + */
105 + public TwoWayP2PIntent(ApplicationId appId, Key key,
106 + ConnectPoint one, ConnectPoint two,
107 + TrafficSelector selector,
108 + TrafficTreatment treatment,
109 + List<Constraint> constraints) {
110 + super(appId, key, Collections.emptyList(), selector, treatment, constraints);
111 +
112 + // TODO: consider whether the case one and two are same is allowed
113 + this.one = checkNotNull(one);
114 + this.two = checkNotNull(two);
115 +
116 + }
117 +
118 + private static HostId min(HostId one, HostId two) {
119 + return one.hashCode() < two.hashCode() ? one : two;
120 + }
121 +
122 + private static HostId max(HostId one, HostId two) {
123 + return one.hashCode() >= two.hashCode() ? one : two;
124 + }
125 +
126 + /**
127 + * Returns identifier of the first host.
128 + *
129 + * @return first host identifier
130 + */
131 + public ConnectPoint one() {
132 + return one;
133 + }
134 +
135 + /**
136 + * Returns identifier of the second host.
137 + *
138 + * @return second host identifier
139 + */
140 + public ConnectPoint two() {
141 + return two;
142 + }
143 +
144 + @Override
145 + public String toString() {
146 + return MoreObjects.toStringHelper(getClass())
147 + .add("id", id())
148 + .add("key", key())
149 + .add("appId", appId())
150 + .add("resources", resources())
151 + .add("selector", selector())
152 + .add("treatment", treatment())
153 + .add("constraints", constraints())
154 + .add("one", one)
155 + .add("two", two)
156 + .toString();
157 + }
158 +
159 +}
1 +/*
2 + * Copyright 2015 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.impl;
17 +
18 +import com.google.common.collect.Lists;
19 +import org.apache.felix.scr.annotations.Activate;
20 +import org.apache.felix.scr.annotations.Component;
21 +import org.apache.felix.scr.annotations.Deactivate;
22 +import org.onosproject.net.intent.Intent;
23 +import org.onosproject.net.intent.PointToPointIntent;
24 +import org.onosproject.net.intent.TwoWayP2PIntent;
25 +import org.onosproject.net.resource.LinkResourceAllocations;
26 +
27 +import java.util.List;
28 +import java.util.Set;
29 +
30 +/**
31 + * A intent compiler for {@link org.onosproject.net.intent.TwoWayP2PIntent}.
32 + */
33 +@Component(immediate = true)
34 +public class TwoWayP2PIntentCompiler
35 + extends ConnectivityIntentCompiler<TwoWayP2PIntent> {
36 +
37 + @Activate
38 + public void activate() {
39 + intentManager.registerCompiler(TwoWayP2PIntent.class, this);
40 + }
41 +
42 + @Deactivate
43 + public void deactivate() {
44 + intentManager.unregisterCompiler(TwoWayP2PIntent.class);
45 + }
46 +
47 + @Override
48 + public List<Intent> compile(TwoWayP2PIntent intent, List<Intent> installable,
49 + Set<LinkResourceAllocations> resources) {
50 + return Lists.newArrayList(
51 + new PointToPointIntent(intent.appId(), intent.key(),
52 + intent.selector(), intent.treatment(),
53 + intent.one(), intent.two(),
54 + intent.constraints()),
55 + new PointToPointIntent(intent.appId(), intent.key(),
56 + intent.selector(), intent.treatment(),
57 + intent.two(), intent.one(),
58 + intent.constraints()));
59 +
60 + }
61 +}