blob: 9d457b7cd608508d7e8a406a45577ec0c933fad6 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.calendar;
Thomas Vachuska140d5852014-10-16 12:17:45 -070017
Ray Milkeycaa450b2014-10-29 15:54:24 -070018import java.net.URI;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080019import java.util.concurrent.CountDownLatch;
20import java.util.concurrent.TimeUnit;
21
Brian O'Connorabafb502014-12-02 22:26:20 -080022import org.onosproject.net.ConnectPoint;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.intent.Intent;
25import org.onosproject.net.intent.IntentEvent;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.intent.IntentListener;
27import org.onosproject.net.intent.IntentService;
28import org.onosproject.net.intent.IntentState;
Hongtao Yin621c57a2014-10-30 14:28:03 -070029import org.onlab.rest.BaseResource;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080030
Hongtao Yin621c57a2014-10-30 14:28:03 -070031import javax.ws.rs.POST;
32import javax.ws.rs.DELETE;
33import javax.ws.rs.PathParam;
34import javax.ws.rs.core.Response;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080035
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.core.ApplicationId;
37import org.onosproject.core.CoreService;
38import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
41import org.onosproject.net.intent.PointToPointIntent;
Ray Milkeycaa450b2014-10-29 15:54:24 -070042import org.onlab.packet.Ethernet;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080043
Brian O'Connorabafb502014-12-02 22:26:20 -080044import static org.onosproject.net.PortNumber.portNumber;
45import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
Thomas Vachuska140d5852014-10-16 12:17:45 -070046
Brian O'Connorabafb502014-12-02 22:26:20 -080047import static org.onosproject.net.intent.IntentState.FAILED;
48import static org.onosproject.net.intent.IntentState.INSTALLED;
49import static org.onosproject.net.intent.IntentState.WITHDRAWN;
Hongtao Yin621c57a2014-10-30 14:28:03 -070050import static org.slf4j.LoggerFactory.getLogger;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080051
Hongtao Yin621c57a2014-10-30 14:28:03 -070052import org.slf4j.Logger;
53
Thomas Vachuska140d5852014-10-16 12:17:45 -070054/**
55 * Web resource for triggering calendared intents.
56 */
Hongtao Yin621c57a2014-10-30 14:28:03 -070057@javax.ws.rs.Path("intent")
Thomas Vachuska140d5852014-10-16 12:17:45 -070058public class BandwidthCalendarResource extends BaseResource {
59
Hongtao Yin621c57a2014-10-30 14:28:03 -070060 private static final Logger log = getLogger(BandwidthCalendarResource.class);
Thomas Vachuska56d1a702014-11-11 19:14:57 -080061 private static final long TIMEOUT = 5; // seconds
Hongtao Yin621c57a2014-10-30 14:28:03 -070062
63 @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}")
Thomas Vachuska140d5852014-10-16 12:17:45 -070064 @POST
Thomas Vachuska140d5852014-10-16 12:17:45 -070065 public Response createIntent(@PathParam("src") String src,
66 @PathParam("dst") String dst,
67 @PathParam("srcPort") String srcPort,
68 @PathParam("dstPort") String dstPort,
69 @PathParam("bandwidth") String bandwidth) {
Hongtao Yin621c57a2014-10-30 14:28:03 -070070
71 log.info("Receiving Create Intent request...");
72 log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} BW = {}",
Thomas Vachuska56d1a702014-11-11 19:14:57 -080073 src, srcPort, dst, dstPort, bandwidth);
Hongtao Yin621c57a2014-10-30 14:28:03 -070074
Thomas Vachuska140d5852014-10-16 12:17:45 -070075 IntentService service = get(IntentService.class);
76
77 ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
78 ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
79
Ray Milkeycaa450b2014-10-29 15:54:24 -070080 TrafficSelector selector = buildTrafficSelector();
81 TrafficTreatment treatment = builder().build();
82
Hongtao Yin621c57a2014-10-30 14:28:03 -070083 PointToPointIntent intentP2P =
Thomas Vachuska56d1a702014-11-11 19:14:57 -080084 new PointToPointIntent(appId(), selector, treatment,
85 srcPoint, dstPoint);
Ray Milkeycaa450b2014-10-29 15:54:24 -070086
Thomas Vachuska56d1a702014-11-11 19:14:57 -080087 CountDownLatch latch = new CountDownLatch(1);
88 InternalIntentListener listener = new InternalIntentListener(intentP2P, service, latch);
89 service.addListener(listener);
90 service.submit(intentP2P);
91 try {
92 if (latch.await(TIMEOUT, TimeUnit.SECONDS)) {
93 log.info("Submitted Calendar App intent: src = {}; dst = {}; " +
94 "srcPort = {}; dstPort = {}; intentID = {}",
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 }
102 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
Hongtao Yin621c57a2014-10-30 14:28:03 -0700103 }
104
105 @javax.ws.rs.Path("/cancellation/{intentId}")
106 @DELETE
107 public Response withdrawIntent(@PathParam("intentId") String intentId) {
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800108 log.info("Receiving Teardown request for {}", intentId);
109 IntentService service = get(IntentService.class);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800110 // TODO: there needs to be an app id and key here
111 /*
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800112 Intent intent = service.getIntent(IntentId.valueOf(Long.parseLong(intentId)));
113 if (intent != null) {
114 service.withdraw(intent);
115 String reply = "ok\n";
116 return Response.ok(reply).build();
117 }
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800118 */
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800119 return Response.status(Response.Status.NOT_FOUND).build();
Hongtao Yin621c57a2014-10-30 14:28:03 -0700120 }
121
122 @javax.ws.rs.Path("/modification/{intentId}/{bandwidth}")
123 @POST
124 public Response modifyBandwidth(@PathParam("intentId") String intentId,
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800125 @PathParam("bandwidth") String bandwidth) {
Hongtao Yin621c57a2014-10-30 14:28:03 -0700126
127 log.info("Receiving Modify request...");
128 log.info("Modify bw for intentId = {} with new bandwidth = {}", intentId, bandwidth);
129
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800130 String reply = "ok\n";
Hongtao Yin621c57a2014-10-30 14:28:03 -0700131 return Response.ok(reply).build();
Thomas Vachuska140d5852014-10-16 12:17:45 -0700132 }
133
Ray Milkeycaa450b2014-10-29 15:54:24 -0700134 private TrafficSelector buildTrafficSelector() {
135 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
136 Short ethType = Ethernet.TYPE_IPV4;
137
138 selectorBuilder.matchEthType(ethType);
139
140 return selectorBuilder.build();
141 }
142
Thomas Vachuska140d5852014-10-16 12:17:45 -0700143 private DeviceId deviceId(String dpid) {
144 return DeviceId.deviceId(URI.create("of:" + dpid));
145 }
146
Ray Milkeycaa450b2014-10-29 15:54:24 -0700147 protected ApplicationId appId() {
Brian O'Connorabafb502014-12-02 22:26:20 -0800148 return get(CoreService.class).registerApplication("org.onosproject.calendar");
Ray Milkeycaa450b2014-10-29 15:54:24 -0700149 }
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800150
151 // Auxiliary listener to wait until the given intent reaches the installed or failed states.
152 private final class InternalIntentListener implements IntentListener {
153 private final Intent intent;
154 private final IntentService service;
155 private final CountDownLatch latch;
156 private IntentState state;
157
158 private InternalIntentListener(Intent intent, IntentService service,
159 CountDownLatch latch) {
160 this.intent = intent;
161 this.service = service;
162 this.latch = latch;
163 }
164
165 @Override
166 public void event(IntentEvent event) {
167 if (event.subject().equals(intent)) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800168 state = service.getIntentState(intent.key());
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800169 if (state == INSTALLED || state == FAILED || state == WITHDRAWN) {
170 latch.countDown();
171 }
172 service.removeListener(this);
173 }
174 }
175
176 public IntentState getState() {
177 return state;
178 }
179 }
Thomas Vachuska140d5852014-10-16 12:17:45 -0700180}