2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.http;
24 import java.io.BufferedReader;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.UnsupportedEncodingException;
29 import java.net.URLDecoder;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Optional;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import javax.servlet.Servlet;
36 import javax.servlet.ServletException;
37 import javax.servlet.http.HttpServlet;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40 import org.json.JSONObject;
41 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.InventoryTreeProvider;
42 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.DataTreeObject;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity;
44 import org.osgi.service.component.annotations.Component;
45 import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletName;
46 import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletPattern;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
51 * @author Michael Dürre
55 @HttpWhiteboardServletPattern("/tree/*")
56 @HttpWhiteboardServletName("DataTreeHttpServlet")
57 @Component(service = Servlet.class)
58 public class DataTreeHttpServlet extends HttpServlet {
60 private static final long serialVersionUID = 1L;
61 private InventoryTreeProvider dataTreeProvider;
62 private static final Logger LOG = LoggerFactory.getLogger(DataTreeHttpServlet.class);
64 public DataTreeHttpServlet() {
68 public void setInventoryTreeProvider(InventoryTreeProvider provider) {
69 this.dataTreeProvider = provider;
73 public static String readPayload(HttpServletRequest request) throws IOException {
76 StringBuilder stringBuilder = new StringBuilder();
77 BufferedReader bufferedReader = null;
78 IOException toThrow = null;
79 try (InputStream inputStream = request.getInputStream()) {
81 if (inputStream != null) {
82 bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
83 char[] charBuffer = new char[128];
85 while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
86 stringBuilder.append(charBuffer, 0, bytesRead);
89 stringBuilder.append("");
91 } catch (IOException ex) {
94 if (bufferedReader != null) {
96 bufferedReader.close();
97 } catch (IOException ex) {
98 LOG.debug("problem closing reader:", ex);
103 if (toThrow != null) {
106 body = stringBuilder.toString();
111 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
112 final String uri = req.getRequestURI();
113 LOG.debug("GET request for {}", uri);
114 final EntityWithTree e = getEntity(uri);
116 LOG.debug("GET request for {} to e={} with tree={}", uri, e.entity, e.tree);
118 case Inventoryequipment:
119 DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, null);
120 this.doJsonResponse(resp, o);
123 this.notAvailble(resp);
127 LOG.debug("unable to find entity for uri {}", uri);
132 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
133 final String uri = req.getRequestURI();
134 String filter = null;
136 final String body = readPayload(req);
137 JSONObject data = new JSONObject(body);
138 if (data.has("query")) {
139 filter = data.getString("query");
142 } catch (Exception e) {
143 LOG.warn("problem reading payload: {}", e);
145 LOG.debug("POST request for {}", uri);
146 final EntityWithTree e = getEntity(uri);
149 case Inventoryequipment:
150 DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, filter);
151 this.doJsonResponse(resp, o);
154 this.notAvailble(resp);
163 private void notAvailble(HttpServletResponse resp) {
165 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
166 } catch (IOException e) {
171 public static EntityWithTree getEntity(String uri) {
172 final String regex = "^\\/tree\\/read-(.*)-tree\\/?(.*)$";
173 final Pattern pattern = Pattern.compile(regex);
174 final Matcher matcher = pattern.matcher(uri);
175 if (matcher.find() && matcher.groupCount() > 0) {
177 Optional<Entity> oe = Optional.ofNullable(Entity.forName(matcher.group(1)));
178 if (oe.isPresent()) {
179 return new EntityWithTree(oe.get(), matcher.groupCount() > 1 ? matcher.group(2) : null);
181 LOG.warn("unable to find entity for name {}", matcher.group(1));
183 } catch (Exception e2) {
184 LOG.warn("unable to parse {} into entity: ", matcher.group(2), e2);
191 private void doJsonResponse(HttpServletResponse resp, DataTreeObject data) {
192 resp.setHeader("Content-Type", "application/json");
194 resp.getWriter().write(data.toJSON());
195 } catch (IOException e) {
196 LOG.warn("problem sending response: ", e);
200 public static class EntityWithTree {
201 public final Entity entity;
202 public final List<String> tree;
205 public String toString() {
206 return "EntityWithTree [entity=" + entity + ", tree=" + tree + "]";
211 * @param e database enttity to access
212 * @param tree tree description
213 * e.g. nodeA => tree entry for node-id=nodeA
214 * nodeA/key0 => tree entry for node-id=nodeA and uuid=key0 and tree-level=0
215 * nodeA/key0/key1 => tree entry for node-id=nodeA and uuid=key1 and tree-level=1
218 public EntityWithTree(Entity e, String tree) {
221 if (tree.startsWith("/")) {
222 tree = tree.substring(1);
224 if (tree.endsWith("/")) {
225 tree = tree.substring(0, tree.length() - 1);
227 String[] tmp = tree.split("\\/");
228 this.tree = new ArrayList<>();
229 for (int i = 0; i < tmp.length; i++) {
231 String s = URLDecoder.decode(tmp[i], "utf-8");
232 if (s != null && s.length() > 0) {
235 } catch (UnsupportedEncodingException e1) {
236 LOG.warn("problem urldecode {}: {}", tmp[i], e);