blob: 6c25482bd208a87f17b0ee22cd3a54908664772f [file] [log] [blame]
Ray Milkey2b217142014-12-15 09:24:24 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Ray Milkey2b217142014-12-15 09:24:24 -08003 *
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 */
16package org.onosproject.rest;
17
Ray Milkey67c22722015-03-09 15:48:57 -070018import java.util.Objects;
19import java.util.concurrent.CountDownLatch;
20import java.util.concurrent.TimeUnit;
21
22import javax.ws.rs.DELETE;
Ray Milkey2b217142014-12-15 09:24:24 -080023import javax.ws.rs.GET;
24import javax.ws.rs.Path;
25import javax.ws.rs.PathParam;
26import javax.ws.rs.Produces;
27import javax.ws.rs.core.MediaType;
28import javax.ws.rs.core.Response;
29
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
Ray Milkeyc95bb9d2015-01-06 10:28:24 -080032import org.onosproject.net.intent.HostToHostIntent;
Ray Milkey2b217142014-12-15 09:24:24 -080033import org.onosproject.net.intent.Intent;
Ray Milkey67c22722015-03-09 15:48:57 -070034import org.onosproject.net.intent.IntentEvent;
35import org.onosproject.net.intent.IntentListener;
Ray Milkey2b217142014-12-15 09:24:24 -080036import org.onosproject.net.intent.IntentService;
Ray Milkey67c22722015-03-09 15:48:57 -070037import org.onosproject.net.intent.IntentState;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080038import org.onosproject.net.intent.Key;
Ray Milkeyc95bb9d2015-01-06 10:28:24 -080039import org.onosproject.net.intent.PointToPointIntent;
Ray Milkey67c22722015-03-09 15:48:57 -070040import org.slf4j.Logger;
Ray Milkey2b217142014-12-15 09:24:24 -080041
42import com.fasterxml.jackson.databind.node.ObjectNode;
43
Thomas Vachuskaf8cac482015-04-08 19:40:12 -070044import static org.onlab.util.Tools.nullIsNotFound;
Ray Milkey67c22722015-03-09 15:48:57 -070045import static org.onosproject.net.intent.IntentState.FAILED;
46import static org.onosproject.net.intent.IntentState.WITHDRAWN;
47import static org.slf4j.LoggerFactory.getLogger;
48
Ray Milkey2b217142014-12-15 09:24:24 -080049/**
50 * REST resource for interacting with the inventory of intents.
51 */
52
53@Path("intents")
54public class IntentsWebResource extends AbstractWebResource {
Ray Milkey67c22722015-03-09 15:48:57 -070055 private static final Logger log = getLogger(IntentsWebResource.class);
56 private static final int WITHDRAW_EVENT_TIMEOUT_SECONDS = 5;
57
Ray Milkey2b217142014-12-15 09:24:24 -080058 public static final String INTENT_NOT_FOUND = "Intent is not found";
59
60 /**
61 * Gets an array containing all the intents in the system.
62 *
63 * @return array of all the intents in the system
64 */
65 @GET
66 @Produces(MediaType.APPLICATION_JSON)
67 public Response getIntents() {
68 final Iterable<Intent> intents = get(IntentService.class).getIntents();
69 final ObjectNode root = encodeArray(Intent.class, "intents", intents);
Ray Milkey3f025692015-01-26 11:15:41 -080070 return ok(root).build();
Ray Milkey2b217142014-12-15 09:24:24 -080071 }
72
73 /**
74 * Gets a single intent by Id.
75 *
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080076 * @param appId the Application ID
77 * @param key the Intent key value to look up
Ray Milkey2b217142014-12-15 09:24:24 -080078 * @return intent data
79 */
80 @GET
81 @Produces(MediaType.APPLICATION_JSON)
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080082 @Path("{appId}/{key}")
83 public Response getIntentById(@PathParam("appId") Short appId,
84 @PathParam("key") String key) {
85 final ApplicationId app = get(CoreService.class).getAppId(appId);
86
87 Intent intent = get(IntentService.class).getIntent(Key.of(key, app));
88 if (intent == null) {
89 intent = get(IntentService.class)
Yuta HIGUCHI179f3772015-02-18 17:28:39 +090090 .getIntent(Key.of(Long.parseLong(key), app));
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080091 }
92 nullIsNotFound(intent, INTENT_NOT_FOUND);
93
Ray Milkeyc95bb9d2015-01-06 10:28:24 -080094 final ObjectNode root;
95 if (intent instanceof HostToHostIntent) {
96 root = codec(HostToHostIntent.class).encode((HostToHostIntent) intent, this);
97 } else if (intent instanceof PointToPointIntent) {
98 root = codec(PointToPointIntent.class).encode((PointToPointIntent) intent, this);
99 } else {
100 root = codec(Intent.class).encode(intent, this);
101 }
Ray Milkey3f025692015-01-26 11:15:41 -0800102 return ok(root).build();
Ray Milkey2b217142014-12-15 09:24:24 -0800103 }
Ray Milkey67c22722015-03-09 15:48:57 -0700104
105 class DeleteListener implements IntentListener {
106 final Key key;
107 final CountDownLatch latch;
108
109 DeleteListener(Key key, CountDownLatch latch) {
110 this.key = key;
111 this.latch = latch;
112 }
113
114 @Override
115 public void event(IntentEvent event) {
116 if (Objects.equals(event.subject().key(), key) &&
117 (event.type() == IntentEvent.Type.WITHDRAWN ||
118 event.type() == IntentEvent.Type.FAILED)) {
119 latch.countDown();
120 }
121 }
122 }
123
124 /**
125 * Uninstalls a single intent by Id.
126 *
127 * @param appId the Application ID
128 * @param keyString the Intent key value to look up
129 */
130 @DELETE
131 @Path("{appId}/{key}")
132 public void deleteIntentById(@PathParam("appId") Short appId,
133 @PathParam("key") String keyString) {
134 final ApplicationId app = get(CoreService.class).getAppId(appId);
135
136 Intent intent = get(IntentService.class).getIntent(Key.of(keyString, app));
137 IntentService service = get(IntentService.class);
138
139 if (intent == null) {
140 intent = service
141 .getIntent(Key.of(Long.parseLong(keyString), app));
142 }
143 if (intent == null) {
144 // No such intent. REST standards recommend a positive status code
145 // in this case.
146 return;
147 }
148
149
150 Key key = intent.key();
151
152 // set up latch and listener to track uninstall progress
153 CountDownLatch latch = new CountDownLatch(1);
154
155 IntentListener listener = new DeleteListener(key, latch);
156 service.addListener(listener);
157
158 try {
159 // request the withdraw
160 service.withdraw(intent);
161
162 try {
163 latch.await(WITHDRAW_EVENT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
164 } catch (InterruptedException e) {
165 log.info("REST Delete operation timed out waiting for intent {}", key);
166 }
167 // double check the state
168 IntentState state = service.getIntentState(key);
169 if (state == WITHDRAWN || state == FAILED) {
170 service.purge(intent);
171 }
172
173 } finally {
174 // clean up the listener
175 service.removeListener(listener);
176 }
177 }
178
Ray Milkey2b217142014-12-15 09:24:24 -0800179}