6c5ed0dae5f4f85b30c02481fb7e9f54209db92a
[ccsdk/features.git] /
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.dataprovider.http;
19
20 import java.io.IOException;
21 import java.net.URL;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.jar.Attributes;
26 import java.util.jar.Manifest;
27
28 import javax.servlet.ServletException;
29 import javax.servlet.ServletOutputStream;
30 import javax.servlet.http.HttpServlet;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.onap.ccsdk.features.sdnr.wt.common.Resources;
35 import org.onap.ccsdk.features.sdnr.wt.common.file.PomFile;
36 import org.onap.ccsdk.features.sdnr.wt.common.file.PomPropertiesFile;
37 import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ODLVersionLUT;
38 import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.SystemInfo;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 public class AboutHttpServlet extends HttpServlet {
43
44         /**
45          * 
46          */
47         private static final long serialVersionUID = 1L;
48         private static final Logger LOG = LoggerFactory.getLogger(AboutHttpServlet.class);
49         private static final String UNKNOWN = "unknown";
50         private static final String METAINF_MAVEN = "/META-INF/maven/";
51         private static final String EXCEPTION_FORMAT_UNABLE_TO_READ_INNER_POMFILE = "unable to read inner pom file: {}";
52
53         private static final String URI_PRE = "/about";
54         private static final String RES_BASEPATH = "about/";
55
56         private static final String PLACEHOLDER_ONAP_RELEASENAME = "{release-name}";
57         private static final String PLACEHOLDER_ONAP_RELEASEVERSION = "{release-version}";
58         private static final String PLACEHOLDER_ODL_RELEASENAME = "{odl-version}";
59         private static final String PLACEHOLDER_BUILD_TIMESTAMP = "{build-time}";
60         private static final String PLACEHOLDER_ODLUX_REVISION = "{odlux-revision}";
61         private static final String PLACEHOLDER_PACKAGE_GITHASH = "{package-githash}";
62         private static final String PLACEHOLDER_PACAKGE_VERSION = "{package-version}";
63         private static final String PLACEHOLDER_CCSDK_VERSION = "{ccsdk-version}";
64         private static final String PLACEHOLDER_CLUSTER_SIZE = "{cluster-size}";
65         private static final String PLACEHOLDER_MDSAL_VERSION = "{mdsal-version}";
66         private static final String PLACEHOLDER_YANGTOOLS_VERSION = "{yangtools-version}";
67         private static final String PLACEHOLDER_KARAF_INFO = "{karaf-info}";
68         private static final String README_FILE = "README.md";
69
70         private final String groupId = "org.onap.ccsdk.features.sdnr.wt";
71         private final String artifactId = "sdnr-wt-data-provider-provider";
72
73         private final Map<String, String> data;
74         private final String readmeContent;
75
76         public AboutHttpServlet() {
77
78                 this.data = new HashMap<>();
79                 this.collectStaticData();
80                 this.readmeContent = this.render(this.getResourceFileContent(README_FILE));
81         }
82
83         /**
84          * collect static versioning data 
85          */
86         private void collectStaticData() {
87                 PomPropertiesFile props = this.getPomProperties();
88                 final String ccsdkVersion = this.getPomParentVersion();
89                 this.data.put(PLACEHOLDER_ONAP_RELEASENAME, ODLVersionLUT.getONAPReleaseName(ccsdkVersion, UNKNOWN));
90                 this.data.put(PLACEHOLDER_ODL_RELEASENAME, ODLVersionLUT.getOdlVersion(ccsdkVersion, UNKNOWN));
91                 this.data.put(PLACEHOLDER_BUILD_TIMESTAMP, props != null ? props.getBuildDate().toString() : "");
92                 this.data.put(PLACEHOLDER_ODLUX_REVISION, this.getPomProperty("odlux.buildno"));
93                 this.data.put(PLACEHOLDER_PACAKGE_VERSION, this.getManifestValue("Bundle-Version"));
94                 this.data.put(PLACEHOLDER_CCSDK_VERSION, ccsdkVersion);
95                 this.data.put(PLACEHOLDER_ONAP_RELEASEVERSION, "1.8.1-SNAPSHOT");
96                 this.data.put(PLACEHOLDER_MDSAL_VERSION, SystemInfo.getMdSalVersion(UNKNOWN));
97                 this.data.put(PLACEHOLDER_YANGTOOLS_VERSION, SystemInfo.getYangToolsVersion(UNKNOWN));
98                 this.data.put(PLACEHOLDER_PACKAGE_GITHASH, this.getGitHash(UNKNOWN));
99         }
100
101         @Override
102         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
103
104                 String uri = req.getRequestURI().substring(URI_PRE.length());
105                 LOG.debug("request for {}", uri);
106                 if (uri.length() <= 0 || uri.equals("/")) {
107                         // collect data
108                         this.collectData();
109                         // render readme
110                         String content = this.render();
111                         byte[] output = content != null ? content.getBytes() : new byte[0];
112                         // output
113                         resp.setStatus(HttpServletResponse.SC_OK);
114                         resp.setContentLength(output.length);
115                         resp.setContentType("text/plain");
116                         ServletOutputStream os = null;
117                         try{
118                                 os = resp.getOutputStream();
119                                 os.write(output);
120                         }
121                         catch(IOException e) {
122                                 LOG.warn("problem writing response for {}: {}",uri,e);
123                         }
124                         finally {
125                                 if(os!=null) {
126                                         try{
127                                                 os.close();
128                                         }
129                                         catch(IOException e) {
130                                                 LOG.warn("problem closing response stream: {}",e);
131                                         }
132                                 }
133                         }
134
135                 } else {
136                         this.doGetFile(uri, resp);
137                 }
138         }
139
140         /**
141          * load git.commit.id from jar /META-INF/git.properties
142          * 
143          * @param def
144          */
145         private String getGitHash(String def) {
146                 String content = Resources.getFileContent(AboutHttpServlet.class, "/META-INF/git.properties");
147                 if (content == null) {
148                         return def;
149                 }
150                 String lines[] = content.split("\n");
151                 for (String line : lines) {
152                         if (line.startsWith("git.commit.id")) {
153                                 def = line.substring("git.commit.id=".length());
154                                 break;
155                         }
156                 }
157                 return def;
158         }
159
160         private String getResourceFileContent(String filename) {
161                 LOG.debug("try ti get content of {}", filename);
162                 return Resources.getFileContent(AboutHttpServlet.class, RES_BASEPATH + filename);
163         }
164
165         /**
166          * collect dynamic data for about.md
167          */
168         private void collectData() {
169                 LOG.info("collecting dynamic data");
170                 try {
171                         this.data.put(PLACEHOLDER_KARAF_INFO, SystemInfo.get());
172                 } catch (Exception e) {
173                         LOG.warn("problem collecting system data: {}", e);
174                 }
175         }
176
177         /**
178          * get value for key out of /META-INF/MANIFEST.MF
179          * @param key
180          * @return
181          */
182         private String getManifestValue(String key) {
183                 URL url = Resources.getUrlForRessource(AboutHttpServlet.class, "/META-INF/MANIFEST.MF");
184                 if (url == null) {
185                         return null;
186                 }
187                 Manifest manifest;
188                 try {
189                         manifest = new Manifest(url.openStream());
190                         Attributes attr = manifest.getMainAttributes();
191                         return attr.getValue(key);
192                 } catch (IOException e) {
193                         LOG.warn("problem reading manifest: {}", e);
194                 }
195                 return null;
196
197         }
198         /**
199          * get object representation of /META-INF/maven/groupId/artifactId/pom.properties
200          * @return
201          */
202         private PomPropertiesFile getPomProperties() {
203                 URL url = Resources.getUrlForRessource(AboutHttpServlet.class,
204                                 METAINF_MAVEN + groupId + "/" + artifactId + "/pom.properties");
205                 PomPropertiesFile propfile;
206                 if (url == null) {
207                         return null;
208                 }
209                 try {
210                         propfile = new PomPropertiesFile(url.openStream());
211                         return propfile;
212                 } catch (Exception e) {
213                         LOG.warn(EXCEPTION_FORMAT_UNABLE_TO_READ_INNER_POMFILE, e);
214                 }
215                 return null;
216         }
217         /**
218          * get value for key out of /META-INF/maven/groupId/artifactId/pom.xml in properties section
219          * @param key
220          * @return
221          */
222         private String getPomProperty(String key) {
223                 LOG.info("try to get pom property for {}", key);
224                 URL url = Resources.getUrlForRessource(AboutHttpServlet.class,
225                                 METAINF_MAVEN + groupId + "/" + artifactId + "/pom.xml");
226                 if (url == null) {
227                         return null;
228                 }
229                 PomFile pomfile;
230                 try {
231                         pomfile = new PomFile(url.openStream());
232                         return pomfile.getProperty(key);
233                 } catch (Exception e) {
234                         LOG.warn(EXCEPTION_FORMAT_UNABLE_TO_READ_INNER_POMFILE, e);
235                 }
236                 return null;
237         }
238         /**
239          * get parent pom version out of /META-INF/maven/groupId/artifactId/pom.xml 
240          * @return
241          */
242         private String getPomParentVersion() {
243                 LOG.info("try to get pom parent version");
244                 URL url = Resources.getUrlForRessource(AboutHttpServlet.class,
245                                 METAINF_MAVEN + groupId + "/" + artifactId + "/pom.xml");
246                 if (url == null) {
247                         return null;
248                 }
249                 PomFile pomfile;
250                 try {
251                         pomfile = new PomFile(url.openStream());
252                         return pomfile.getParentVersion();
253                 } catch (Exception e) {
254                         LOG.warn(EXCEPTION_FORMAT_UNABLE_TO_READ_INNER_POMFILE, e);
255                 }
256                 return null;
257         }
258
259         /**
260          * get file by uri from resources and write out to response stream 
261          * @param uri
262          * @param resp
263          */
264         private void doGetFile(String uri, HttpServletResponse resp) {
265                 String content = this.getResourceFileContent(uri);
266                 if (content == null) {
267                         try {
268                                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
269                         } catch (IOException e) {
270                                 LOG.debug("unable to send error response : {}", e);
271                         }
272                 } else {
273                         byte[] data = content.getBytes();
274                         resp.setStatus(HttpServletResponse.SC_OK);
275                         resp.setContentType(this.getContentType(uri));
276                         try {
277                                 resp.getOutputStream().write(data);
278                         } catch (IOException e) {
279                                 LOG.debug("unable to send data : {}", e);
280                         }
281                 }
282
283         }
284
285         /**
286          * create http response contentType by filename
287          * @param filename
288          * @return
289          */
290         private String getContentType(String filename) {
291                 String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
292                 switch (ext) {
293                 case "jpg":
294                 case "jpeg":
295                 case "svg":
296                 case "png":
297                 case "gif":
298                 case "bmp":
299                         return "image/" + ext;
300                 case "json":
301                         return "application/json";
302                 case "html":
303                 case "htm":
304                         return "text/html";
305                 case "txt":
306                 case "md":
307                 default:
308                         return "text/plain";
309                 }
310         }
311
312         /**
313          * render this.readmeContent with this.data
314          * @return
315          */
316         private String render() {
317                 return this.render(null);
318         }
319
320         /**
321          * render content with this.data
322          * @param content
323          * @return
324          */
325         private String render(String content) {
326                 if (content == null) {
327                         content = this.readmeContent;
328                 }
329                 if (content == null) {
330                         return null;
331                 }
332                 for (Entry<String, String> entry : this.data.entrySet()) {
333                         if (entry.getValue() != null && content.contains(entry.getKey())) {
334                                 content = content.replace(entry.getKey(), entry.getValue());
335                         }
336                 }
337
338                 return content;
339         }
340
341         public void setClusterSize(String value) {
342                 this.data.put(PLACEHOLDER_CLUSTER_SIZE, value);
343         }
344 }