Java tutorial
/* * Copyright 2017-present Open Networking Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.imr.rest; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.lang3.tuple.Pair; import org.onosproject.core.ApplicationId; import org.onosproject.core.DefaultApplicationId; import org.onosproject.imr.IntentMonitorAndRerouteService; import org.onosproject.imr.data.Route; import org.onosproject.imr.data.RoutingConfigurations; import org.onosproject.net.ElementId; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.intent.Key; import org.onosproject.rest.AbstractWebResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Set; /** * Intent Monitor and Reroute REST API. */ @Path("imr") public class ImrWebResource extends AbstractWebResource { public static final String ROOT_FIELD_STATISTICS_NAME = "statistics"; public static final String ROOT_FIELD_MONITORED_INTENTS = "response"; private final Logger log = LoggerFactory.getLogger(getClass()); private IntentMonitorAndRerouteService imrService; private final ObjectMapper mapper = new ObjectMapper(); /** * Get the statistics of the monitored intents. * Shows for each intent all the flow entries. * * @onos.rsModel intentStatsGet * @return 200 OK */ @GET @Path("intentStats") @Produces(MediaType.APPLICATION_JSON) public Response getIntentsStats() { ObjectNode root = mapper.createObjectNode(); imrService = get(IntentMonitorAndRerouteService.class); root.putArray(ROOT_FIELD_STATISTICS_NAME).addAll(getJsonNodesIntentStats(imrService.getStats())); return ok(root).build(); } /** * Get the statistics of the monitored intent of a specific application * Shows for each intent all the flow entries. * * @onos.rsModel intentStatsGet * @param id Application ID * @param name Application Name * @return 200 OK */ @GET @Path("intentStats/{id}/{name}") @Produces(MediaType.APPLICATION_JSON) public Response getIntentsStats(@PathParam("id") short id, @PathParam("name") String name) { ObjectNode root = mapper.createObjectNode(); imrService = get(IntentMonitorAndRerouteService.class); ApplicationId appId = new DefaultApplicationId(id, name); root.putArray(ROOT_FIELD_STATISTICS_NAME).addAll(getJsonNodesIntentStats(imrService.getStats(appId))); return ok(root).build(); } /** * Get the statistics of a specific monitored intent. * Shows all the flow entries of the specific intent * * @onos.rsModel intentStatsGet * @param id Application ID * @param name Application Name * @param intentK Intent Key * @return 200 OK */ @GET @Path("intentStats/{id}/{name}/{intentKey}") @Produces(MediaType.APPLICATION_JSON) public Response getIntentsStats(@PathParam("id") short id, @PathParam("name") String name, @PathParam("intentKey") String intentK) { ObjectNode root = mapper.createObjectNode(); imrService = get(IntentMonitorAndRerouteService.class); ApplicationId appId = new DefaultApplicationId(id, name); Key intentKey = Key.of(intentK, appId); root.putArray("statistics").addAll(getJsonNodesIntentStats(imrService.getStats(appId, intentKey))); return ok(root).build(); } /** * Build the Json Nodes from the intent stats retrieved from {@link IntentMonitorAndRerouteService}. * * @param mapKeyToStats Intent statistics * @return {@link ArrayNode} built from the statistics */ private ArrayNode getJsonNodesIntentStats(Map<ApplicationId, Map<Key, List<FlowEntry>>> mapKeyToStats) { final ArrayNode rootArrayNode = mapper.createArrayNode(); mapKeyToStats.forEach((appId, mapIntentKeyStats) -> { ObjectNode appObjNode = codec(ApplicationId.class).encode(appId, this); ArrayNode intentArrayNode = appObjNode.putArray("intents"); mapIntentKeyStats.forEach((intentKey, lstStats) -> { ObjectNode intentKeyObjNode = mapper.createObjectNode(); ArrayNode statsArrayNode = intentKeyObjNode.putArray(intentKey.toString()); lstStats.forEach(stat -> { statsArrayNode.add(codec(FlowEntry.class).encode(stat, this)); }); intentArrayNode.add(intentKeyObjNode); }); rootArrayNode.add(appObjNode); }); return rootArrayNode; } /** * Get the list of monitored intents. * Shows for each intent key the related end points (as inElements and OutElements). * * @onos.rsModel monitoredIntentsGet * @return 200 OK */ @GET @Path("monitoredIntents") @Produces(MediaType.APPLICATION_JSON) public Response getMonitoredIntents() { imrService = get(IntentMonitorAndRerouteService.class); ArrayNode jsonMonitoredIntents = getJsonMonitoredIntents(imrService.getMonitoredIntents()); ObjectNode result = mapper.createObjectNode(); result.putArray(ROOT_FIELD_MONITORED_INTENTS).addAll(jsonMonitoredIntents); return ok(result).build(); } /** * Get the list of monitored intents of a specific application. * Shows for each intent key the related end points (as inElements and OutElements). * * @onos.rsModel monitoredIntentsGet * @param id Application ID * @param name Application Name * @return 200 OK */ @GET @Path("monitoredIntents/{id}/{name}") @Produces(MediaType.APPLICATION_JSON) public Response getMonitoredIntents(@PathParam("id") short id, @PathParam("name") String name) { imrService = get(IntentMonitorAndRerouteService.class); ApplicationId appId = new DefaultApplicationId(id, name); ArrayNode jsonMonitoredIntents = getJsonMonitoredIntents(imrService.getMonitoredIntents(appId)); ObjectNode result = mapper.createObjectNode(); result.putArray(ROOT_FIELD_MONITORED_INTENTS).addAll(jsonMonitoredIntents); return ok(result).build(); } /** * Build the JSON Node from the monitored intents retrieved from {@link IntentMonitorAndRerouteService}. * * @param monIntents Monitored intents structure. * @return {@link ArrayNode} built from the monitored intents. */ private ArrayNode getJsonMonitoredIntents( Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> monIntents) { final ArrayNode rootArrayNode = mapper.createArrayNode(); monIntents.forEach((appId, mapIntentKeyEndElements) -> { ObjectNode appObjNode = codec(ApplicationId.class).encode(appId, this); ArrayNode intentArrayNode = appObjNode.putArray("intents"); mapIntentKeyEndElements.forEach((intentKey, inOutElem) -> { ObjectNode intentKeyObjNode = mapper.createObjectNode().put("key", intentKey.toString()); ArrayNode inElements = intentKeyObjNode.putArray("inElements"); inOutElem.getLeft().forEach(elementId -> inElements.add(elementId.toString())); ArrayNode outElements = intentKeyObjNode.putArray("outElements"); inOutElem.getRight().forEach(elementId -> outElements.add(elementId.toString())); intentArrayNode.add(intentKeyObjNode); }); rootArrayNode.add(appObjNode); }); return rootArrayNode; } /** * POST a list of routing configurations. For each intents a list of paths * with relative weights is specified. The body of HTTP POST is a JSON * * @onos.rsModel reRouteIntentsPost * @param stream JSON stream * @return 200 OK if the routing configurations are applied correctly, * otherwise 500 Internal Server Error */ @POST @Path("reRouteIntents") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Response reRouteIntents(InputStream stream) { imrService = get(IntentMonitorAndRerouteService.class); ObjectNode result = mapper().createObjectNode(); StringBuilder resultString = new StringBuilder(); mapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); try { RoutingConfigurations msg = mapper().readValue(stream, RoutingConfigurations.class); for (Route routingConfiguration : msg.routingList()) { String outcome; try { if (!imrService.applyPath(routingConfiguration)) { outcome = "Application ID:" + routingConfiguration.appId() + " or Intent Key:" + routingConfiguration.key() + " not monitored!"; } else { outcome = "OK"; } } catch (IllegalArgumentException | NullPointerException ex) { outcome = ex.getMessage(); } if (!outcome.equals("OK")) { if (resultString.length() > 0) { resultString.append(" "); } resultString.append(outcome); } } if (resultString.length() > 0) { result.put("response", "addRouting() failed: ".concat(resultString.toString())); } else { result.put("response", "OK"); } return ok(result).build(); } catch (Exception e) { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()).build(); } } }