39239fdf7df9f2cab0b49d9d5d9a6d61d6aa2dce
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.http;
23
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.ServletException;
36 import javax.servlet.http.HttpServlet;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39 import org.json.JSONObject;
40 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.InventoryTreeProvider;
41 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.DataTreeObject;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * @author Michael Dürre
48  *
49  */
50
51 //@HttpWhiteboardServletPattern("/tree/*")
52 //@HttpWhiteboardServletName("DataTreeHttpServlet")
53 //@Component(service = Servlet.class)
54 public class DataTreeHttpServlet extends HttpServlet {
55
56     private static final long serialVersionUID = 1L;
57     public static final String URI_PRE = "/tree";
58     private InventoryTreeProvider dataTreeProvider;
59     private static final Logger LOG = LoggerFactory.getLogger(DataTreeHttpServlet.class);
60
61     public DataTreeHttpServlet() {
62         super();
63     }
64
65     public void setInventoryTreeProvider(InventoryTreeProvider provider) {
66         this.dataTreeProvider = provider;
67
68     }
69
70     public static String readPayload(HttpServletRequest request) throws IOException {
71
72         String body = null;
73         StringBuilder stringBuilder = new StringBuilder();
74         BufferedReader bufferedReader = null;
75         IOException toThrow = null;
76         try (InputStream inputStream = request.getInputStream()) {
77
78             if (inputStream != null) {
79                 bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
80                 char[] charBuffer = new char[128];
81                 int bytesRead = -1;
82                 while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
83                     stringBuilder.append(charBuffer, 0, bytesRead);
84                 }
85             } else {
86                 stringBuilder.append("");
87             }
88         } catch (IOException ex) {
89             toThrow = ex;
90         } finally {
91             if (bufferedReader != null) {
92                 try {
93                     bufferedReader.close();
94                 } catch (IOException ex) {
95                     LOG.debug("problem closing reader:", ex);
96                     toThrow = ex;
97                 }
98             }
99         }
100         if (toThrow != null) {
101             throw toThrow;
102         }
103         body = stringBuilder.toString();
104         return body;
105     }
106
107     @Override
108     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
109         final String uri = req.getRequestURI();
110         LOG.debug("GET request for {}", uri);
111         final EntityWithTree e = getEntity(uri);
112         if (e != null) {
113             LOG.debug("GET request for {} to e={} with tree={}", uri, e.entity, e.tree);
114             switch (e.entity) {
115                 case Inventoryequipment:
116                     DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, null);
117                     this.doJsonResponse(resp, o);
118                     break;
119                 default:
120                     this.notAvailble(resp);
121                     break;
122             }
123         } else {
124             LOG.debug("unable to find entity for uri {}", uri);
125         }
126     }
127
128     @Override
129     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
130         final String uri = req.getRequestURI();
131         String filter = null;
132         try {
133             final String body = readPayload(req);
134             JSONObject data = new JSONObject(body);
135             if (data.has("query")) {
136                 filter = data.getString("query");
137             }
138
139         } catch (Exception e) {
140             LOG.warn("problem reading payload: {}", e);
141         }
142         LOG.debug("POST request for {}", uri);
143         final EntityWithTree e = getEntity(uri);
144         if (e != null) {
145             switch (e.entity) {
146                 case Inventoryequipment:
147                     DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, filter);
148                     this.doJsonResponse(resp, o);
149                     break;
150                 default:
151                     this.notAvailble(resp);
152                     break;
153             }
154         }
155     }
156
157     /**
158      * @param resp
159      */
160     private void notAvailble(HttpServletResponse resp) {
161         try {
162             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
163         } catch (IOException e) {
164
165         }
166     }
167
168     public static EntityWithTree getEntity(String uri) {
169         final String regex = "^\\/tree\\/read-(.*)-tree\\/?(.*)$";
170         final Pattern pattern = Pattern.compile(regex);
171         final Matcher matcher = pattern.matcher(uri);
172         if (matcher.find() && matcher.groupCount() > 0) {
173             try {
174                 Optional<Entity> oe = Optional.ofNullable(Entity.forName(matcher.group(1)));
175                 if (oe.isPresent()) {
176                     return new EntityWithTree(oe.get(), matcher.groupCount() > 1 ? matcher.group(2) : null);
177                 } else {
178                     LOG.warn("unable to find entity for name {}", matcher.group(1));
179                 }
180             } catch (Exception e2) {
181                 LOG.warn("unable to parse {} into entity: ", matcher.group(2), e2);
182             }
183         }
184         return null;
185
186     }
187
188     private void doJsonResponse(HttpServletResponse resp, DataTreeObject data) {
189         resp.setHeader("Content-Type", "application/json");
190         try {
191             resp.getWriter().write(data.toJSON());
192         } catch (IOException e) {
193             LOG.warn("problem sending response: ", e);
194         }
195     }
196
197     public static class EntityWithTree {
198         public final Entity entity;
199         public final List<String> tree;
200
201         @Override
202         public String toString() {
203             return "EntityWithTree [entity=" + entity + ", tree=" + tree + "]";
204         }
205
206         /**
207         *
208         * @param e database enttity to access
209         * @param tree tree description
210         *   e.g. nodeA           => tree entry for node-id=nodeA
211         *        nodeA/key0      => tree entry for node-id=nodeA and uuid=key0 and tree-level=0
212         *        nodeA/key0/key1 => tree entry for node-id=nodeA and uuid=key1 and tree-level=1
213         *
214         */
215         public EntityWithTree(Entity e, String tree) {
216             this.entity = e;
217             if (tree != null) {
218                 if (tree.startsWith("/")) {
219                     tree = tree.substring(1);
220                 }
221                 if (tree.endsWith("/")) {
222                     tree = tree.substring(0, tree.length() - 1);
223                 }
224                 String[] tmp = tree.split("\\/");
225                 this.tree = new ArrayList<>();
226                 for (int i = 0; i < tmp.length; i++) {
227                     try {
228                         String s = URLDecoder.decode(tmp[i], "utf-8");
229                         if (s != null && s.length() > 0) {
230                             this.tree.add(s);
231                         }
232                     } catch (UnsupportedEncodingException e1) {
233                         LOG.warn("problem urldecode {}: {}", tmp[i], e);
234                     }
235                 }
236             } else {
237                 this.tree = null;
238             }
239         }
240     }
241 }