blob: f6a0f04dddad42cc9175fe6ca9f625971cdae3bb [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 */
Thomas Vachuska140d5852014-10-16 12:17:45 -070016package org.onlab.onos.calendar;
17
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
Ray Milkeycaa450b2014-10-29 15:54:24 -070022import org.onlab.onos.net.ConnectPoint;
23import org.onlab.onos.net.DeviceId;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080024import org.onlab.onos.net.intent.Intent;
25import org.onlab.onos.net.intent.IntentEvent;
26import org.onlab.onos.net.intent.IntentId;
27import org.onlab.onos.net.intent.IntentListener;
Hongtao Yin621c57a2014-10-30 14:28:03 -070028import org.onlab.onos.net.intent.IntentService;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080029import org.onlab.onos.net.intent.IntentState;
Hongtao Yin621c57a2014-10-30 14:28:03 -070030import org.onlab.rest.BaseResource;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080031
Hongtao Yin621c57a2014-10-30 14:28:03 -070032import javax.ws.rs.POST;
33import javax.ws.rs.DELETE;
34import javax.ws.rs.PathParam;
35import javax.ws.rs.core.Response;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080036
Hongtao Yin621c57a2014-10-30 14:28:03 -070037import org.onlab.onos.core.ApplicationId;
38import org.onlab.onos.core.CoreService;
Ray Milkeycaa450b2014-10-29 15:54:24 -070039import org.onlab.onos.net.flow.DefaultTrafficSelector;
40import org.onlab.onos.net.flow.TrafficSelector;
41import org.onlab.onos.net.flow.TrafficTreatment;
Hongtao Yin621c57a2014-10-30 14:28:03 -070042import org.onlab.onos.net.intent.PointToPointIntent;
Ray Milkeycaa450b2014-10-29 15:54:24 -070043import org.onlab.packet.Ethernet;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080044
Thomas Vachuska140d5852014-10-16 12:17:45 -070045import static org.onlab.onos.net.PortNumber.portNumber;
Ray Milkeycaa450b2014-10-29 15:54:24 -070046import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
Thomas Vachuska140d5852014-10-16 12:17:45 -070047
Thomas Vachuska56d1a702014-11-11 19:14:57 -080048import static org.onlab.onos.net.intent.IntentState.FAILED;
49import static org.onlab.onos.net.intent.IntentState.INSTALLED;
50import static org.onlab.onos.net.intent.IntentState.WITHDRAWN;
Hongtao Yin621c57a2014-10-30 14:28:03 -070051import static org.slf4j.LoggerFactory.getLogger;
Thomas Vachuska56d1a702014-11-11 19:14:57 -080052
Hongtao Yin621c57a2014-10-30 14:28:03 -070053import org.slf4j.Logger;
54
Thomas Vachuska140d5852014-10-16 12:17:45 -070055/**
56 * Web resource for triggering calendared intents.
57 */
Hongtao Yin621c57a2014-10-30 14:28:03 -070058@javax.ws.rs.Path("intent")
Thomas Vachuska140d5852014-10-16 12:17:45 -070059public class BandwidthCalendarResource extends BaseResource {
60
Hongtao Yin621c57a2014-10-30 14:28:03 -070061 private static final Logger log = getLogger(BandwidthCalendarResource.class);
Thomas Vachuska56d1a702014-11-11 19:14:57 -080062 private static final long TIMEOUT = 5; // seconds
Hongtao Yin621c57a2014-10-30 14:28:03 -070063
64 @javax.ws.rs.Path("/{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}")
Thomas Vachuska140d5852014-10-16 12:17:45 -070065 @POST
Thomas Vachuska140d5852014-10-16 12:17:45 -070066 public Response createIntent(@PathParam("src") String src,
67 @PathParam("dst") String dst,
68 @PathParam("srcPort") String srcPort,
69 @PathParam("dstPort") String dstPort,
70 @PathParam("bandwidth") String bandwidth) {
Hongtao Yin621c57a2014-10-30 14:28:03 -070071
72 log.info("Receiving Create Intent request...");
73 log.info("Path Constraints: Src = {} SrcPort = {} Dest = {} DestPort = {} BW = {}",
Thomas Vachuska56d1a702014-11-11 19:14:57 -080074 src, srcPort, dst, dstPort, bandwidth);
Hongtao Yin621c57a2014-10-30 14:28:03 -070075
Thomas Vachuska140d5852014-10-16 12:17:45 -070076 IntentService service = get(IntentService.class);
77
78 ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
79 ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
80
Ray Milkeycaa450b2014-10-29 15:54:24 -070081 TrafficSelector selector = buildTrafficSelector();
82 TrafficTreatment treatment = builder().build();
83
Hongtao Yin621c57a2014-10-30 14:28:03 -070084 PointToPointIntent intentP2P =
Thomas Vachuska56d1a702014-11-11 19:14:57 -080085 new PointToPointIntent(appId(), selector, treatment,
86 srcPoint, dstPoint);
Ray Milkeycaa450b2014-10-29 15:54:24 -070087
Thomas Vachuska56d1a702014-11-11 19:14:57 -080088 CountDownLatch latch = new CountDownLatch(1);
89 InternalIntentListener listener = new InternalIntentListener(intentP2P, service, latch);
90 service.addListener(listener);
91 service.submit(intentP2P);
92 try {
93 if (latch.await(TIMEOUT, TimeUnit.SECONDS)) {
94 log.info("Submitted Calendar App intent: src = {}; dst = {}; " +
95 "srcPort = {}; dstPort = {}; intentID = {}",
96 src, dst, srcPort, dstPort, intentP2P.id());
97 String reply = intentP2P.id() + " " + listener.getState() + "\n";
98 return Response.ok(reply).build();
99 }
100 } catch (InterruptedException e) {
101 log.warn("Interrupted while waiting for intent {} status", intentP2P.id());
102 }
103 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
Hongtao Yin621c57a2014-10-30 14:28:03 -0700104 }
105
106 @javax.ws.rs.Path("/cancellation/{intentId}")
107 @DELETE
108 public Response withdrawIntent(@PathParam("intentId") String intentId) {
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800109 log.info("Receiving Teardown request for {}", intentId);
110 IntentService service = get(IntentService.class);
111 Intent intent = service.getIntent(IntentId.valueOf(Long.parseLong(intentId)));
112 if (intent != null) {
113 service.withdraw(intent);
114 String reply = "ok\n";
115 return Response.ok(reply).build();
116 }
117 return Response.status(Response.Status.NOT_FOUND).build();
Hongtao Yin621c57a2014-10-30 14:28:03 -0700118 }
119
120 @javax.ws.rs.Path("/modification/{intentId}/{bandwidth}")
121 @POST
122 public Response modifyBandwidth(@PathParam("intentId") String intentId,
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800123 @PathParam("bandwidth") String bandwidth) {
Hongtao Yin621c57a2014-10-30 14:28:03 -0700124
125 log.info("Receiving Modify request...");
126 log.info("Modify bw for intentId = {} with new bandwidth = {}", intentId, bandwidth);
127
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800128 String reply = "ok\n";
Hongtao Yin621c57a2014-10-30 14:28:03 -0700129 return Response.ok(reply).build();
Thomas Vachuska140d5852014-10-16 12:17:45 -0700130 }
131
Ray Milkeycaa450b2014-10-29 15:54:24 -0700132 private TrafficSelector buildTrafficSelector() {
133 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
134 Short ethType = Ethernet.TYPE_IPV4;
135
136 selectorBuilder.matchEthType(ethType);
137
138 return selectorBuilder.build();
139 }
140
Thomas Vachuska140d5852014-10-16 12:17:45 -0700141 private DeviceId deviceId(String dpid) {
142 return DeviceId.deviceId(URI.create("of:" + dpid));
143 }
144
Ray Milkeycaa450b2014-10-29 15:54:24 -0700145 protected ApplicationId appId() {
146 return get(CoreService.class).registerApplication("org.onlab.onos.calendar");
147 }
Thomas Vachuska56d1a702014-11-11 19:14:57 -0800148
149 // Auxiliary listener to wait until the given intent reaches the installed or failed states.
150 private final class InternalIntentListener implements IntentListener {
151 private final Intent intent;
152 private final IntentService service;
153 private final CountDownLatch latch;
154 private IntentState state;
155
156 private InternalIntentListener(Intent intent, IntentService service,
157 CountDownLatch latch) {
158 this.intent = intent;
159 this.service = service;
160 this.latch = latch;
161 }
162
163 @Override
164 public void event(IntentEvent event) {
165 if (event.subject().equals(intent)) {
166 state = service.getIntentState(intent.id());
167 if (state == INSTALLED || state == FAILED || state == WITHDRAWN) {
168 latch.countDown();
169 }
170 service.removeListener(this);
171 }
172 }
173
174 public IntentState getState() {
175 return state;
176 }
177 }
Thomas Vachuska140d5852014-10-16 12:17:45 -0700178}