blob: 7e62953ae02b5f852b5c898f73fce50d7e336378 [file] [log] [blame]
Ray Milkey2b217142014-12-15 09:24:24 -08001/*
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 */
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
Ray Milkey67c22722015-03-09 15:48:57 -070044import static org.onosproject.net.intent.IntentState.FAILED;
45import static org.onosproject.net.intent.IntentState.WITHDRAWN;
46import static org.slf4j.LoggerFactory.getLogger;
47
Ray Milkey2b217142014-12-15 09:24:24 -080048/**
49 * REST resource for interacting with the inventory of intents.
50 */
51
52@Path("intents")
53public class IntentsWebResource extends AbstractWebResource {
Ray Milkey67c22722015-03-09 15:48:57 -070054 private static final Logger log = getLogger(IntentsWebResource.class);
55 private static final int WITHDRAW_EVENT_TIMEOUT_SECONDS = 5;
56
Ray Milkey2b217142014-12-15 09:24:24 -080057 public static final String INTENT_NOT_FOUND = "Intent is not found";
58
59 /**
60 * Gets an array containing all the intents in the system.
61 *
62 * @return array of all the intents in the system
63 */
64 @GET
65 @Produces(MediaType.APPLICATION_JSON)
66 public Response getIntents() {
67 final Iterable<Intent> intents = get(IntentService.class).getIntents();
68 final ObjectNode root = encodeArray(Intent.class, "intents", intents);
Ray Milkey3f025692015-01-26 11:15:41 -080069 return ok(root).build();
Ray Milkey2b217142014-12-15 09:24:24 -080070 }
71
72 /**
73 * Gets a single intent by Id.
74 *
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080075 * @param appId the Application ID
76 * @param key the Intent key value to look up
Ray Milkey2b217142014-12-15 09:24:24 -080077 * @return intent data
78 */
79 @GET
80 @Produces(MediaType.APPLICATION_JSON)
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080081 @Path("{appId}/{key}")
82 public Response getIntentById(@PathParam("appId") Short appId,
83 @PathParam("key") String key) {
84 final ApplicationId app = get(CoreService.class).getAppId(appId);
85
86 Intent intent = get(IntentService.class).getIntent(Key.of(key, app));
87 if (intent == null) {
88 intent = get(IntentService.class)
Yuta HIGUCHI179f3772015-02-18 17:28:39 +090089 .getIntent(Key.of(Long.parseLong(key), app));
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080090 }
91 nullIsNotFound(intent, INTENT_NOT_FOUND);
92
Ray Milkeyc95bb9d2015-01-06 10:28:24 -080093 final ObjectNode root;
94 if (intent instanceof HostToHostIntent) {
95 root = codec(HostToHostIntent.class).encode((HostToHostIntent) intent, this);
96 } else if (intent instanceof PointToPointIntent) {
97 root = codec(PointToPointIntent.class).encode((PointToPointIntent) intent, this);
98 } else {
99 root = codec(Intent.class).encode(intent, this);
100 }
Ray Milkey3f025692015-01-26 11:15:41 -0800101 return ok(root).build();
Ray Milkey2b217142014-12-15 09:24:24 -0800102 }
Ray Milkey67c22722015-03-09 15:48:57 -0700103
104 class DeleteListener implements IntentListener {
105 final Key key;
106 final CountDownLatch latch;
107
108 DeleteListener(Key key, CountDownLatch latch) {
109 this.key = key;
110 this.latch = latch;
111 }
112
113 @Override
114 public void event(IntentEvent event) {
115 if (Objects.equals(event.subject().key(), key) &&
116 (event.type() == IntentEvent.Type.WITHDRAWN ||
117 event.type() == IntentEvent.Type.FAILED)) {
118 latch.countDown();
119 }
120 }
121 }
122
123 /**
124 * Uninstalls a single intent by Id.
125 *
126 * @param appId the Application ID
127 * @param keyString the Intent key value to look up
128 */
129 @DELETE
130 @Path("{appId}/{key}")
131 public void deleteIntentById(@PathParam("appId") Short appId,
132 @PathParam("key") String keyString) {
133 final ApplicationId app = get(CoreService.class).getAppId(appId);
134
135 Intent intent = get(IntentService.class).getIntent(Key.of(keyString, app));
136 IntentService service = get(IntentService.class);
137
138 if (intent == null) {
139 intent = service
140 .getIntent(Key.of(Long.parseLong(keyString), app));
141 }
142 if (intent == null) {
143 // No such intent. REST standards recommend a positive status code
144 // in this case.
145 return;
146 }
147
148
149 Key key = intent.key();
150
151 // set up latch and listener to track uninstall progress
152 CountDownLatch latch = new CountDownLatch(1);
153
154 IntentListener listener = new DeleteListener(key, latch);
155 service.addListener(listener);
156
157 try {
158 // request the withdraw
159 service.withdraw(intent);
160
161 try {
162 latch.await(WITHDRAW_EVENT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
163 } catch (InterruptedException e) {
164 log.info("REST Delete operation timed out waiting for intent {}", key);
165 }
166 // double check the state
167 IntentState state = service.getIntentState(key);
168 if (state == WITHDRAWN || state == FAILED) {
169 service.purge(intent);
170 }
171
172 } finally {
173 // clean up the listener
174 service.removeListener(listener);
175 }
176 }
177
Ray Milkey2b217142014-12-15 09:24:24 -0800178}