Ray Milkey

ONOS-1242 - REST API for Withdrawing Intents

- upgraded Jersey to 1.19 for some REST bug fixes for Java 8
- consolidated references to Jersey by using the dependecy
  management plugin in the top level pom file.

Change-Id: Ic027f97f8fce6c673c9f2c02a92abaeedfedeb97
...@@ -71,9 +71,10 @@ ...@@ -71,9 +71,10 @@
71 description="ONOS 3rd party dependencies"> 71 description="ONOS 3rd party dependencies">
72 <feature>war</feature> 72 <feature>war</feature>
73 <feature>onos-thirdparty-base</feature> 73 <feature>onos-thirdparty-base</feature>
74 - <bundle>mvn:com.sun.jersey/jersey-core/1.18.1</bundle> 74 + <bundle>mvn:com.sun.jersey/jersey-core/1.19</bundle>
75 - <bundle>mvn:com.sun.jersey/jersey-server/1.18.1</bundle> 75 + <bundle>mvn:com.sun.jersey/jersey-server/1.19</bundle>
76 - <bundle>mvn:com.sun.jersey/jersey-servlet/1.18.1</bundle> 76 + <bundle>mvn:com.sun.jersey/jersey-servlet/1.19</bundle>
77 + <bundle>mvn:javax.ws.rs/jsr311-api/1.1.1</bundle>
77 </feature> 78 </feature>
78 79
79 <feature name="onos-api" version="@FEATURE-VERSION" 80 <feature name="onos-api" version="@FEATURE-VERSION"
......
...@@ -194,10 +194,22 @@ ...@@ -194,10 +194,22 @@
194 <dependency> 194 <dependency>
195 <groupId>com.sun.jersey</groupId> 195 <groupId>com.sun.jersey</groupId>
196 <artifactId>jersey-servlet</artifactId> 196 <artifactId>jersey-servlet</artifactId>
197 - <version>1.18.1</version> 197 + <version>1.19</version>
198 <scope>provided</scope> 198 <scope>provided</scope>
199 </dependency> 199 </dependency>
200 <dependency> 200 <dependency>
201 + <groupId>com.sun.jersey.jersey-test-framework</groupId>
202 + <artifactId>jersey-test-framework-core</artifactId>
203 + <version>1.19</version>
204 + <scope>test</scope>
205 + </dependency>
206 + <dependency>
207 + <groupId>com.sun.jersey.jersey-test-framework</groupId>
208 + <artifactId>jersey-test-framework-grizzly2</artifactId>
209 + <version>1.19</version>
210 + <scope>test</scope>
211 + </dependency>
212 + <dependency>
201 <groupId>com.fasterxml.jackson.core</groupId> 213 <groupId>com.fasterxml.jackson.core</groupId>
202 <artifactId>jackson-databind</artifactId> 214 <artifactId>jackson-databind</artifactId>
203 <version>2.4.2</version> 215 <version>2.4.2</version>
......
...@@ -33,19 +33,13 @@ ...@@ -33,19 +33,13 @@
33 33
34 <dependencies> 34 <dependencies>
35 <dependency> 35 <dependency>
36 - <groupId>com.sun.jersey</groupId>
37 - <artifactId>jersey-servlet</artifactId>
38 - </dependency>
39 - <dependency>
40 <groupId>com.sun.jersey.jersey-test-framework</groupId> 36 <groupId>com.sun.jersey.jersey-test-framework</groupId>
41 <artifactId>jersey-test-framework-core</artifactId> 37 <artifactId>jersey-test-framework-core</artifactId>
42 - <version>1.18.1</version>
43 <scope>test</scope> 38 <scope>test</scope>
44 </dependency> 39 </dependency>
45 <dependency> 40 <dependency>
46 <groupId>com.sun.jersey.jersey-test-framework</groupId> 41 <groupId>com.sun.jersey.jersey-test-framework</groupId>
47 <artifactId>jersey-test-framework-grizzly2</artifactId> 42 <artifactId>jersey-test-framework-grizzly2</artifactId>
48 - <version>1.18.1</version>
49 <scope>test</scope> 43 <scope>test</scope>
50 </dependency> 44 </dependency>
51 45
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
15 */ 15 */
16 package org.onosproject.rest; 16 package org.onosproject.rest;
17 17
18 +import java.util.Objects;
19 +import java.util.concurrent.CountDownLatch;
20 +import java.util.concurrent.TimeUnit;
21 +
22 +import javax.ws.rs.DELETE;
18 import javax.ws.rs.GET; 23 import javax.ws.rs.GET;
19 import javax.ws.rs.Path; 24 import javax.ws.rs.Path;
20 import javax.ws.rs.PathParam; 25 import javax.ws.rs.PathParam;
...@@ -26,18 +31,29 @@ import org.onosproject.core.ApplicationId; ...@@ -26,18 +31,29 @@ import org.onosproject.core.ApplicationId;
26 import org.onosproject.core.CoreService; 31 import org.onosproject.core.CoreService;
27 import org.onosproject.net.intent.HostToHostIntent; 32 import org.onosproject.net.intent.HostToHostIntent;
28 import org.onosproject.net.intent.Intent; 33 import org.onosproject.net.intent.Intent;
34 +import org.onosproject.net.intent.IntentEvent;
35 +import org.onosproject.net.intent.IntentListener;
29 import org.onosproject.net.intent.IntentService; 36 import org.onosproject.net.intent.IntentService;
37 +import org.onosproject.net.intent.IntentState;
30 import org.onosproject.net.intent.Key; 38 import org.onosproject.net.intent.Key;
31 import org.onosproject.net.intent.PointToPointIntent; 39 import org.onosproject.net.intent.PointToPointIntent;
40 +import org.slf4j.Logger;
32 41
33 import com.fasterxml.jackson.databind.node.ObjectNode; 42 import com.fasterxml.jackson.databind.node.ObjectNode;
34 43
44 +import static org.onosproject.net.intent.IntentState.FAILED;
45 +import static org.onosproject.net.intent.IntentState.WITHDRAWN;
46 +import static org.slf4j.LoggerFactory.getLogger;
47 +
35 /** 48 /**
36 * REST resource for interacting with the inventory of intents. 49 * REST resource for interacting with the inventory of intents.
37 */ 50 */
38 51
39 @Path("intents") 52 @Path("intents")
40 public class IntentsWebResource extends AbstractWebResource { 53 public class IntentsWebResource extends AbstractWebResource {
54 + private static final Logger log = getLogger(IntentsWebResource.class);
55 + private static final int WITHDRAW_EVENT_TIMEOUT_SECONDS = 5;
56 +
41 public static final String INTENT_NOT_FOUND = "Intent is not found"; 57 public static final String INTENT_NOT_FOUND = "Intent is not found";
42 58
43 /** 59 /**
...@@ -84,4 +100,79 @@ public class IntentsWebResource extends AbstractWebResource { ...@@ -84,4 +100,79 @@ public class IntentsWebResource extends AbstractWebResource {
84 } 100 }
85 return ok(root).build(); 101 return ok(root).build();
86 } 102 }
103 +
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 +
87 } 178 }
......
...@@ -79,13 +79,11 @@ ...@@ -79,13 +79,11 @@
79 <dependency> 79 <dependency>
80 <groupId>com.sun.jersey.jersey-test-framework</groupId> 80 <groupId>com.sun.jersey.jersey-test-framework</groupId>
81 <artifactId>jersey-test-framework-core</artifactId> 81 <artifactId>jersey-test-framework-core</artifactId>
82 - <version>1.18.1</version>
83 <scope>test</scope> 82 <scope>test</scope>
84 </dependency> 83 </dependency>
85 <dependency> 84 <dependency>
86 <groupId>com.sun.jersey.jersey-test-framework</groupId> 85 <groupId>com.sun.jersey.jersey-test-framework</groupId>
87 <artifactId>jersey-test-framework-grizzly2</artifactId> 86 <artifactId>jersey-test-framework-grizzly2</artifactId>
88 - <version>1.18.1</version>
89 <scope>test</scope> 87 <scope>test</scope>
90 </dependency> 88 </dependency>
91 89
......