blob: 40b5c9316594eea03f7b3af4af1b7d276fefe5ca [file] [log] [blame]
Jian Li6e4da2f2018-05-21 18:11:31 +09001/*
2 * Copyright 2018-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.openstacktelemetry.web;
17
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
Jian Li6e4da2f2018-05-21 18:11:31 +090020import com.fasterxml.jackson.databind.node.ObjectNode;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090021import com.google.common.collect.Sets;
22import org.apache.commons.lang3.exception.ExceptionUtils;
23import org.onosproject.codec.JsonCodec;
24import org.onosproject.openstacktelemetry.api.FlowInfo;
25import org.onosproject.openstacktelemetry.api.StatsFlowRule;
26import org.onosproject.openstacktelemetry.api.StatsFlowRuleAdminService;
Jian Li7fe7eaf2018-12-31 17:00:33 +090027import org.onosproject.openstacktelemetry.codec.rest.FlowInfoJsonCodec;
Jian Li6e4da2f2018-05-21 18:11:31 +090028import org.onosproject.rest.AbstractWebResource;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
Jian Li6e4da2f2018-05-21 18:11:31 +090031
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090032import javax.ws.rs.Consumes;
Jian Lia4947682018-07-07 14:53:32 +090033import javax.ws.rs.DELETE;
Jian Li6e4da2f2018-05-21 18:11:31 +090034import javax.ws.rs.GET;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090035import javax.ws.rs.POST;
Jian Li6e4da2f2018-05-21 18:11:31 +090036import javax.ws.rs.Path;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090037import javax.ws.rs.PathParam;
Jian Li6e4da2f2018-05-21 18:11:31 +090038import javax.ws.rs.Produces;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090039import javax.ws.rs.core.Context;
Jian Li6e4da2f2018-05-21 18:11:31 +090040import javax.ws.rs.core.MediaType;
41import javax.ws.rs.core.Response;
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090042import javax.ws.rs.core.UriBuilder;
43import javax.ws.rs.core.UriInfo;
44import java.io.InputStream;
45import java.util.Set;
46
47import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
48import static javax.ws.rs.core.Response.created;
49import static org.onlab.util.Tools.readTreeFromStream;
Jian Li6e4da2f2018-05-21 18:11:31 +090050
51/**
52 * Handles REST API call of openstack telemetry.
53 */
Jian Li6e4da2f2018-05-21 18:11:31 +090054@Path("telemetry")
55public class OpenstackTelemetryWebResource extends AbstractWebResource {
56
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090057 private final Logger log = LoggerFactory.getLogger(getClass());
58
Jian Li6e4da2f2018-05-21 18:11:31 +090059 private final ObjectNode root = mapper().createObjectNode();
60
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090061 private static final String JSON_NODE_FLOW_RULE = "rules";
62 private static final String FLOW_RULE_ID = "STATS_FLOW_RULE_ID";
63
Jian Li0bbbb1c2018-06-22 22:01:17 +090064 private final StatsFlowRuleAdminService
65 statsFlowRuleService = get(StatsFlowRuleAdminService.class);
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090066
67 @Context
68 private UriInfo uriInfo;
69
70 /**
71 * Creates a flow rule for metric.
72 *
73 * @param input openstack flow rule JSON input stream
74 * @return 201 CREATED if the JSON is correct,
75 * 400 BAD_REQUEST if the JSON is malformed.
76 */
77 @POST
78 @Consumes(MediaType.APPLICATION_JSON)
79 @Produces(MediaType.APPLICATION_JSON)
80 public Response createBulkFlowRule(InputStream input) {
81 log.info("CREATE BULK FLOW RULE: {}", input.toString());
82
83 readNodeConfiguration(input).forEach(flowRule -> {
84 log.debug("FlowRule: {}", flowRule.toString());
Jian Li0bbbb1c2018-06-22 22:01:17 +090085 statsFlowRuleService.createStatFlowRule(flowRule);
Boyoung Jeong9e8faec2018-06-17 21:19:23 +090086 });
87
88 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
89 .path(JSON_NODE_FLOW_RULE)
90 .path(FLOW_RULE_ID);
91
92 return created(locationBuilder.build()).build();
93 }
94
95 /**
96 * Delete flow rules.
97 *
98 * @param input openstack flow rule JSON input stream
99 * @return 200 OK if processing is correct.
100 */
Jian Lia4947682018-07-07 14:53:32 +0900101 @DELETE
102 @Consumes(MediaType.APPLICATION_JSON)
103 @Produces(MediaType.APPLICATION_JSON)
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900104 public Response deleteBulkFlowRule(InputStream input) {
105 log.info("DELETE BULK FLOW RULE: {}", input.toString());
106
107 readNodeConfiguration(input).forEach(flowRule -> {
108 log.debug("FlowRule: {}", flowRule.toString());
Jian Li0bbbb1c2018-06-22 22:01:17 +0900109 statsFlowRuleService.deleteStatFlowRule(flowRule);
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900110 });
111
112 return ok(root).build();
113 }
114
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900115 /**
116 * Get flow rules which is installed on ONOS.
117 *
118 * @return 200 OK
119 */
120 public Response readBulkFlowRule() {
121 log.info("READ BULK FLOW RULE");
122
123 return ok(root).build();
124 }
125
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900126 /**
127 * Get flow information list.
128 *
129 * @return Flow information list
130 */
131 @GET
132 @Path("list")
133 @Produces(MediaType.APPLICATION_JSON)
134 public Response getFlowInfoBulk() {
135 log.info("GET BULK FLOW RULE");
136
137 Set<FlowInfo> flowInfoSet;
Jian Lif8b8c7f2018-08-27 18:49:04 +0900138 flowInfoSet = statsFlowRuleService.getOverlayFlowInfos();
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900139
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900140 JsonCodec<FlowInfo> flowInfoCodec = new FlowInfoJsonCodec();
141
142 ObjectNode nodeJson;
143 int idx = 0;
144 for (FlowInfo flowInfo: flowInfoSet) {
145 nodeJson = flowInfoCodec.encode(flowInfo, this);
Jian Li7fe7eaf2018-12-31 17:00:33 +0900146 root.put("FlowInfo" + idx++, nodeJson.toString());
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900147 }
148 return ok(root).build();
149 }
150
151 @GET
Jian Lia4947682018-07-07 14:53:32 +0900152 @Path("list/{srcIpPrefix}/{dstIpPrefix}")
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900153 @Produces(MediaType.APPLICATION_JSON)
Jian Lia4947682018-07-07 14:53:32 +0900154 public Response getFlowRule(@PathParam("srcIpPrefix") String srcIpPrefix,
155 @PathParam("dstIpPrefix") String dstIpPrefix) {
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900156 return ok(root).build();
157 }
158
Boyoung Jeong9e8faec2018-06-17 21:19:23 +0900159 private Set<StatsFlowRule> readNodeConfiguration(InputStream input) {
160 log.info("Input JSON Data: \n\t\t{}", input.toString());
161 Set<StatsFlowRule> flowRuleSet = Sets.newHashSet();
162 try {
163 JsonNode jsonTree = readTreeFromStream(mapper().enable(INDENT_OUTPUT), input);
164 ArrayNode nodes = (ArrayNode) jsonTree.path(JSON_NODE_FLOW_RULE);
165 nodes.forEach(node -> {
166 try {
167 ObjectNode objectNode = node.deepCopy();
168 log.debug("ObjectNode: {}", objectNode.toString());
169 StatsFlowRule statsFlowRule = codec(StatsFlowRule.class)
170 .decode(objectNode, this);
171 log.debug("StatsFlowRule: {}", statsFlowRule.toString());
172 flowRuleSet.add(statsFlowRule);
173 } catch (Exception ex) {
174 log.error("Exception Stack:\n{}", ExceptionUtils.getStackTrace(ex));
175 throw new IllegalArgumentException();
176 }
177 });
178 } catch (Exception ex) {
179 log.error("Exception Stack:\n{}", ExceptionUtils.getStackTrace(ex));
180 throw new IllegalArgumentException(ex);
181 }
182
183 return flowRuleSet;
184 }
Jian Li6e4da2f2018-05-21 18:11:31 +0900185}