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