blob: 6b9f9eb00a012d30d0b05c568852538e1a0be40c [file] [log] [blame]
Jovana Vuletafe32db7d2017-05-01 12:18:00 +02001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jovana Vuletafe32db7d2017-05-01 12:18:00 +02003 *
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.ofagent.rest;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
22import org.onosproject.incubator.net.virtual.NetworkId;
23import org.onosproject.ofagent.api.OFAgent;
24import org.onosproject.ofagent.api.OFAgentAdminService;
25import org.onosproject.ofagent.api.OFAgentService;
26import org.onosproject.rest.AbstractWebResource;
27
28import javax.ws.rs.Consumes;
29import javax.ws.rs.DELETE;
30import javax.ws.rs.GET;
31import javax.ws.rs.POST;
32import javax.ws.rs.PUT;
33import javax.ws.rs.Path;
34import javax.ws.rs.PathParam;
35import javax.ws.rs.core.MediaType;
36import javax.ws.rs.core.Response;
37
38import java.io.IOException;
39import java.io.InputStream;
40
41import static javax.ws.rs.core.Response.Status.*;
Ray Milkey86ee5e82018-04-02 15:33:07 -070042import static org.onlab.util.Tools.readTreeFromStream;
Jovana Vuletafe32db7d2017-05-01 12:18:00 +020043
44
45/**
46 * Manage virtual switch and controller mapping.
47 */
48@Path("service")
49public class OFAgentWebResource extends AbstractWebResource {
50
51 private static final String OFAGENT_NOT_FOUND = "OFAgent not found";
52 private static final String OFAGENTS_NOT_FOUND = "OFAgent set not found";
53 private static final String OFAGENT_CREATED = "OFAgent created";
54 private static final String OFAGENT_NOT_CREATED = "OFAgent not created";
55 private static final String OFAGENT_STARTED = "OFAgent started";
56 private static final String OFAGENT_NOT_STARTED = "OFAgent not started";
57 private static final String OFAGENT_UPDATED = "OFAgent updated";
58 private static final String OFAGENT_NOT_UPDATED = "OFAgent not updated";
59
60 /**
61 * Lists OpenFlow agents.
62 * Shows OpenFlow agents for all virtual networks.
63 *
64 * @return 200 OK if set exists, 500 INTERNAL SERVER ERROR otherwise
65 */
66 @GET
67 @Path("ofagents")
68 public Response listOFAgents() {
69 OFAgentService service = get(OFAgentService.class);
70 ObjectMapper mapper = new ObjectMapper();
71 ObjectNode root = mapper.createObjectNode();
72 ArrayNode ofAgentsArray = mapper.createArrayNode();
73 if (service.agents() == null) {
74 return Response.status(INTERNAL_SERVER_ERROR)
75 .entity(OFAGENTS_NOT_FOUND).build();
76 } else {
77 service.agents().forEach(ofAgent -> ofAgentsArray.add((new OFAgentCodec()).encode(ofAgent, this)));
78
79 root.set("ofAgents", ofAgentsArray);
80 return Response.ok(root, MediaType.APPLICATION_JSON_TYPE).build();
81 }
82
83 }
84
85 /**
86 * Lists OpenFlow agent.
87 * Shows OpenFlow agent for given network.
88 *
89 * @param networkId OFAgent networkId
90 * @return 200 OK if OFAgent exists, 404 NOT FOUND otherwise
91 */
92 @GET
93 @Path("ofagent/{networkId}")
94 public Response listOFAgent(@PathParam("networkId") long networkId) {
95 OFAgentService service = get(OFAgentService.class);
96 OFAgent ofAgent = service.agent(NetworkId.networkId(networkId));
97 if (ofAgent == null) {
98 return Response.status(NOT_FOUND)
99 .entity(OFAGENT_NOT_FOUND).build();
100 } else {
101 return Response.ok((new OFAgentCodec()).encode(ofAgent, this), MediaType
102 .APPLICATION_JSON_TYPE)
103 .build();
104 }
105 }
106
107 /**
108 * Adds a new OpenFlow agent.
109 * Creates a new OpenFlow agent and adds it to OpenFlow agent store.
110 *
111 * @param stream JSON stream
112 * @return 201 CREATED , 400 BAD REQUEST if stream cannot be decoded to OFAgent
113 * @throws IOException if request cannot be parsed
114 */
115 @POST
116 @Path("ofagent-create")
117 @Consumes(MediaType.APPLICATION_JSON)
118 public Response createOFAgent(InputStream stream) throws IOException {
119 OFAgentAdminService adminService = get(OFAgentAdminService.class);
120
Ray Milkey86ee5e82018-04-02 15:33:07 -0700121 OFAgent ofAgent = (new OFAgentCodec()).decode(readTreeFromStream(mapper(), stream), this);
Jovana Vuletafe32db7d2017-05-01 12:18:00 +0200122 if (ofAgent == null) {
123 return Response.status(BAD_REQUEST)
124 .entity(OFAGENT_NOT_CREATED).build();
125 } else {
126 adminService.createAgent(ofAgent);
127 return Response.status(CREATED).entity(OFAGENT_CREATED).build();
128 }
129 }
130
131 /**
132 * Starts OpenFlow agent.
133 * Starts OpenFlow agent for the given network.
134 *
135 * @param stream JSON stream
136 * @return 200 OK if OFAgent was started, 404 NOT FOUND when OF agent does not exist, 400 BAD REQUEST otherwise
137 * @throws IOException if request cannot be parsed
138 */
139 @POST
140 @Path("ofagent-start")
141 @Consumes(MediaType.APPLICATION_JSON)
142 public Response startOFAgent(InputStream stream) throws IOException {
143 OFAgentAdminService adminService = get(OFAgentAdminService.class);
144
Ray Milkey86ee5e82018-04-02 15:33:07 -0700145 ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
Jovana Vuletafe32db7d2017-05-01 12:18:00 +0200146 JsonNode networkId = jsonTree.get("networkId");
147
148 if (networkId == null) {
149 return Response.status(BAD_REQUEST)
150 .entity(OFAGENT_NOT_STARTED).build();
151 } else if (get(OFAgentService.class).agent(NetworkId.networkId(networkId.asLong())) == null) {
152 return Response.status(NOT_FOUND)
153 .entity(OFAGENT_NOT_STARTED).build();
154 } else {
155 adminService.startAgent(NetworkId.networkId(networkId.asLong()));
156 return Response.status(OK).entity(OFAGENT_STARTED).build();
157 }
158 }
159
160 /**
161 * Updates OpenFlow agent.
162 * Updates existing OpenFlow agent for the given network.
163 *
164 * @param stream JSON stream
165 * @return 200 OK if OFAgent was updated, 404 NOT FOUND when OF agent does not exist, 400 BAD REQUEST otherwise
166 * @throws IOException if request cannot be parsed
167 */
168 @PUT
169 @Path("ofagent-update")
170 @Consumes(MediaType.APPLICATION_JSON)
171 public Response updateOFAgent(InputStream stream) throws IOException {
172 OFAgentAdminService adminService = get(OFAgentAdminService.class);
173
Ray Milkey86ee5e82018-04-02 15:33:07 -0700174 OFAgent ofAgent = (new OFAgentCodec()).decode(readTreeFromStream(mapper(), stream), this);
Jovana Vuletafe32db7d2017-05-01 12:18:00 +0200175
176 if (ofAgent == null) {
177 return Response.status(NOT_FOUND)
178 .entity(OFAGENT_NOT_UPDATED).build();
179 } else if (get(OFAgentService.class).agent(ofAgent.networkId()) == null) {
180 return Response.status(NOT_FOUND)
181 .entity(OFAGENT_NOT_UPDATED).build();
182 }
183
184 adminService.updateAgent(ofAgent);
185 return Response.status(OK).entity(OFAGENT_UPDATED).build();
186 }
187
188
189 /**
190 * Stops OFAgent.
191 * Stops OFAgent for the given virtual network.
192 *
193 * @param stream JSON stream
194 * @return 204 NO CONTENT if OpenFlow agent was stopped, 404 NOT FOUND otherwise
195 * @throws IOException if request cannot be parsed
196 */
197 @POST
198 @Path("ofagent-stop")
199 @Consumes(MediaType.APPLICATION_JSON)
200 public Response stopOFAgent(InputStream stream) throws IOException {
201
202 OFAgentAdminService adminService = get(OFAgentAdminService.class);
Ray Milkey86ee5e82018-04-02 15:33:07 -0700203 ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
Jovana Vuletafe32db7d2017-05-01 12:18:00 +0200204 JsonNode networkId = jsonTree.get("networkId");
205
206 if (get(OFAgentService.class).agent(NetworkId.networkId(networkId.asLong())) == null) {
207 return Response.status(NOT_FOUND)
208 .entity(OFAGENT_NOT_FOUND).build();
209 }
210
211 adminService.stopAgent(NetworkId.networkId(networkId.asLong()));
212 return Response.noContent().build();
213 }
214
215
216 /**
217 * Deletes OFAgent.
218 * Removes OFAgent for the given virtual network from repository.
219 *
220 * @param networkId OFAgent networkId
221 * @return 200 OK if OFAgent was removed, 404 NOT FOUND when OF agent does not exist, 400 BAD REQUEST otherwise
222 */
223 @DELETE
224 @Path("ofagent-remove/{networkId}")
225 public Response removeOFAgent(@PathParam("networkId") long networkId) {
226 if (get(OFAgentService.class).agent(NetworkId.networkId(networkId)) == null) {
227 return Response.status(BAD_REQUEST)
228 .entity(OFAGENT_NOT_FOUND).build();
229 }
230
231 OFAgentAdminService adminService = get(OFAgentAdminService.class);
232 OFAgent removed = adminService.removeAgent(NetworkId.networkId(networkId));
233 if (removed != null) {
234 return Response.ok((new OFAgentCodec()).encode(removed, this), MediaType
235 .APPLICATION_JSON_TYPE)
236 .build();
237 } else {
238 return Response.status(NOT_FOUND)
239 .entity(OFAGENT_NOT_FOUND).build();
240 }
241 }
242}