blob: 2486df07daa4df575a2fcdaf76883b1580f6320d [file] [log] [blame]
Sean Condon0e89bda2017-03-21 14:23:19 +00001/*
2 * Copyright 2017-present Open Networking Foundation
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.cfm.impl;
17
18import java.io.InputStream;
19import java.net.URI;
20import java.util.Collection;
21
22import javax.ws.rs.Consumes;
23import javax.ws.rs.DELETE;
24import javax.ws.rs.GET;
25import javax.ws.rs.POST;
26import javax.ws.rs.PUT;
27import javax.ws.rs.Path;
28import javax.ws.rs.PathParam;
29import javax.ws.rs.Produces;
30import javax.ws.rs.core.MediaType;
31import javax.ws.rs.core.Response;
32
33import org.onosproject.cfm.web.MepCodec;
34import org.onosproject.codec.JsonCodec;
35import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
36import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
37import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
38import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
39import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
40import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
41import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
42import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
43import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
44import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
45import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
46import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
47import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
48import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
49import org.onosproject.rest.AbstractWebResource;
50import org.slf4j.Logger;
51import org.slf4j.LoggerFactory;
52
53import com.fasterxml.jackson.databind.JsonNode;
54import com.fasterxml.jackson.databind.ObjectMapper;
55import com.fasterxml.jackson.databind.node.ArrayNode;
56import com.fasterxml.jackson.databind.node.ObjectNode;
57
58/**
59 * Layer 2 CFM Maintenance Association Endpoint (MEP) web resource.
60 */
61@Path("md/{md_name}/ma/{ma_name}/mep")
62public class MepWebResource extends AbstractWebResource {
63 private final Logger log = LoggerFactory.getLogger(getClass());
64
65 /**
66 * Get all MEPs by MD name, MA name.
67 *
68 * @param mdName The name of a Maintenance Domain
69 * @param maName The name of a Maintenance Association belonging to the MD
70 * @return 200 OK with a list of MEPS or 500 on error
71 */
72 @GET
73 @Produces(MediaType.APPLICATION_JSON)
74 @Consumes(MediaType.APPLICATION_JSON)
75 public Response getAllMepsForMa(@PathParam("md_name") String mdName,
76 @PathParam("ma_name") String maName) {
77 log.debug("GET all Meps called for MA {}", mdName + "/" + maName);
78 try {
79 MdId mdId = MdIdCharStr.asMdId(mdName);
80 MaIdShort maId = MaIdCharStr.asMaId(maName);
81 Collection<MepEntry> mepCollection = get(CfmMepService.class).getAllMeps(mdId, maId);
82 ArrayNode an = mapper().createArrayNode();
83 an.add(codec(MepEntry.class).encode(mepCollection, this));
84 return ok(mapper().createObjectNode().set("meps", an)).build();
85 } catch (CfmConfigException e) {
86 log.error("Get all Meps on {} failed because of exception",
87 mdName + "/" + maName, e);
88 return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
89 }
90
91 }
92
93 /**
94 * Get MEP by MD name, MA name and Mep Id.
95 *
96 * @param mdName The name of a Maintenance Domain
97 * @param maName The name of a Maintenance Association belonging to the MD
98 * @param mepId The Id of the MEP
99 * @return 200 OK with details of the MEP or 500 on error
100 */
101 @GET
102 @Path("{mep_id}")
103 @Produces(MediaType.APPLICATION_JSON)
104 @Consumes(MediaType.APPLICATION_JSON)
105 public Response getMep(@PathParam("md_name") String mdName,
106 @PathParam("ma_name") String maName,
107 @PathParam("mep_id") short mepId) {
108 log.debug("GET called for MEP {}", mdName + "/" + maName + "/" + mepId);
109 try {
110 MdId mdId = MdIdCharStr.asMdId(mdName);
111 MaIdShort maId = MaIdCharStr.asMaId(maName);
112 MepEntry mepEntry = get(CfmMepService.class)
113 .getMep(mdId, maId, MepId.valueOf(mepId));
114 if (mepEntry == null) {
115 return Response.serverError().entity("{ \"failure\":\"MEP " +
116 mdName + "/" + maName + "/" + mepId + " not found\" }").build();
117 }
118 ObjectNode node = mapper().createObjectNode();
119 node.set("mep", codec(MepEntry.class).encode(mepEntry, this));
120 return ok(node).build();
121 } catch (CfmConfigException e) {
122 log.error("Get Mep {} failed because of exception",
123 mdName + "/" + maName + "/" + mepId, e);
124 return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
125 }
126 }
127
128 /**
129 * Delete MEP by MD name, MA name and Mep Id.
130 *
131 * @param mdName The name of a Maintenance Domain
132 * @param maName The name of a Maintenance Association belonging to the MD
133 * @param mepIdShort The Id of the MEP
134 * @return 200 OK or 304 if not found, or 500 on error
135 */
136 @DELETE
137 @Path("{mep_id}")
138 @Consumes(MediaType.APPLICATION_JSON)
139 @Produces(MediaType.APPLICATION_JSON)
140 public Response deleteMep(@PathParam("md_name") String mdName,
141 @PathParam("ma_name") String maName,
142 @PathParam("mep_id") short mepIdShort) {
143 log.debug("DELETE called for MEP " + mdName + "/" + maName + "/" + mepIdShort);
144 try {
145 MdId mdId = MdIdCharStr.asMdId(mdName);
146 MaIdShort maId = MaIdCharStr.asMaId(maName);
147 boolean deleted = get(CfmMepService.class)
148 .deleteMep(mdId, maId, MepId.valueOf(mepIdShort));
149 if (!deleted) {
150 return Response.notModified(mdName + "/" + maName + "/" +
151 mepIdShort + " did not exist").build();
152 } else {
153 return ok("{ \"success\":\"deleted " + mdName + "/" + maName +
154 "/" + mepIdShort + "\" }").build();
155 }
156 } catch (CfmConfigException e) {
157 log.error("Delete Mep {} failed because of exception ",
158 mdName + "/" + maName + "/" + mepIdShort, e);
159 return Response.serverError().entity("{ \"failure\":\"" +
160 e.toString() + "\" }").build();
161 }
162 }
163
164 /**
165 * Create MEP with MD name, MA name and Mep Json.
166 *
167 * @param mdName The name of a Maintenance Domain
168 * @param maName The name of a Maintenance Association belonging to the MD
169 * @param input A JSON formatted input stream specifying the Mep parameters
170 * @return 201 Created or 304 if already exists or 500 on error
171 */
172 @POST
173 @Consumes(MediaType.APPLICATION_JSON)
174 @Produces(MediaType.APPLICATION_JSON)
175 public Response createMep(@PathParam("md_name") String mdName,
176 @PathParam("ma_name") String maName, InputStream input) {
177 log.debug("POST called to Create Mep");
178 try {
179 MdId mdId = MdIdCharStr.asMdId(mdName);
180 MaIdShort maId = MaIdCharStr.asMaId(maName);
181 MaintenanceAssociation ma = get(CfmMdService.class).getMaintenanceAssociation(mdId, maId).get();
182
183 ObjectMapper mapper = new ObjectMapper();
184 JsonNode cfg = mapper.readTree(input);
185 JsonCodec<Mep> mepCodec = codec(Mep.class);
186
187 Mep mep = ((MepCodec) mepCodec).decode((ObjectNode) cfg, this, mdName, maName);
188
189 Boolean issuccess = get(CfmMepService.class).createMep(mdId, maId, mep);
190 if (!issuccess) {
191 return Response.notModified(mdName + "/" + ma.maId() + "/" + mep.mepId() +
192 " already exists").build();
193 }
194 return Response
195 .created(new URI("md/" + mdName + "/ma/" + ma.maId() + "/mep/" + mep.mepId()))
196 .entity("{ \"success\":\"mep " + mdName + "/" + ma.maId() + "/" + mep.mepId() + " created\" }")
197 .build();
198 } catch (Exception | CfmConfigException e) {
199 log.error("Create Mep on " + mdName + "/" + maName + " failed because of exception {}",
200 e.toString());
201 return Response.serverError()
202 .entity("{ \"failure\":\"" + e.toString() + "\" }")
203 .build();
204 }
205 }
206
207 /**
208 * Transmit Loopback on MEP with MD name, MA name and Mep Id.
209 *
210 * @param mdName The name of a Maintenance Domain
211 * @param maName The name of a Maintenance Association belonging to the MD
212 * @param mepIdShort The id of a MEP belonging to the MA
213 * @param input A JSON formatted input stream specifying the Mep parameters
214 * @return 202 Received with success message or 500 on error
215 */
216 @PUT
217 @Path("{mep_id}/transmit-loopback")
218 @Consumes(MediaType.APPLICATION_JSON)
219 @Produces(MediaType.APPLICATION_JSON)
220 public Response transmitLoopback(
221 @PathParam("md_name") String mdName,
222 @PathParam("ma_name") String maName,
223 @PathParam("mep_id") short mepIdShort,
224 InputStream input) {
225 log.debug("PUT called to Transmit Loopback on Mep");
226
227 MdId mdId = MdIdCharStr.asMdId(mdName);
228 MaIdShort maId = MaIdCharStr.asMaId(maName);
229 MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
230 MaintenanceAssociation ma = get(CfmMdService.class)
231 .getMaintenanceAssociation(mdId, maId).get();
232
233 MepId mepId = MepId.valueOf(mepIdShort);
234
235 try {
236 ObjectMapper mapper = new ObjectMapper();
237 JsonNode cfg = mapper.readTree(input);
238 JsonCodec<MepLbCreate> mepLbCreateCodec = codec(MepLbCreate.class);
239
240 MepLbCreate lbCreate = mepLbCreateCodec.decode((ObjectNode) cfg, this);
241 get(CfmMepService.class).transmitLoopback(md.mdId(), ma.maId(), mepId, lbCreate);
242 } catch (Exception | CfmConfigException e) {
243 log.error("Transmit Loopback on " + mdName + "/" + maName +
244 "/{} failed", String.valueOf(mepIdShort), e);
245 return Response.serverError()
246 .entity("{ \"failure\":\"" + e.toString() + "\" }")
247 .build();
248 }
249
250 return Response.accepted()
251 .entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
252 + mepId.id() + " started\" }").build();
253 }
254
255 /**
256 * Abort Loopback on MEP with MD name, MA name and Mep Id.
257 *
258 * @param mdName The name of a Maintenance Domain
259 * @param maName The name of a Maintenance Association belonging to the MD
260 * @param mepIdShort The id of a MEP belonging to the MA
261 * @return 202 Received with success message or 500 on error
262 */
263 @PUT
264 @Path("{mep_id}/abort-loopback")
265 @Consumes(MediaType.APPLICATION_JSON)
266 @Produces(MediaType.APPLICATION_JSON)
267 public Response abortLoopback(
268 @PathParam("md_name") String mdName,
269 @PathParam("ma_name") String maName,
270 @PathParam("mep_id") short mepIdShort) {
271 log.debug("PUT called to Abort Loopback on Mep");
272
273 MdId mdId = MdIdCharStr.asMdId(mdName);
274 MaIdShort maId = MaIdCharStr.asMaId(maName);
275 MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
276 MaintenanceAssociation ma = get(CfmMdService.class)
277 .getMaintenanceAssociation(mdId, maId).get();
278
279 MepId mepId = MepId.valueOf(mepIdShort);
280
281 try {
282 get(CfmMepService.class).abortLoopback(md.mdId(), ma.maId(), mepId);
283 } catch (CfmConfigException e) {
284 log.error("Abort Loopback on " + mdName + "/" + maName +
285 "/{} failed", String.valueOf(mepIdShort), e);
286 return Response.serverError()
287 .entity("{ \"failure\":\"" + e.toString() + "\" }")
288 .build();
289 }
290
291 return Response.accepted()
292 .entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
293 + mepId.id() + " aborted\" }").build();
294 }
295
296 /**
297 * Transmit Linktrace on MEP with MD name, MA name and Mep Id.
298 *
299 * @param mdName The name of a Maintenance Domain
300 * @param maName The name of a Maintenance Association belonging to the MD
301 * @param mepIdShort The id of a MEP belonging to the MA
302 * @param input A JSON formatted input stream specifying the Linktrace parameters
303 * @return 202 Received with success message or 500 on error
304 */
305 @PUT
306 @Path("{mep_id}/transmit-linktrace")
307 @Consumes(MediaType.APPLICATION_JSON)
308 @Produces(MediaType.APPLICATION_JSON)
309 public Response transmitLinktrace(
310 @PathParam("md_name") String mdName,
311 @PathParam("ma_name") String maName,
312 @PathParam("mep_id") short mepIdShort,
313 InputStream input) {
314 log.debug("PUT called to Transmit Linktrace on Mep");
315
316 MdId mdId = MdIdCharStr.asMdId(mdName);
317 MaIdShort maId = MaIdCharStr.asMaId(maName);
318 MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
319 MaintenanceAssociation ma = get(CfmMdService.class)
320 .getMaintenanceAssociation(mdId, maId).get();
321
322 MepId mepId = MepId.valueOf(mepIdShort);
323
324 try {
325 ObjectMapper mapper = new ObjectMapper();
326 JsonNode cfg = mapper.readTree(input);
327 JsonCodec<MepLtCreate> mepLtCreateCodec = codec(MepLtCreate.class);
328
329 MepLtCreate ltCreate = mepLtCreateCodec.decode((ObjectNode) cfg, this);
330 get(CfmMepService.class).transmitLinktrace(md.mdId(), ma.maId(), mepId, ltCreate);
331 } catch (Exception | CfmConfigException e) {
332 log.error("Transmit Linktrace on " + mdName + "/" + maName +
333 "/{} failed", String.valueOf(mepIdShort), e);
334 return Response.serverError()
335 .entity("{ \"failure\":\"" + e.toString() + "\" }")
336 .build();
337 }
338
339 return Response.accepted()
340 .entity("{ \"success\":\"Linktrace on MEP " + mdName + "/" + ma.maId() + "/"
341 + mepId.id() + " started\" }").build();
342 }
343}